[asterisk-commits] kmoore: branch kmoore/stasis-bridging-channel_events r386745 - in /team/kmoor...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Apr 27 10:09:32 CDT 2013


Author: kmoore
Date: Sat Apr 27 10:09:24 2013
New Revision: 386745

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386745
Log:
Multiple revisions 386626,386644,386689,386725-386726,386732

........
  r386626 | root | 2013-04-26 15:17:47 -0500 (Fri, 26 Apr 2013) | 39 lines
  
  Multiple revisions 386623-386624
  
  ........
    r386623 | dlee | 2013-04-26 15:03:32 -0500 (Fri, 26 Apr 2013) | 1 line
    
    Ignore *.[oi] files in res/res_sip
  ........
    r386624 | dlee | 2013-04-26 15:05:15 -0500 (Fri, 26 Apr 2013) | 27 lines
    
    Example of how to use the Stasis message bus
    
    In order to get people familiar with the Stasis message bus, it would
    be useful to have something of a tutorial. Since I'm not clever enough
    to think of some cool integration we could do with Twitter, I settled
    for something that might actually be useful.
    
    This patch adds a res_statsd.so module, which implements a basic
    statsd[1] client. Statsd is a very simple statistics gathering server,
    which can publish its results to a backend graphing engine, like
    Graphite[2]. There are several different Statsd server
    implementations[3], so you can pick what works best for your
    environment.
    
    The actual example of how to use the Stasis message bus is in
    res_chan_stats.so. This module demonstrates how to use subscriptions
    and the message router by monitoring messages and posting channels
    stats to the statsd server.
    
    A wiki page walking through res_chan_stats.so is forthcoming.
    
     [1]: https://github.com/etsy/statsd/
     [2]: http://graphite.readthedocs.org/en/latest/
     [3]: http://joemiller.me/2011/09/21/list-of-statsd-server-implementations/
    
    Review: https://reviewboard.asterisk.org/r/2460/
  ........
  
  Merged revisions 386623-386624 from file:///srv/subversion/repos/asterisk/trunk
........
  r386644 | root | 2013-04-26 16:17:42 -0500 (Fri, 26 Apr 2013) | 16 lines
  
  Multiple revisions 386638,386640
  
  ........
    r386638 | mmichelson | 2013-04-26 15:32:11 -0500 (Fri, 26 Apr 2013) | 5 lines
    
    Add an \extref doxygen pointer for libuuid.
    
    Thanks to Olle Johansson for suggesting this.
  ........
    r386640 | dlee | 2013-04-26 16:00:45 -0500 (Fri, 26 Apr 2013) | 1 line
    
    Removing stray printf from r386540
  ........
  
  Merged revisions 386638,386640 from file:///srv/subversion/repos/asterisk/trunk
........
  r386689 | root | 2013-04-26 17:17:37 -0500 (Fri, 26 Apr 2013) | 74 lines
  
  Multiple revisions 386676,386684-386686
  
  ........
    r386676 | mjordan | 2013-04-26 16:27:24 -0500 (Fri, 26 Apr 2013) | 19 lines
    
    Clean up resources in features on exit
    
    This patch cleans up two things features:
    * It properly unregisters the CLI commands that features registered
    * It cancels and performs a pthread_join on the created parking thread. This
      not only properly joins a non-detached thread, but also prevents disposing
      of the parking lots prior to the parking thread completely exiting.
    
    (closes issue ASTERISK-21407)
    Reported by: Corey Farrell
    patches:
      features_shutdown-r2.patch uploaded by Corey Farrell (License 5909)
    ........
    
    Merged revisions 386641 from http://svn.asterisk.org/svn/asterisk/branches/1.8
    ........
    
    Merged revisions 386642 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
    r386684 | dlee | 2013-04-26 16:31:39 -0500 (Fri, 26 Apr 2013) | 5 lines
    
    By popular demand, putting the about-to-load-module printf back.
    
    But now it only prints during the initial startup, and prints at verbose 1
    level.
  ........
    r386685 | mjordan | 2013-04-26 16:34:16 -0500 (Fri, 26 Apr 2013) | 20 lines
    
    Clean up memory leak in config file on off nominal paths when glob is allowed
    
    If a system allows for its usage, Asterisk will use glob to help parse
    Asterisk .conf files. The config file loading routine was leaking the memory
    allocated by the glob() routine when the config file was in an unmodified
    or invalid state.
    
    This patch properly calls globfree in those off nominal paths.
    
    (closes issue ASTERISK-21412)
    Reported by: Corey Farrell
    patches:
      config_glob_leak.patch uploaded by Corey Farrell (license 5909)
    ........
    
    Merged revisions 386672 from http://svn.asterisk.org/svn/asterisk/branches/1.8
    ........
    
    Merged revisions 386677 from http://svn.asterisk.org/svn/asterisk/branches/11
  ........
    r386686 | mjordan | 2013-04-26 16:52:06 -0500 (Fri, 26 Apr 2013) | 16 lines
    
    Add missing module dependencies to various res_sip* modules
    
    This patch updates the various res_sip modules with their proper menuselect
    options and proper dependencies, such that Asterisk still has a snowball's
    chance in hell of compiling without pjproject.
    
    Much thanks to snuffy(-home|-work) for making everyone's life
    easier with this patch.
    
    Review: https://reviewboard.asterisk.org/r/2472/
    
    (closes issue ASTERISK-21669)
    Reported by: snuffy
    patches:
      xml-depends.diff uploaded by snuffy (license 5024)
  ........
  
  Merged revisions 386676,386684-386686 from file:///srv/subversion/repos/asterisk/trunk
........
  r386725 | rmudgett | 2013-04-26 22:34:17 -0500 (Fri, 26 Apr 2013) | 17 lines
  
  * Add kick_me channel list option to ast_bridge_merge().
  
  * Make bridge_merge_do() kick out channels in the destination bridge after
  the other channels have been moved.  We don't want pulling the kicked
  channel to dissolve the destination bridge before moving any channels in
  the source bridge.
  
  * Added the merge_best_direction option to ast_bridge_merge().  Factored
  out bridge_merge_determine_direction() from check_merge_optimize_out() to
  support merge_best_direction.
  
  * Add AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE option flag and support in
  bridge_merge_do() and bridge_move_locked() for it.
  
  * Make bridge_channel_push() fail if the swap channel is in the process of
  leaving the bridge.
........
  r386726 | rmudgett | 2013-04-26 22:37:56 -0500 (Fri, 26 Apr 2013) | 1 line
  
  Add note to implement AST_BRIDGE_CHANNEL_FLAG_LONELY support.
........
  r386732 | root | 2013-04-27 07:17:52 -0500 (Sat, 27 Apr 2013) | 14 lines
  
  Add support for a realtime sorcery module.
  
  This change does the following:
  
  1. Adds the sorcery realtime module
  2. Adds unit tests for the sorcery realtime module
  3. Changes the realtime core to use an ast_variable list instead of variadic arguments
  4. Changes all realtime drivers to accept an ast_variable list
  
  Review: https://reviewboard.asterisk.org/r/2424/
  ........
  
  Merged revisions 386731 from file:///srv/subversion/repos/asterisk/trunk
........

Merged revisions 386626,386644,386689,386725-386726,386732 from http://svn.asterisk.org/svn/asterisk/team/group/bridge_construction

Added:
    team/kmoore/stasis-bridging-channel_events/configs/statsd.conf.sample
      - copied unchanged from r386732, team/group/bridge_construction/configs/statsd.conf.sample
    team/kmoore/stasis-bridging-channel_events/include/asterisk/statsd.h
      - copied unchanged from r386732, team/group/bridge_construction/include/asterisk/statsd.h
    team/kmoore/stasis-bridging-channel_events/res/res_chan_stats.c
      - copied unchanged from r386732, team/group/bridge_construction/res/res_chan_stats.c
    team/kmoore/stasis-bridging-channel_events/res/res_sorcery_realtime.c
      - copied unchanged from r386732, team/group/bridge_construction/res/res_sorcery_realtime.c
    team/kmoore/stasis-bridging-channel_events/res/res_statsd.c
      - copied unchanged from r386732, team/group/bridge_construction/res/res_statsd.c
    team/kmoore/stasis-bridging-channel_events/res/res_statsd.exports.in
      - copied unchanged from r386732, team/group/bridge_construction/res/res_statsd.exports.in
    team/kmoore/stasis-bridging-channel_events/tests/test_sorcery_realtime.c
      - copied unchanged from r386732, team/group/bridge_construction/tests/test_sorcery_realtime.c
Modified:
    team/kmoore/stasis-bridging-channel_events/   (props changed)
    team/kmoore/stasis-bridging-channel_events/CHANGES
    team/kmoore/stasis-bridging-channel_events/addons/res_config_mysql.c
    team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_features.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/config.h
    team/kmoore/stasis-bridging-channel_events/include/asterisk/utils.h
    team/kmoore/stasis-bridging-channel_events/main/bridging.c
    team/kmoore/stasis-bridging-channel_events/main/config.c
    team/kmoore/stasis-bridging-channel_events/main/features.c
    team/kmoore/stasis-bridging-channel_events/main/loader.c
    team/kmoore/stasis-bridging-channel_events/main/sorcery.c
    team/kmoore/stasis-bridging-channel_events/main/uuid.c
    team/kmoore/stasis-bridging-channel_events/res/res_config_curl.c
    team/kmoore/stasis-bridging-channel_events/res/res_config_ldap.c
    team/kmoore/stasis-bridging-channel_events/res/res_config_odbc.c
    team/kmoore/stasis-bridging-channel_events/res/res_config_pgsql.c
    team/kmoore/stasis-bridging-channel_events/res/res_config_sqlite3.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip/   (props changed)
    team/kmoore/stasis-bridging-channel_events/res/res_sip_acl.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_dtmf_info.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_endpoint_identifier_constant.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_endpoint_identifier_ip.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_endpoint_identifier_user.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_logger.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_mwi.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_nat.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_outbound_authenticator_digest.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_outbound_registration.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_pubsub.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_registrar.c
    team/kmoore/stasis-bridging-channel_events/res/res_sip_rfc3326.c

Propchange: team/kmoore/stasis-bridging-channel_events/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.

Propchange: team/kmoore/stasis-bridging-channel_events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sat Apr 27 10:09:24 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-386618
+/team/group/bridge_construction:1-386744

Modified: team/kmoore/stasis-bridging-channel_events/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/CHANGES?view=diff&rev=386745&r1=386744&r2=386745
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/CHANGES (original)
+++ team/kmoore/stasis-bridging-channel_events/CHANGES Sat Apr 27 10:09:24 2013
@@ -161,6 +161,12 @@
    If any resource is available the device state is considered to be not in use.
    If no resources exist or all are unavailable the device state is considered
    to be unavailable.
+
+Sorcery
+------------------
+ * All future modules which utilize Sorcery for object persistence must have a
+   column named "id" within their schema when using the Sorcery realtime module.
+   This column must be able to contain a string of up to 128 characters in length.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 10 to Asterisk 11 --------------------

Modified: team/kmoore/stasis-bridging-channel_events/addons/res_config_mysql.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/addons/res_config_mysql.c?view=diff&rev=386745&r1=386744&r2=386745
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/addons/res_config_mysql.c (original)
+++ team/kmoore/stasis-bridging-channel_events/addons/res_config_mysql.c Sat Apr 27 10:09:24 2013
@@ -316,7 +316,7 @@
 	return orig;
 }
 
-static struct ast_variable *realtime_mysql(const char *database, const char *table, va_list ap)
+static struct ast_variable *realtime_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
 {
 	struct mysql_conn *dbh;
 	MYSQL_RES *result;
@@ -328,7 +328,7 @@
 	char *stringp;
 	char *chunk;
 	char *op;
-	const char *newparam, *newval;
+	const struct ast_variable *field = rt_fields;
 	struct ast_variable *var=NULL, *prev=NULL;
 
 	if (!(dbh = find_database(database, 0))) {
@@ -343,7 +343,7 @@
 	}
 
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *)))  {
+	if (!field) {
 		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;
@@ -358,21 +358,20 @@
 	/* Create the first part of the query using the first parameter/value pairs we just extracted
 	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
 
-	if (!strchr(newparam, ' ')) 
+	if (!strchr(field->name, ' ')) 
 		op = " ="; 
 	else 
 		op = "";
 
-	ESCAPE_STRING(buf, newval);
-	ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, ast_str_buffer(buf));
-	while ((newparam = va_arg(ap, const char *))) {
-		newval = va_arg(ap, const char *);
-		if (!strchr(newparam, ' ')) 
+	ESCAPE_STRING(buf, field->value);
+	ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, field->name, op, ast_str_buffer(buf));
+	while ((field = field->next)) {
+		if (!strchr(field->name, ' ')) 
 			op = " ="; 
 		else
 			op = "";
-		ESCAPE_STRING(buf, newval);
-		ast_str_append(&sql, 0, " AND %s%s '%s'", newparam, op, ast_str_buffer(buf));
+		ESCAPE_STRING(buf, field->value);
+		ast_str_append(&sql, 0, " AND %s%s '%s'", field->name, op, ast_str_buffer(buf));
 	}
 
 	ast_debug(1, "MySQL RealTime: Retrieve SQL: %s\n", ast_str_buffer(sql));
@@ -417,7 +416,7 @@
 	return var;
 }
 
-static struct ast_config *realtime_multi_mysql(const char *database, const char *table, va_list ap)
+static struct ast_config *realtime_multi_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
 {
 	struct mysql_conn *dbh;
 	MYSQL_RES *result;
@@ -430,7 +429,7 @@
 	char *stringp;
 	char *chunk;
 	char *op;
-	const char *newparam, *newval;
+	const struct ast_variable *field = rt_fields;
 	struct ast_variable *var = NULL;
 	struct ast_config *cfg = NULL;
 	struct ast_category *cat = NULL;
@@ -454,14 +453,14 @@
 	}
 
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *)))  {
+	if (!field) {
 		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);
 		return NULL;
 	}
 
-	initfield = ast_strdupa(newparam);
+	initfield = ast_strdupa(field->name);
 	if ((op = strchr(initfield, ' '))) {
 		*op = '\0';
 	}
@@ -476,18 +475,17 @@
 	/* Create the first part of the query using the first parameter/value pairs we just extracted
 	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
 
-	if (!strchr(newparam, ' '))
+	if (!strchr(field->name, ' '))
 		op = " =";
 	else
 		op = "";
 
-	ESCAPE_STRING(buf, newval);
-	ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, ast_str_buffer(buf));
-	while ((newparam = va_arg(ap, const char *))) {
-		newval = va_arg(ap, const char *);
-		if (!strchr(newparam, ' ')) op = " ="; else op = "";
-		ESCAPE_STRING(buf, newval);
-		ast_str_append(&sql, 0, " AND %s%s '%s'", newparam, op, ast_str_buffer(buf));
+	ESCAPE_STRING(buf, field->value);
+	ast_str_set(&sql, 0, "SELECT * FROM %s WHERE %s%s '%s'", table, field->name, op, ast_str_buffer(buf));
+	while ((field = field->next)) {
+		if (!strchr(field->name, ' ')) op = " ="; else op = "";
+		ESCAPE_STRING(buf, field->value);
+		ast_str_append(&sql, 0, " AND %s%s '%s'", field->name, op, ast_str_buffer(buf));
 	}
 
 	if (initfield) {
@@ -540,11 +538,11 @@
 	return cfg;
 }
 
-static int update_mysql(const char *database, const char *tablename, const char *keyfield, const char *lookup, va_list ap)
+static int update_mysql(const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
 {
 	struct mysql_conn *dbh;
 	my_ulonglong numrows;
-	const char *newparam, *newval;
+	const struct ast_variable *field = rt_fields;
 	struct ast_str *sql = ast_str_thread_get(&sql_buf, 100), *buf = ast_str_thread_get(&scratch_buf, 100);
 	struct tables *table;
 	struct columns *column = NULL;
@@ -574,7 +572,7 @@
 	}
 
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *)))  {
+	if (!field) {
 		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);
@@ -582,8 +580,8 @@
 	}
 
 	/* Check that the column exists in the table */
-	if (!(column = find_column(table, newparam))) {
-		ast_log(LOG_ERROR, "MySQL RealTime: Updating column '%s', but that column does not exist within the table '%s' (first pair MUST exist)!\n", newparam, tablename);
+	if (!(column = find_column(table, field->name))) {
+		ast_log(LOG_ERROR, "MySQL RealTime: Updating column '%s', but that column does not exist within the table '%s' (first pair MUST exist)!\n", field->name, tablename);
 		release_table(table);
 		release_database(dbh);
 		return -1;
@@ -599,29 +597,27 @@
 	/* Create the first part of the query using the first parameter/value pairs we just extracted
 	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
 
-	ESCAPE_STRING(buf, newval);
-	ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, newparam, ast_str_buffer(buf));
+	ESCAPE_STRING(buf, field->value);
+	ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf));
 
 	/* If the column length isn't long enough, give a chance to lengthen it. */
 	if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-		internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-	}
-
-	while ((newparam = va_arg(ap, const char *))) {
-		newval = va_arg(ap, const char *);
-
+		internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+	}
+
+	while ((field = field->next)) {
 		/* If the column is not within the table, then skip it */
-		if (!(column = find_column(table, newparam))) {
-			ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", newparam, tablename);
+		if (!(column = find_column(table, field->name))) {
+			ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", field->name, tablename);
 			continue;
 		}
 
-		ESCAPE_STRING(buf, newval);
-		ast_str_append(&sql, 0, ", `%s` = '%s'", newparam, ast_str_buffer(buf));
+		ESCAPE_STRING(buf, field->value);
+		ast_str_append(&sql, 0, ", `%s` = '%s'", field->value, ast_str_buffer(buf));
 
 		/* If the column length isn't long enough, give a chance to lengthen it. */
 		if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-			internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+			internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
 		}
 	}
 
@@ -653,12 +649,12 @@
 	return (int)numrows;
 }
 
-static int update2_mysql(const char *database, const char *tablename, va_list ap)
+static int update2_mysql(const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
 {
 	struct mysql_conn *dbh;
 	my_ulonglong numrows;
 	int first;
-	const char *newparam, *newval;
+	const struct ast_variable *field;
 	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);
 	struct tables *table;
@@ -697,51 +693,38 @@
 	}
 
 	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);
+	for (field = lookup_fields; field; field = field->next) {
+		if (!(column = find_column(table, field->name))) {
+			ast_log(LOG_ERROR, "Updating on column '%s', but that column does not exist within the table '%s'!\n", field->name, tablename);
 			release_table(table);
 			release_database(dbh);
 			return -1;
 		}
-		if (!(newval = va_arg(ap, const char *))) {
-			ast_log(LOG_ERROR, "Invalid arguments: no value specified for column '%s' on '%s@%s'\n", newparam, tablename, database);
-			release_table(table);
-			release_database(dbh);
-			return -1;
-		}
-		ESCAPE_STRING(buf, newval);
-		ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", newparam, ast_str_buffer(buf));
+		ESCAPE_STRING(buf, field->value);
+		ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf));
 		first = 0;
 
 		/* If the column length isn't long enough, give a chance to lengthen it. */
 		if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-			internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+			internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
 		}
 	}
 
 	first = 1;
-	while ((newparam = va_arg(ap, const char *))) {
-		if (!(newval = va_arg(ap, const char *))) {
-			ast_log(LOG_ERROR, "Invalid arguments: no value specified for column '%s' on '%s@%s'\n", newparam, tablename, database);
-			release_table(table);
-			release_database(dbh);
-			return -1;
-		}
-
+	for (field = update_fields; field; field = field->next) {
 		/* If the column is not within the table, then skip it */
-		if (!(column = find_column(table, newparam))) {
-			ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", newparam, tablename);
+		if (!(column = find_column(table, field->name))) {
+			ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", field->name, tablename);
 			continue;
 		}
 
-		ESCAPE_STRING(buf, newval);
-		ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", newparam, ast_str_buffer(buf));
+		ESCAPE_STRING(buf, field->value);
+		ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf));
 		first = 0;
 
 		/* If the column length isn't long enough, give a chance to lengthen it. */
 		if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
-			internal_require(database, tablename, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+			internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
 		}
 	}
 
@@ -773,14 +756,14 @@
 	return (int)numrows;
 }
  
-static int store_mysql(const char *database, const char *table, va_list ap)
+static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
 {
 	struct mysql_conn *dbh;
 	my_ulonglong insertid;
 	struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
 	struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16);
 	struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
-	const char *newparam, *newval;
+	const struct ast_variable *field = rt_fields;
 
 	if (!(dbh = find_database(database, 1))) {
 		ast_log(LOG_WARNING, "MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
@@ -793,7 +776,7 @@
 		return -1;
 	}
 	/* Get the first parameter and first value in our list of passed paramater/value pairs */
-	if (!(newparam = va_arg(ap, const char *)) || !(newval = va_arg(ap, const char *))) {
+	if (!field) {
 		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;
@@ -805,20 +788,17 @@
 	}
 	/* Create the first part of the query using the first parameter/value pairs we just extracted
 		If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
-	ESCAPE_STRING(buf, newval);
-	ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, newparam);
+	ESCAPE_STRING(buf, field->value);
+	ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name);
 	ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf));
 
-	internal_require(database, table, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
-
-	while ((newparam = va_arg(ap, const char *))) {
-		if ((newval = va_arg(ap, const char *))) {
-			ESCAPE_STRING(buf, newval);
-		} else {
-			ast_str_reset(buf);
-		}
-		if (internal_require(database, table, newparam, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) {
-			ast_str_append(&sql, 0, ", `%s`", newparam);
+	internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
+
+	while ((field = field->next)) {
+		ESCAPE_STRING(buf, field->value);
+
+		if (internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) {
+			ast_str_append(&sql, 0, ", `%s`", field->name);
 			ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
 		}
 	}
@@ -846,13 +826,13 @@
 	return (int)insertid;
 }
 
-static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
+static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
 {
 	struct mysql_conn *dbh;
 	my_ulonglong numrows;
 	struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
 	struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
-	const char *newparam, *newval;
+	const struct ast_variable *field;
 
 	if (!(dbh = find_database(database, 1))) {
 		ast_log(LOG_WARNING, "MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
@@ -884,10 +864,9 @@
 	   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
 	ESCAPE_STRING(buf, lookup);
 	ast_str_set(&sql, 0, "DELETE FROM %s WHERE `%s` = '%s'", table, keyfield, ast_str_buffer(buf));
-	while ((newparam = va_arg(ap, const char *))) {
-		newval = va_arg(ap, const char *);
-		ESCAPE_STRING(buf, newval);
-		ast_str_append(&sql, 0, " AND `%s` = '%s'", newparam, ast_str_buffer(buf));
+	for (field = rt_fields; field; field = field->next) {
+		ESCAPE_STRING(buf, field->value);
+		ast_str_append(&sql, 0, " AND `%s` = '%s'", field->name, ast_str_buffer(buf));
 	}
 
 	ast_debug(1, "MySQL RealTime: Delete SQL: %s\n", ast_str_buffer(sql));

Modified: team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h?view=diff&rev=386745&r1=386744&r2=386745
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h (original)
+++ team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging.h Sat Apr 27 10:09:24 2013
@@ -450,9 +450,8 @@
  * \note This must be done after a bridge constructor has
  * completed setting up the new bridge but before it returns.
  *
- * \note After a bridge is registered, the bridge must be
- * explicitly destroyed by ast_bridge_destroy() to get rid of
- * the bridge.
+ * \note After a bridge is registered, ast_bridge_destroy() must
+ * eventually be called to get rid of the bridge.
  *
  * \retval bridge on success.
  * \retval NULL on error.
@@ -758,6 +757,9 @@
  *
  * \param dst_bridge Destination bridge of merge.
  * \param src_bridge Source bridge of merge.
+ * \param merge_best_direction TRUE if don't care about which bridge merges into the other.
+ * \param kick_me Array of channels to kick from the bridges.
+ * \param num_kick Number of channels in the kick_me array.
  *
  * \retval 0 on success
  * \retval -1 on failure
@@ -765,18 +767,13 @@
  * Example usage:
  *
  * \code
- * ast_bridge_merge(dst_bridge, src_bridge);
+ * ast_bridge_merge(dst_bridge, src_bridge, 0, NULL, 0);
  * \endcode
  *
- * This merges the bridge pointed to by src_bridge into the bridge
- * pointed to by dst_bridge.  In reality all of the channels in
- * src_bridge are moved to dst_bridge.
- *
- * \note The source bridge has no active channels in it when
- * this operation is completed.  The caller should explicitly
- * call ast_bridge_destroy().
- */
-int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge);
+ * This moves the channels in src_bridge into the bridge pointed
+ * to by dst_bridge.
+ */
+int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick);
 
 /*!
  * \brief Move a channel from one bridge to another.

Modified: team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_features.h?view=diff&rev=386745&r1=386744&r2=386745
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_features.h (original)
+++ team/kmoore/stasis-bridging-channel_events/include/asterisk/bridging_features.h Sat Apr 27 10:09:24 2013
@@ -54,6 +54,8 @@
 	AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP = (1 << 0),
 	/*! This channel leaves the bridge if all participants have this flag set. */
 	AST_BRIDGE_CHANNEL_FLAG_LONELY = (1 << 1),
+	/*! This channel cannot be moved to another bridge. */
+	AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE = (1 << 2),
 };
 
 /*! \brief Built in DTMF features */

Modified: team/kmoore/stasis-bridging-channel_events/include/asterisk/config.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/include/asterisk/config.h?view=diff&rev=386745&r1=386744&r2=386745
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/include/asterisk/config.h (original)
+++ team/kmoore/stasis-bridging-channel_events/include/asterisk/config.h Sat Apr 27 10:09:24 2013
@@ -98,12 +98,12 @@
 };
 
 typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, struct ast_flags flags, const char *suggested_include_file, const char *who_asked);
-typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
-typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
-typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
-typedef int realtime_update2(const char *database, const char *table, va_list ap);
-typedef int realtime_store(const char *database, const char *table, va_list ap);
-typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
+typedef struct ast_variable *realtime_var_get(const char *database, const char *table, const struct ast_variable *fields);
+typedef struct ast_config *realtime_multi_get(const char *database, const char *table, const struct ast_variable *fields);
+typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
+typedef int realtime_update2(const char *database, const char *table, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields);
+typedef int realtime_store(const char *database, const char *table, const struct ast_variable *fields);
+typedef int realtime_destroy(const char *database, const char *table, const char *keyfield, const char *entity, const struct ast_variable *fields);
 
 /*!
  * \brief Function pointer called to ensure database schema is properly configured for realtime use
@@ -305,7 +305,9 @@
  * You should use the constant SENTINEL to terminate arguments, in
  * order to preserve cross-platform compatibility.
  */
+struct ast_variable *ast_load_realtime_fields(const char *family, const struct ast_variable *fields);
 struct ast_variable *ast_load_realtime(const char *family, ...) attribute_sentinel;
+struct ast_variable *ast_load_realtime_all_fields(const char *family, const struct ast_variable *fields);
 struct ast_variable *ast_load_realtime_all(const char *family, ...) attribute_sentinel;
 
 /*!
@@ -363,6 +365,7 @@
  * \brief Retrieve realtime configuration
  *
  * \param family which family/config to lookup
+ * \param fields list of fields
  *
  * \details
  * This will use builtin configuration backends to look up a particular
@@ -373,6 +376,23 @@
  *
  * \return An ast_config with one or more results
  * \retval NULL Error or no results returned
+ */
+struct ast_config *ast_load_realtime_multientry_fields(const char *family, const struct ast_variable *fields);
+
+/*!
+ * \brief Retrieve realtime configuration
+ *
+ * \param family which family/config to lookup
+ *
+ * \details
+ * This will use builtin configuration backends to look up a particular
+ * entity in realtime and return a variable list of its parameters. Unlike
+ * the ast_load_realtime, this function can return more than one entry and
+ * is thus stored inside a traditional ast_config structure rather than
+ * just returning a linked list of variables.
+ *
+ * \return An ast_config with one or more results
+ * \retval NULL Error or no results returned
  *
  * \note You should use the constant SENTINEL to terminate arguments, in
  * order to preserve cross-platform compatibility.
@@ -385,6 +405,21 @@
  * \param family which family/config to be updated
  * \param keyfield which field to use as the key
  * \param lookup which value to look for in the key field to match the entry.
+ * \param fields fields to update
+ *
+ * \details
+ * This function is used to update a parameter in realtime configuration space.
+ *
+ * \return Number of rows affected, or -1 on error.
+ */
+int ast_update_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields);
+
+/*!
+ * \brief Update realtime configuration
+ *
+ * \param family which family/config to be updated
+ * \param keyfield which field to use as the key
+ * \param lookup which value to look for in the key field to match the entry.
  *
  * \details
  * This function is used to update a parameter in realtime configuration space.
@@ -400,6 +435,8 @@
  * \brief Update realtime configuration
  *
  * \param family which family/config to be updated
+ * \param lookup_fields fields used to look up entries
+ * \param update_fields fields to update
  *
  * \details
  * This function is used to update a parameter in realtime configuration space.
@@ -408,6 +445,21 @@
  * lookup values and the other to terminate the listing of fields to update.
  *
  * \return Number of rows affected, or -1 on error.
+ */
+int ast_update2_realtime_fields(const char *family, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields);
+
+/*!
+ * \brief Update realtime configuration
+ *
+ * \param family which family/config to be updated
+ *
+ * \details
+ * This function is used to update a parameter in realtime configuration space.
+ * It includes the ability to lookup a row based upon multiple key criteria.
+ * As a result, this function includes two sentinel values, one to terminate
+ * lookup values and the other to terminate the listing of fields to update.
+ *
+ * \return Number of rows affected, or -1 on error.
  *
  * \note You should use the constant SENTINEL to terminate arguments, in
  * order to preserve cross-platform compatibility.
@@ -418,6 +470,7 @@
  * \brief Create realtime configuration
  *
  * \param family which family/config to be created
+ * \param fields fields themselves
  *
  * \details
  * This function is used to create a parameter in realtime configuration space.
@@ -428,11 +481,44 @@
  * On the MySQL engine only, for reasons of backwards compatibility, the return
  * value is the insert ID.  This value is nonportable and may be changed in a
  * future version to match the other engines.
+ */
+int ast_store_realtime_fields(const char *family, const struct ast_variable *fields);
+
+/*!
+ * \brief Create realtime configuration
+ *
+ * \param family which family/config to be created
+ *
+ * \details
+ * This function is used to create a parameter in realtime configuration space.
+ *
+ * \return Number of rows affected, or -1 on error.
+ *
+ * \note
+ * On the MySQL engine only, for reasons of backwards compatibility, the return
+ * value is the insert ID.  This value is nonportable and may be changed in a
+ * future version to match the other engines.
  *
  * \note You should use the constant SENTINEL to terminate arguments, in
  * order to preserve cross-platform compatibility.
  */
 int ast_store_realtime(const char *family, ...) attribute_sentinel;
+
+/*!
+ * \brief Destroy realtime configuration
+ *
+ * \param family which family/config to be destroyed
+ * \param keyfield which field to use as the key
+ * \param lookup which value to look for in the key field to match the entry.
+ * \param fields fields themselves
+ *
+ * \details
+ * This function is used to destroy an entry in realtime configuration space.
+ * Additional params are used as keys.
+ *
+ * \return Number of rows affected, or -1 on error.
+ */
+int ast_destroy_realtime_fields(const char *family, const char *keyfield, const char *lookup, const struct ast_variable *fields);
 
 /*!
  * \brief Destroy realtime configuration
@@ -502,6 +588,19 @@
  * \retval 0 if it is not
  */
 int ast_realtime_is_mapping_defined(const char *family);
+
+#ifdef TEST_FRAMEWORK
+/*!
+ * \brief Add an explicit mapping for a family
+ *
+ * \param name Family name
+ * \param driver Driver to use
+ * \param database Database to access
+ * \param table Table to use
+ * \param priority Priority of this mapping
+ */
+int ast_realtime_append_mapping(const char *name, const char *driver, const char *database, const char *table, int priority);
+#endif
 
 /*!
  * \brief Exposed initialization method for core process

Modified: team/kmoore/stasis-bridging-channel_events/include/asterisk/utils.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-bridging-channel_events/include/asterisk/utils.h?view=diff&rev=386745&r1=386744&r2=386745
==============================================================================
--- team/kmoore/stasis-bridging-channel_events/include/asterisk/utils.h (original)
+++ team/kmoore/stasis-bridging-channel_events/include/asterisk/utils.h Sat Apr 27 10:09:24 2013
@@ -458,6 +458,11 @@
 
 long int ast_random(void);
 
+/*!

[... 2909 lines stripped ...]



More information about the asterisk-commits mailing list