[asterisk-commits] oej: branch oej/earl-grey-sip2cause-configurable-trunk r382856 - in /team/oej...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 12 12:06:45 CDT 2013


Author: oej
Date: Tue Mar 12 12:06:39 2013
New Revision: 382856

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382856
Log:
Reinstate automerge if it ever was instated.

Added:
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/stasis.h
      - copied unchanged from r382852, trunk/include/asterisk/stasis.h
    team/oej/earl-grey-sip2cause-configurable-trunk/main/stasis.c
      - copied unchanged from r382852, trunk/main/stasis.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/stasis_cache.c
      - copied unchanged from r382852, trunk/main/stasis_cache.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/stasis_message.c
      - copied unchanged from r382852, trunk/main/stasis_message.c
    team/oej/earl-grey-sip2cause-configurable-trunk/tests/test_stasis.c
      - copied unchanged from r382852, trunk/tests/test_stasis.c
Modified:
    team/oej/earl-grey-sip2cause-configurable-trunk/   (props changed)
    team/oej/earl-grey-sip2cause-configurable-trunk/CHANGES
    team/oej/earl-grey-sip2cause-configurable-trunk/CREDITS
    team/oej/earl-grey-sip2cause-configurable-trunk/Makefile
    team/oej/earl-grey-sip2cause-configurable-trunk/addons/res_config_mysql.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_confbridge.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_dial.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_meetme.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_parkandannounce.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_skel.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_voicemail.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_config_parser.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state_empty.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state_inactive.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state_multi.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state_multi_marked.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state_single.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/conf_state_single_marked.c
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/include/conf_state.h
    team/oej/earl-grey-sip2cause-configurable-trunk/apps/confbridge/include/confbridge.h
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/chan_iax2.c
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/chan_jingle.c
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/chan_motif.c
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/chan_sip.c
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/chan_skinny.c
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/chan_unistim.c
    team/oej/earl-grey-sip2cause-configurable-trunk/channels/sip/include/sip.h
    team/oej/earl-grey-sip2cause-configurable-trunk/configs/confbridge.conf.sample
    team/oej/earl-grey-sip2cause-configurable-trunk/configs/motif.conf.sample
    team/oej/earl-grey-sip2cause-configurable-trunk/configs/res_ldap.conf.sample
    team/oej/earl-grey-sip2cause-configurable-trunk/configs/sip.conf.sample
    team/oej/earl-grey-sip2cause-configurable-trunk/configs/skinny.conf.sample
    team/oej/earl-grey-sip2cause-configurable-trunk/configs/xmpp.conf.sample
    team/oej/earl-grey-sip2cause-configurable-trunk/configure
    team/oej/earl-grey-sip2cause-configurable-trunk/configure.ac
    team/oej/earl-grey-sip2cause-configurable-trunk/contrib/realtime/mysql/sippeers.sql
    team/oej/earl-grey-sip2cause-configurable-trunk/contrib/realtime/postgresql/realtime.sql
    team/oej/earl-grey-sip2cause-configurable-trunk/contrib/scripts/asterisk.ldap-schema
    team/oej/earl-grey-sip2cause-configurable-trunk/contrib/scripts/asterisk.ldif
    team/oej/earl-grey-sip2cause-configurable-trunk/doc/appdocsxml.dtd
    team/oej/earl-grey-sip2cause-configurable-trunk/funcs/func_presencestate.c
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/_private.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/channel.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/channel_internal.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/config_options.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/format_cap.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/logger.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/module.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/rtp_engine.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/sorcery.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/threadpool.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/xml.h
    team/oej/earl-grey-sip2cause-configurable-trunk/include/asterisk/xmldoc.h
    team/oej/earl-grey-sip2cause-configurable-trunk/main/Makefile
    team/oej/earl-grey-sip2cause-configurable-trunk/main/asterisk.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/asterisk.exports.in
    team/oej/earl-grey-sip2cause-configurable-trunk/main/autoservice.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/bridging.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/channel.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/channel_internal_api.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/cli.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/config_options.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/event.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/features.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/loader.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/logger.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/manager.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/named_acl.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/pbx.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/presencestate.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/rtp_engine.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/sorcery.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/threadpool.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/udptl.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/xml.c
    team/oej/earl-grey-sip2cause-configurable-trunk/main/xmldoc.c
    team/oej/earl-grey-sip2cause-configurable-trunk/res/res_agi.c
    team/oej/earl-grey-sip2cause-configurable-trunk/res/res_rtp_asterisk.c
    team/oej/earl-grey-sip2cause-configurable-trunk/res/res_sorcery_config.c
    team/oej/earl-grey-sip2cause-configurable-trunk/res/res_sorcery_memory.c
    team/oej/earl-grey-sip2cause-configurable-trunk/res/res_xmpp.c
    team/oej/earl-grey-sip2cause-configurable-trunk/res/snmp/agent.c
    team/oej/earl-grey-sip2cause-configurable-trunk/tests/test_sorcery.c

Propchange: team/oej/earl-grey-sip2cause-configurable-trunk/
------------------------------------------------------------------------------
    automerge = Is-there-life-off-net?

Propchange: team/oej/earl-grey-sip2cause-configurable-trunk/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/oej/earl-grey-sip2cause-configurable-trunk/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Mar 12 12:06:39 2013
@@ -1,1 +1,1 @@
-/trunk:1-381489
+/trunk:1-382854

Modified: team/oej/earl-grey-sip2cause-configurable-trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/oej/earl-grey-sip2cause-configurable-trunk/CHANGES?view=diff&rev=382856&r1=382855&r2=382856
==============================================================================
--- team/oej/earl-grey-sip2cause-configurable-trunk/CHANGES (original)
+++ team/oej/earl-grey-sip2cause-configurable-trunk/CHANGES Tue Mar 12 12:06:39 2013
@@ -50,6 +50,13 @@
 
  * Added ECAM command support for Sony Ericsson phones.
 
+chan_sip
+------------------
+ * Added support for RFC 3327 "Path" headers. This can be enabled in sip.conf
+   using the 'supportpath' setting, either on a global basis or on a peer basis.
+   This setting enables Asterisk to route outgoing out-of-dialog requests via a
+   set of proxies by using a pre-loaded route-set defined by the Path headers in
+   the REGISTER request. See Realtime updates for more configuration information.
 
 Features
 -------------------
@@ -72,6 +79,14 @@
 
  * Added the 'queue_log_realtime_use_gmt' option to have timestamps in GMT
    for realtime queue log entries.
+
+MeetMe
+-------------------
+* Added the 'n' option to MeetMe to prevent application of the DENOISE function
+  to a channel joining a conference. Some channel drivers that vary the number
+  of audio samples in a voice frame will experience significant quality problems
+  if a denoiser is attached to the channel; this option gives them the ability
+  to remove the denoiser without having to unload func_speex.
 
 Queue
 -------------------
@@ -86,6 +101,15 @@
    that the REDIRECTING dialplan function can be used to set the redirecting
    reason to any string. It also allows for custom strings to be read as the
    redirecting reason from SIP Diversion headers.
+
+Realtime
+------------------
+ * Dynamic realtime tables for SIP Users can now include a 'path' field. This
+   will store the path information for that peer when it registers. Realtime
+   tables can also use the 'supportpath' field to enable Path header support.
+
+ * LDAP realtime configurations for SIP Users now have the AstAccountPathSupport
+   objectIdentifier. This maps to the supportpath option in sip.conf. 
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 10 to Asterisk 11 --------------------
@@ -145,6 +169,9 @@
  * Added announcement configuration option to user profile. If set the sound
    file will be played to the user, and only the user, upon joining the
    conference bridge.
+
+ * Added record_file_append option that defaults to "yes", but if set to no
+   will create a new file between each start/stop recording.
 
 
 Dial
@@ -387,6 +414,9 @@
    detects that an incoming SIP request crossed a NAT after being sent by
    the remote endpoint.
 
+ * The default global nat setting in sip.conf has been changed from force_rport
+   to auto_force_rport.
+
  * NAT settings are now a combinable list of options. The equivalent of the
    deprecated nat=yes is nat=force_rport,comedia. nat=no behaves as before.
 
@@ -442,6 +472,9 @@
    when using Transfer application. See refer_addheaders in sip.conf.sample.
 
  * Added support to use private party ID information with calls.
+
+ * Adds an option discard_remote_hold_retrieval that when set stops telling
+   the peer to start music on hold.
 
 
 chan_skinny

Modified: team/oej/earl-grey-sip2cause-configurable-trunk/CREDITS
URL: http://svnview.digium.com/svn/asterisk/team/oej/earl-grey-sip2cause-configurable-trunk/CREDITS?view=diff&rev=382856&r1=382855&r2=382856
==============================================================================
--- team/oej/earl-grey-sip2cause-configurable-trunk/CREDITS (original)
+++ team/oej/earl-grey-sip2cause-configurable-trunk/CREDITS Tue Mar 12 12:06:39 2013
@@ -22,7 +22,7 @@
 	* John Todd, TalkPlus, Inc.  and JR Richardson, Ntegrated Solutions. 
 		for funding the development of SIP Session Timers support.
 
-	* Omnitor AB, Gunnar Hellström, for funding work with videocaps, 
+	* Omnitor AB, Gunnar Hellstr�m, for funding work with videocaps, 
 		T.140 RED, originate with video/text and many more 
 		contributions.
 
@@ -54,7 +54,7 @@
 
 === HARDWARE DONORS === 
 
- We'd like to thank the followwing for granting access to hardware for testing.
+ We'd like to thank the following for granting access to hardware for testing.
 
 	* Thanks to QuickNet Technologies for their donation of an Internet
 		PhoneJack and Linejack card to the project.  
@@ -63,13 +63,12 @@
 	* Thanks to VoipSupply for their donation of Sipura ATAs to the project
 		for T.38 testing. (http://www.voipsupply.com)
 
-
 	* Thanks to Grandstream for their donation of ATAs to the project for
 		T.38 testing. (http://www.grandstream.com)
 
 === MISCELLANEOUS PATCHES ===
 
- We'd like to thank the flollowing for their patches
+ We'd like to thank the following for their patches
 
 	* Jim Dixon - Zapata Telephony and app_rpt
 		http://www.zapatatelephony.org/app_rpt.html
@@ -240,7 +239,8 @@
 		ControlPlayback, and multiple bug fixes See 
 		http://voip-info.org/users/view/sergee serg(AT)voipsolutions.ru
 
-	* Klaus Darillon - the SIPremoveHeader function in chan_sip
+	* Klaus Darillon - the SIPremoveHeader function in chan_sip and SIP Path
+		Support.
 
 	* Moises Silva (moy) - for writing LibOpenR2, and providing support for
 		it in chan_dahdi moises.silva(AT)gmail.com
@@ -252,7 +252,7 @@
 		cdr_tds rewrite, countless other improvements, fixes, and good
 		ideas. sean(AT)malleable.com
 
-	* Jan Kaláb - Calendaring support for Exchange Server 2007+ via 
+	* Jan Kal�b - Calendaring support for Exchange Server 2007+ via 
 		Exchange Web Services.
 
 	* University of Oslo (uio.no), Norway - SIP Max-Forwards setting 

Modified: team/oej/earl-grey-sip2cause-configurable-trunk/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/oej/earl-grey-sip2cause-configurable-trunk/Makefile?view=diff&rev=382856&r1=382855&r2=382856
==============================================================================
--- team/oej/earl-grey-sip2cause-configurable-trunk/Makefile (original)
+++ team/oej/earl-grey-sip2cause-configurable-trunk/Makefile Tue Mar 12 12:06:39 2013
@@ -456,7 +456,7 @@
 	@echo "<docs xmlns:xi=\"http://www.w3.org/2001/XInclude\">" >> $@
 	@for x in $(MOD_SUBDIRS); do \
 		printf "$$x " ; \
-		for i in $$x/*.c; do \
+		for i in `find $$x -name *.c`; do \
 			$(AWK) -f build_tools/get_documentation $$i >> $@ ; \
 		done ; \
 	done

Modified: team/oej/earl-grey-sip2cause-configurable-trunk/addons/res_config_mysql.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/earl-grey-sip2cause-configurable-trunk/addons/res_config_mysql.c?view=diff&rev=382856&r1=382855&r2=382856
==============================================================================
--- team/oej/earl-grey-sip2cause-configurable-trunk/addons/res_config_mysql.c (original)
+++ team/oej/earl-grey-sip2cause-configurable-trunk/addons/res_config_mysql.c Tue Mar 12 12:06:39 2013
@@ -343,9 +343,7 @@
 	}
 
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	newparam = va_arg(ap, const char *);
-	newval = va_arg(ap, const char *);
-	if (!newparam || !newval)  {
+	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *)))  {
 		ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 		release_database(dbh);
 		return NULL;
@@ -376,7 +374,6 @@
 		ESCAPE_STRING(buf, newval);
 		ast_str_append(&sql, 0, " AND %s%s '%s'", newparam, op, ast_str_buffer(buf));
 	}
-	va_end(ap);
 
 	ast_debug(1, "MySQL RealTime: Retrieve SQL: %s\n", ast_str_buffer(sql));
 
@@ -457,9 +454,7 @@
 	}
 
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	newparam = va_arg(ap, const char *);
-	newval = va_arg(ap, const char *);
-	if (!newparam || !newval)  {
+	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *)))  {
 		ast_log(LOG_WARNING, "MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 		ast_config_destroy(cfg);
 		release_database(dbh);
@@ -498,8 +493,6 @@
 	if (initfield) {
 		ast_str_append(&sql, 0, " ORDER BY %s", initfield);
 	}
-
-	va_end(ap);
 
 	ast_debug(1, "MySQL RealTime: Retrieve SQL: %s\n", ast_str_buffer(sql));
 
@@ -581,9 +574,7 @@
 	}
 
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	newparam = va_arg(ap, const char *);
-	newval = va_arg(ap, const char *);
-	if (!newparam || !newval)  {
+	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *)))  {
 		ast_log(LOG_WARNING, "MySQL RealTime: Realtime update requires at least 1 parameter and 1 value to update.\n");
 		release_table(table);
 		release_database(dbh);
@@ -633,7 +624,6 @@
 			internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
 		}
 	}
-	va_end(ap);
 
 	ESCAPE_STRING(buf, lookup);
 	ast_str_append(&sql, 0, " WHERE `%s` = '%s'", keyfield, ast_str_buffer(buf));
@@ -667,7 +657,7 @@
 {
 	struct mysql_conn *dbh;
 	my_ulonglong numrows;
-	int first = 1;
+	int first;
 	const char *newparam, *newval;
 	struct ast_str *sql = ast_str_thread_get(&sql_buf, 100), *buf = ast_str_thread_get(&scratch_buf, 100);
 	struct ast_str *where = ast_str_thread_get(&sql2_buf, 100);
@@ -706,6 +696,7 @@
 		return -1;
 	}
 
+	first = 1;
 	while ((newparam = va_arg(ap, const char *))) {
 		if (!(column = find_column(table, newparam))) {
 			ast_log(LOG_ERROR, "Updating on column '%s', but that column does not exist within the table '%s'!\n", newparam, tablename);
@@ -753,7 +744,7 @@
 			internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
 		}
 	}
-	va_end(ap);
+
 	release_table(table);
 
 	ast_str_append(&sql, 0, " %s", ast_str_buffer(where));
@@ -802,9 +793,7 @@
 		return -1;
 	}
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	newparam = va_arg(ap, const char *);
-	newval = va_arg(ap, const char *);
-	if (!newparam || !newval)  {
+	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *))) {
 		ast_log(LOG_WARNING, "MySQL RealTime: Realtime storage requires at least 1 parameter and 1 value to search on.\n");
 		release_database(dbh);
 		return -1;
@@ -833,7 +822,6 @@
 			ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
 		}
 	}
-	va_end(ap);
 	ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2));
 	ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql));
 
@@ -901,7 +889,6 @@
 		ESCAPE_STRING(buf, newval);
 		ast_str_append(&sql, 0, " AND `%s` = '%s'", newparam, ast_str_buffer(buf));
 	}
-	va_end(ap);
 
 	ast_debug(1, "MySQL RealTime: Delete SQL: %s\n", ast_str_buffer(sql));
 

Modified: team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_confbridge.c?view=diff&rev=382856&r1=382855&r2=382856
==============================================================================
--- team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_confbridge.c (original)
+++ team/oej/earl-grey-sip2cause-configurable-trunk/apps/app_confbridge.c Tue Mar 12 12:06:39 2013
@@ -305,10 +305,10 @@
 /*! \brief Container to hold all conference bridges in progress */
 static struct ao2_container *conference_bridges;
 
-static void leave_conference(struct conference_bridge_user *user);
-static int play_sound_number(struct conference_bridge *conference_bridge, int say_number);
-static int execute_menu_entry(struct conference_bridge *conference_bridge,
-	struct conference_bridge_user *conference_bridge_user,
+static void leave_conference(struct confbridge_user *user);
+static int play_sound_number(struct confbridge_conference *conference, int say_number);
+static int execute_menu_entry(struct confbridge_conference *conference,
+	struct confbridge_user *user,
 	struct ast_bridge_channel *bridge_channel,
 	struct conf_menu_entry *menu_entry,
 	struct conf_menu *menu);
@@ -316,15 +316,15 @@
 /*! \brief Hashing function used for conference bridges container */
 static int conference_bridge_hash_cb(const void *obj, const int flags)
 {
-	const struct conference_bridge *conference_bridge = obj;
-	return ast_str_case_hash(conference_bridge->name);
+	const struct confbridge_conference *conference = obj;
+	return ast_str_case_hash(conference->name);
 }
 
 /*! \brief Comparison function used for conference bridges container */
 static int conference_bridge_cmp_cb(void *obj, void *arg, int flags)
 {
-	const struct conference_bridge *conference_bridge0 = obj, *conference_bridge1 = arg;
-	return (!strcasecmp(conference_bridge0->name, conference_bridge1->name) ? CMP_MATCH | CMP_STOP : 0);
+	const struct confbridge_conference *conference0 = obj, *conference1 = arg;
+	return (!strcasecmp(conference0->name, conference1->name) ? CMP_MATCH | CMP_STOP : 0);
 }
 
 const char *conf_get_sound(enum conf_sounds sound, struct bridge_profile_sounds *custom_sounds)
@@ -596,77 +596,117 @@
 	return tmp;
 }
 
+static void set_rec_filename(struct confbridge_conference *conference, struct ast_str **filename, int is_new)
+{
+	char *rec_file = conference->b_profile.rec_file;
+	time_t now;
+	char *ext;
+
+	if (ast_str_strlen(*filename) && ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND) && !is_new) {
+		    return;
+	}
+
+	time(&now);
+
+	ast_str_reset(*filename);
+	if (ast_strlen_zero(rec_file)) {
+		ast_str_set(filename, 0, "confbridge-%s-%u.wav", conference->name, (unsigned int)now);
+	} else {
+		/* insert time before file extension */
+		ext = strrchr(rec_file, '.');
+		if (ext) {
+			ast_str_set_substr(filename, 0, rec_file, ext - rec_file);
+			ast_str_append(filename, 0, "-%u%s", (unsigned int)now, ext);
+		} else {
+			ast_str_set(filename, 0, "%s-%u", rec_file, (unsigned int)now);
+		}
+	}
+
+	if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_RECORD_FILE_APPEND)) {
+		ast_str_append(filename, 0, ",a");
+	}
+}
+
+static int is_new_rec_file(const char *rec_file, struct ast_str **orig_rec_file)
+{
+	if (!ast_strlen_zero(rec_file)) {
+		if (!*orig_rec_file) {
+			*orig_rec_file = ast_str_create(PATH_MAX);
+		}
+
+		if (strcmp(ast_str_buffer(*orig_rec_file), rec_file)) {
+			ast_str_set(orig_rec_file, 0, "%s", rec_file);
+			return 1;
+		}
+	}
+	return 0;
+}
+
 static void *record_thread(void *obj)
 {
-	struct conference_bridge *conference_bridge = obj;
+	struct confbridge_conference *conference = obj;
 	struct ast_app *mixmonapp = pbx_findapp("MixMonitor");
 	struct ast_channel *chan;
 	struct ast_str *filename = ast_str_alloca(PATH_MAX);
-
-	ast_mutex_lock(&conference_bridge->record_lock);
+	struct ast_str *orig_rec_file = NULL;
+
+	ast_mutex_lock(&conference->record_lock);
 	if (!mixmonapp) {
 		ast_log(LOG_WARNING, "Can not record ConfBridge, MixMonitor app is not installed\n");
-		conference_bridge->record_thread = AST_PTHREADT_NULL;
-		ast_mutex_unlock(&conference_bridge->record_lock);
-		ao2_ref(conference_bridge, -1);
+		conference->record_thread = AST_PTHREADT_NULL;
+		ast_mutex_unlock(&conference->record_lock);
+		ao2_ref(conference, -1);
 		return NULL;
 	}
 
 	/* XXX If we get an EXIT right here, START will essentially be a no-op */
-	while (conference_bridge->record_state != CONF_RECORD_EXIT) {
-		if (!(ast_strlen_zero(conference_bridge->b_profile.rec_file))) {
-			ast_str_append(&filename, 0, "%s", conference_bridge->b_profile.rec_file);
-		} else {
-			time_t now;
-			time(&now);
-			ast_str_append(&filename, 0, "confbridge-%s-%u.wav",
-				conference_bridge->name,
-				(unsigned int) now);
-		}
-
-		chan = ast_channel_ref(conference_bridge->record_chan);
+	while (conference->record_state != CONF_RECORD_EXIT) {
+		set_rec_filename(conference, &filename,
+				 is_new_rec_file(conference->b_profile.rec_file, &orig_rec_file));
+		chan = ast_channel_ref(conference->record_chan);
 		ast_answer(chan);
 		pbx_exec(chan, mixmonapp, ast_str_buffer(filename));
-		ast_bridge_join(conference_bridge->bridge, chan, NULL, NULL, NULL);
+		ast_bridge_join(conference->bridge, chan, NULL, NULL, NULL);
 
 		ast_hangup(chan); /* This will eat this thread's reference to the channel as well */
 		/* STOP has been called. Wait for either a START or an EXIT */
-		ast_cond_wait(&conference_bridge->record_cond, &conference_bridge->record_lock);
-	}
-	ast_mutex_unlock(&conference_bridge->record_lock);
-	ao2_ref(conference_bridge, -1);
+		ast_cond_wait(&conference->record_cond, &conference->record_lock);
+	}
+	ast_free(orig_rec_file);
+	ast_mutex_unlock(&conference->record_lock);
+	ao2_ref(conference, -1);
 	return NULL;
 }
 
 /*! \brief Returns whether or not conference is being recorded.
- * \param conference_bridge The bridge to check for recording
+ * \param conference The bridge to check for recording
  * \retval 1, conference is recording.
  * \retval 0, conference is NOT recording.
  */
-static int conf_is_recording(struct conference_bridge *conference_bridge)
-{
-	return conference_bridge->record_state == CONF_RECORD_START;
+static int conf_is_recording(struct confbridge_conference *conference)
+{
+	return conference->record_state == CONF_RECORD_START;
 }
 
 /*! \brief Stop recording a conference bridge
  * \internal
- * \param conference_bridge The conference bridge on which to stop the recording
+ * \param conference The conference bridge on which to stop the recording
  * \retval -1 Failure
  * \retval 0 Success
  */
-static int conf_stop_record(struct conference_bridge *conference_bridge)
+static int conf_stop_record(struct confbridge_conference *conference)
 {
 	struct ast_channel *chan;
-	if (conference_bridge->record_thread == AST_PTHREADT_NULL || !conf_is_recording(conference_bridge)) {
+	if (conference->record_thread == AST_PTHREADT_NULL || !conf_is_recording(conference)) {
 		return -1;
 	}
-	conference_bridge->record_state = CONF_RECORD_STOP;
-	chan = ast_channel_ref(conference_bridge->record_chan);
-	ast_bridge_remove(conference_bridge->bridge, chan);
+	conference->record_state = CONF_RECORD_STOP;
+	chan = ast_channel_ref(conference->record_chan);
+	ast_bridge_remove(conference->bridge, chan);
 	ast_queue_frame(chan, &ast_null_frame);
 	chan = ast_channel_unref(chan);
-	ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference_bridge->b_profile.name);
-	send_stop_record_event(conference_bridge->name);
+	ast_test_suite_event_notify("CONF_STOP_RECORD", "Message: stopped conference recording channel\r\nConference: %s", conference->b_profile.name);
+	send_stop_record_event(conference->name);
 
 	return 0;
 }
@@ -675,26 +715,26 @@
  * \internal
  * \brief Stops the confbridge recording thread.
  *
- * \note Must be called with the conference_bridge locked
+ * \note Must be called with the conference locked
  */
-static int conf_stop_record_thread(struct conference_bridge *conference_bridge)
-{
-	if (conference_bridge->record_thread == AST_PTHREADT_NULL) {
+static int conf_stop_record_thread(struct confbridge_conference *conference)
+{
+	if (conference->record_thread == AST_PTHREADT_NULL) {
 		return -1;
 	}
-	conf_stop_record(conference_bridge);
-
-	ast_mutex_lock(&conference_bridge->record_lock);
-	conference_bridge->record_state = CONF_RECORD_EXIT;
-	ast_cond_signal(&conference_bridge->record_cond);
-	ast_mutex_unlock(&conference_bridge->record_lock);
-
-	pthread_join(conference_bridge->record_thread, NULL);
-	conference_bridge->record_thread = AST_PTHREADT_NULL;
+	conf_stop_record(conference);
+
+	ast_mutex_lock(&conference->record_lock);
+	conference->record_state = CONF_RECORD_EXIT;
+	ast_cond_signal(&conference->record_cond);
+	ast_mutex_unlock(&conference->record_lock);
+
+	pthread_join(conference->record_thread, NULL);
+	conference->record_thread = AST_PTHREADT_NULL;
 
 	/* this is the reference given to the channel during the channel alloc */
-	if (conference_bridge->record_chan) {
-		conference_bridge->record_chan = ast_channel_unref(conference_bridge->record_chan);
+	if (conference->record_chan) {
+		conference->record_chan = ast_channel_unref(conference->record_chan);
 	}
 
 	return 0;
@@ -702,18 +742,18 @@
 
 /*! \brief Start recording the conference
  * \internal
- * \note conference_bridge must be locked when calling this function
- * \param conference_bridge The conference bridge to start recording
+ * \note The conference must be locked when calling this function
+ * \param conference The conference bridge to start recording
  * \retval 0 success
  * \rteval non-zero failure
  */
-static int conf_start_record(struct conference_bridge *conference_bridge)
+static int conf_start_record(struct confbridge_conference *conference)
 {
 	struct ast_format_cap *cap;
 	struct ast_format tmpfmt;
 	int cause;
 
-	if (conference_bridge->record_state != CONF_RECORD_STOP) {
+	if (conference->record_state != CONF_RECORD_STOP) {
 		return -1;
 	}
 
@@ -728,38 +768,45 @@
 
 	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
 
-	if (!(conference_bridge->record_chan = ast_request("ConfBridgeRec", cap, NULL, conference_bridge->name, &cause))) {
+	if (!(conference->record_chan = ast_request("ConfBridgeRec", cap, NULL, conference->name, &cause))) {
 		cap = ast_format_cap_destroy(cap);
 		return -1;
 	}
 
 	cap = ast_format_cap_destroy(cap);
 
-	conference_bridge->record_state = CONF_RECORD_START;
-	ast_mutex_lock(&conference_bridge->record_lock);
-	ast_cond_signal(&conference_bridge->record_cond);
-	ast_mutex_unlock(&conference_bridge->record_lock);
-	ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference_bridge->b_profile.name);
-	send_start_record_event(conference_bridge->name);
+	conference->record_state = CONF_RECORD_START;
+	ast_mutex_lock(&conference->record_lock);
+	ast_cond_signal(&conference->record_cond);
+	ast_mutex_unlock(&conference->record_lock);
+	ast_test_suite_event_notify("CONF_START_RECORD", "Message: started conference recording channel\r\nConference: %s", conference->b_profile.name);
+	send_start_record_event(conference->name);
 
 	return 0;
 }
 
 /*! \brief Start the recording thread on a conference bridge
  * \internal
- * \param conference_bridge The conference bridge on which to start the recording thread
+ * \param conference The conference bridge on which to start the recording thread
  * \retval 0 success
  * \retval -1 failure
  */
-static int start_conf_record_thread(struct conference_bridge *conference_bridge)
-{
-	ao2_ref(conference_bridge, +1); /* give the record thread a ref */
-
-	conf_start_record(conference_bridge);
-
-	if (ast_pthread_create_background(&conference_bridge->record_thread, NULL, record_thread, conference_bridge)) {
-		ast_log(LOG_WARNING, "Failed to create recording channel for conference %s\n", conference_bridge->name);
-		ao2_ref(conference_bridge, -1); /* error so remove ref */
+static int start_conf_record_thread(struct confbridge_conference *conference)
+{
+	conf_start_record(conference);
+
+	/*
+	 * if the thread has already been started, don't start another
+	 */
+	if (conference->record_thread != AST_PTHREADT_NULL) {
+		return 0;
+	}
+
+	ao2_ref(conference, +1); /* give the record thread a ref */
+
+	if (ast_pthread_create_background(&conference->record_thread, NULL, record_thread, conference)) {
+		ast_log(LOG_WARNING, "Failed to create recording channel for conference %s\n", conference->name);
+		ao2_ref(conference, -1); /* error so remove ref */
 		return -1;
 	}
 
@@ -786,52 +833,52 @@
 /*!
  * \brief Announce number of users in the conference bridge to the caller
  *
- * \param conference_bridge Conference bridge to peek at
- * \param conference_bridge_user Optional Caller
+ * \param conference Conference bridge to peek at
+ * \param user Optional Caller
  *
  * \note if caller is NULL, the announcment will be sent to all participants in the conference.
  * \return Returns 0 on success, -1 if the user hung up
  */
-static int announce_user_count(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user)
-{
-	const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference_bridge->b_profile.sounds);
-	const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference_bridge->b_profile.sounds);
-	const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference_bridge->b_profile.sounds);
-
-	if (conference_bridge->activeusers <= 1) {
+static int announce_user_count(struct confbridge_conference *conference, struct confbridge_user *user)
+{
+	const char *other_in_party = conf_get_sound(CONF_SOUND_OTHER_IN_PARTY, conference->b_profile.sounds);
+	const char *only_one = conf_get_sound(CONF_SOUND_ONLY_ONE, conference->b_profile.sounds);
+	const char *there_are = conf_get_sound(CONF_SOUND_THERE_ARE, conference->b_profile.sounds);
+
+	if (conference->activeusers <= 1) {
 		/* Awww we are the only person in the conference bridge OR we only have waitmarked users */
 		return 0;
-	} else if (conference_bridge->activeusers == 2) {
-		if (conference_bridge_user) {
+	} else if (conference->activeusers == 2) {
+		if (user) {
 			/* Eep, there is one other person */
-			if (ast_stream_and_wait(conference_bridge_user->chan,
+			if (ast_stream_and_wait(user->chan,
 				only_one,
 				"")) {
 				return -1;
 			}
 		} else {
-			play_sound_file(conference_bridge, only_one);
+			play_sound_file(conference, only_one);
 		}
 	} else {
 		/* Alas multiple others in here */
-		if (conference_bridge_user) {
-			if (ast_stream_and_wait(conference_bridge_user->chan,
+		if (user) {
+			if (ast_stream_and_wait(user->chan,
 				there_are,
 				"")) {
 				return -1;
 			}
-			if (ast_say_number(conference_bridge_user->chan, conference_bridge->activeusers - 1, "", ast_channel_language(conference_bridge_user->chan), NULL)) {
+			if (ast_say_number(user->chan, conference->activeusers - 1, "", ast_channel_language(user->chan), NULL)) {
 				return -1;
 			}
-			if (ast_stream_and_wait(conference_bridge_user->chan,
+			if (ast_stream_and_wait(user->chan,
 				other_in_party,
 				"")) {
 				return -1;
 			}
 		} else if (sound_file_exists(there_are) && sound_file_exists(other_in_party)) {
-			play_sound_file(conference_bridge, there_are);
-			play_sound_number(conference_bridge, conference_bridge->activeusers - 1);
-			play_sound_file(conference_bridge, other_in_party);
+			play_sound_file(conference, there_are);
+			play_sound_number(conference, conference->activeusers - 1);
+			play_sound_file(conference, other_in_party);
 		}
 	}
 	return 0;
@@ -840,7 +887,7 @@
 /*!
  * \brief Play back an audio file to a channel
  *
- * \param cbu User to play audio prompt to
+ * \param user User to play audio prompt to
  * \param filename Prompt to play
  *
  * \return Returns 0 on success, -1 if the user hung up
@@ -848,78 +895,79 @@
  * the entire conference while the sound is played. But don't unlock the conference bridge
  * in the middle of a state transition.
  */
-static int play_prompt_to_user(struct conference_bridge_user *cbu, const char *filename)
-{
-	return ast_stream_and_wait(cbu->chan, filename, "");
-}
-
-static void handle_video_on_join(struct conference_bridge *conference_bridge, struct ast_channel *chan, int marked)
+static int play_prompt_to_user(struct confbridge_user *user, const char *filename)
+{
+	return ast_stream_and_wait(user->chan, filename, "");
+}
+
+static void handle_video_on_join(struct confbridge_conference *conference, struct ast_channel *chan, int marked)
 {
 	/* Right now, only marked users are automatically set as the single src of video.*/
 	if (!marked) {
 		return;
 	}
 
-	if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED)) {
+	if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED)) {
 		int set = 1;
-		struct conference_bridge_user *tmp_user = NULL;
-		ao2_lock(conference_bridge);
+		struct confbridge_user *user = NULL;
+
+		ao2_lock(conference);
 		/* see if anyone is already the video src */
-		AST_LIST_TRAVERSE(&conference_bridge->active_list, tmp_user, list) {
-			if (tmp_user->chan == chan) {
+		AST_LIST_TRAVERSE(&conference->active_list, user, list) {
+			if (user->chan == chan) {
 				continue;
 			}
-			if (ast_bridge_is_video_src(conference_bridge->bridge, tmp_user->chan)) {
+			if (ast_bridge_is_video_src(conference->bridge, user->chan)) {
 				set = 0;
 				break;
 			}
 		}
-		ao2_unlock(conference_bridge);
+		ao2_unlock(conference);
 		if (set) {
-			ast_bridge_set_single_src_video_mode(conference_bridge->bridge, chan);
-		}
-	} else if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
+			ast_bridge_set_single_src_video_mode(conference->bridge, chan);
+		}
+	} else if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
 		/* we joined and are video capable, we override anyone else that may have already been the video feed */
-		ast_bridge_set_single_src_video_mode(conference_bridge->bridge, chan);
-	}
-}
-
-static void handle_video_on_exit(struct conference_bridge *conference_bridge, struct ast_channel *chan)
-{
-	struct conference_bridge_user *tmp_user = NULL;
+		ast_bridge_set_single_src_video_mode(conference->bridge, chan);
+	}
+}
+
+static void handle_video_on_exit(struct confbridge_conference *conference, struct ast_channel *chan)
+{
+	struct confbridge_user *user = NULL;
 
 	/* if this isn't a video source, nothing to update */
-	if (!ast_bridge_is_video_src(conference_bridge->bridge, chan)) {
+	if (!ast_bridge_is_video_src(conference->bridge, chan)) {
 		return;
 	}
 
-	ast_bridge_remove_video_src(conference_bridge->bridge, chan);
+	ast_bridge_remove_video_src(conference->bridge, chan);
 
 	/* If in follow talker mode, make sure to restore this mode on the
 	 * bridge when a source is removed.  It is possible this channel was
 	 * only set temporarily as a video source by an AMI or DTMF action. */
-	if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) {
-		ast_bridge_set_talker_src_video_mode(conference_bridge->bridge);
+	if (ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) {
+		ast_bridge_set_talker_src_video_mode(conference->bridge);
 	}
 
 	/* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */
-	if (!ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED) &&
-		!ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
+	if (!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED) &&
+		!ast_test_flag(&conference->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
 		return;
 	}
 
 	/* Make the next available marked user the video src.  */
-	ao2_lock(conference_bridge);
-	AST_LIST_TRAVERSE(&conference_bridge->active_list, tmp_user, list) {
-		if (tmp_user->chan == chan) {
+	ao2_lock(conference);
+	AST_LIST_TRAVERSE(&conference->active_list, user, list) {
+		if (user->chan == chan) {
 			continue;
 		}
-		if (ast_test_flag(&tmp_user->u_profile, USER_OPT_MARKEDUSER)) {
-			ast_bridge_set_single_src_video_mode(conference_bridge->bridge, tmp_user->chan);
+		if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
+			ast_bridge_set_single_src_video_mode(conference->bridge, user->chan);
 			break;
 		}
 	}
-	ao2_unlock(conference_bridge);
+	ao2_unlock(conference);
 }
 
 /*!
@@ -931,75 +979,75 @@
  */
 static void destroy_conference_bridge(void *obj)
 {
-	struct conference_bridge *conference_bridge = obj;
-
-	ast_debug(1, "Destroying conference bridge '%s'\n", conference_bridge->name);
-
-	if (conference_bridge->playback_chan) {

[... 11201 lines stripped ...]



More information about the asterisk-commits mailing list