[asterisk-commits] jrose: branch jrose/bridge_projects r387001 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 30 13:19:41 CDT 2013
Author: jrose
Date: Tue Apr 30 13:19:36 2013
New Revision: 387001
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387001
Log:
merge from bridge_construction and address conflicts.
Added:
team/jrose/bridge_projects/res/res_sorcery_realtime.c
- copied unchanged from r386939, team/group/bridge_construction/res/res_sorcery_realtime.c
team/jrose/bridge_projects/tests/test_sorcery_realtime.c
- copied unchanged from r386939, team/group/bridge_construction/tests/test_sorcery_realtime.c
Modified:
team/jrose/bridge_projects/ (props changed)
team/jrose/bridge_projects/CHANGES
team/jrose/bridge_projects/addons/res_config_mysql.c
team/jrose/bridge_projects/apps/app_queue.c
team/jrose/bridge_projects/include/asterisk/bridging.h
team/jrose/bridge_projects/include/asterisk/bridging_features.h
team/jrose/bridge_projects/include/asterisk/config.h
team/jrose/bridge_projects/include/asterisk/doxygen/commits.h
team/jrose/bridge_projects/include/asterisk/utils.h
team/jrose/bridge_projects/main/bridging.c
team/jrose/bridge_projects/main/config.c
team/jrose/bridge_projects/main/sorcery.c
team/jrose/bridge_projects/res/res_config_curl.c
team/jrose/bridge_projects/res/res_config_ldap.c
team/jrose/bridge_projects/res/res_config_odbc.c
team/jrose/bridge_projects/res/res_config_pgsql.c
team/jrose/bridge_projects/res/res_config_sqlite.c
team/jrose/bridge_projects/res/res_config_sqlite3.c
team/jrose/bridge_projects/res/res_sip.c
team/jrose/bridge_projects/res/res_stasis_http.c
team/jrose/bridge_projects/rest-api-templates/swagger_model.py
team/jrose/bridge_projects/sounds/Makefile
team/jrose/bridge_projects/tests/test_stasis_http.c
Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.
Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
--- bridge_construction-integrated (original)
+++ bridge_construction-integrated Tue Apr 30 13:19:36 2013
@@ -1,1 +1,1 @@
-/trunk:1-386688
+/trunk:1-386938
Propchange: team/jrose/bridge_projects/
------------------------------------------------------------------------------
--- bridge_projects-integrated (original)
+++ bridge_projects-integrated Tue Apr 30 13:19:36 2013
@@ -1,1 +1,1 @@
-/team/group/bridge_construction:1-386694
+/team/group/bridge_construction:1-386991
Modified: team/jrose/bridge_projects/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/CHANGES?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/CHANGES (original)
+++ team/jrose/bridge_projects/CHANGES Tue Apr 30 13:19:36 2013
@@ -212,9 +212,17 @@
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 --------------------
------------------------------------------------------------------------------
+
+
Build System
-------------------
@@ -359,6 +367,9 @@
state_interface has been set.
* Add queue monitoring hints. exten => 8501,hint,Queue:markq.
+
+ * App_queue will now play periodic announcements for the caller that
+ holds the first position in the queue while waiting for answer.
SayUnixTime
------------------
Modified: team/jrose/bridge_projects/addons/res_config_mysql.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/addons/res_config_mysql.c?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/addons/res_config_mysql.c (original)
+++ team/jrose/bridge_projects/addons/res_config_mysql.c Tue Apr 30 13:19:36 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/jrose/bridge_projects/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/apps/app_queue.c?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/apps/app_queue.c (original)
+++ team/jrose/bridge_projects/apps/app_queue.c Tue Apr 30 13:19:36 2013
@@ -4072,7 +4072,7 @@
*
* \todo eventually all call forward logic should be intergerated into and replaced by ast_call_forward()
*/
-static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
+static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed, int ringing)
{
const char *queue = qe->parent->name;
struct callattempt *o, *start = NULL, *prev = NULL;
@@ -4583,6 +4583,16 @@
}
}
+ /* Make a position announcement, if enabled */
+ if (qe->parent->announcefrequency) {
+ say_position(qe, ringing);
+ }
+
+ /* Make a periodic announcement, if enabled */
+ if (qe->parent->periodicannouncefrequency) {
+ say_periodic_announcement(qe, ringing);
+ }
+
if (!*to) {
for (o = start; o; o = o->call_next) {
rna(orig, qe, o->interface, o->member->membername, 1);
@@ -5409,7 +5419,7 @@
ring_one(qe, outgoing, &numbusies);
lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies,
ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT),
- forwardsallowed);
+ forwardsallowed, ringing);
/* The ast_channel_datastore_remove() function could fail here if the
* datastore was moved to another channel during a masquerade. If this is
* the case, don't free the datastore here because later, when the channel
Modified: team/jrose/bridge_projects/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/bridging.h?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/bridging.h (original)
+++ team/jrose/bridge_projects/include/asterisk/bridging.h Tue Apr 30 13:19:36 2013
@@ -452,9 +452,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.
@@ -760,6 +759,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
@@ -767,18 +769,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/jrose/bridge_projects/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/bridging_features.h?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/bridging_features.h (original)
+++ team/jrose/bridge_projects/include/asterisk/bridging_features.h Tue Apr 30 13:19:36 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/jrose/bridge_projects/include/asterisk/config.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/config.h?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/config.h (original)
+++ team/jrose/bridge_projects/include/asterisk/config.h Tue Apr 30 13:19:36 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/jrose/bridge_projects/include/asterisk/doxygen/commits.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/doxygen/commits.h?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/doxygen/commits.h (original)
+++ team/jrose/bridge_projects/include/asterisk/doxygen/commits.h Tue Apr 30 13:19:36 2013
@@ -110,5 +110,5 @@
*
* For more detailed information about working with branches and merging,
* see the following page on %asterisk.org:
- * \arg http://www.asterisk.org/developers/svn-branching-merging
+ * \arg https://wiki.asterisk.org/wiki/display/AST/Subversion+Usage
*/
Modified: team/jrose/bridge_projects/include/asterisk/utils.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/utils.h?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/utils.h (original)
+++ team/jrose/bridge_projects/include/asterisk/utils.h Tue Apr 30 13:19:36 2013
@@ -324,8 +324,8 @@
res = (int) *input + *value;
if (res > 32767)
*input = 32767;
- else if (res < -32767)
- *input = -32767;
+ else if (res < -32768)
+ *input = -32768;
else
*input = (short) res;
}
@@ -337,8 +337,8 @@
res = (int) *input - *value;
if (res > 32767)
*input = 32767;
- else if (res < -32767)
- *input = -32767;
+ else if (res < -32768)
+ *input = -32768;
else
*input = (short) res;
}
@@ -350,8 +350,8 @@
res = (int) *input * *value;
if (res > 32767)
*input = 32767;
- else if (res < -32767)
- *input = -32767;
+ else if (res < -32768)
+ *input = -32768;
else
*input = (short) res;
}
Modified: team/jrose/bridge_projects/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/bridging.c?view=diff&rev=387001&r1=387000&r2=387001
==============================================================================
--- team/jrose/bridge_projects/main/bridging.c (original)
+++ team/jrose/bridge_projects/main/bridging.c Tue Apr 30 13:19:36 2013
@@ -478,6 +478,7 @@
default:
break;
}
+/* BUGBUG need to implement AST_BRIDGE_CHANNEL_FLAG_LONELY support here */
}
/*!
@@ -565,6 +566,7 @@
/* Add channel to the bridge */
if (bridge->dissolved
|| bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT
+ || (swap && swap->state != AST_BRIDGE_CHANNEL_STATE_WAIT)
|| bridge->v_table->push(bridge, bridge_channel, swap)
|| ast_bridge_channel_establish_roles(bridge_channel)) {
ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
@@ -3106,35 +3108,53 @@
*
* \note The two bridges are assumed already locked.
*
- * 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().
- */
-static void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, int num_kick)
+ * This moves the channels in src_bridge into the bridge pointed
+ * to by dst_bridge.
+ */
+static void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick)
{
struct ast_bridge_channel *bridge_channel;
+ unsigned int idx;
ast_debug(1, "Merging bridge %s into bridge %s\n",
src_bridge->uniqueid, dst_bridge->uniqueid);
ast_bridge_publish_merge(dst_bridge, src_bridge);
- if (kick_me) {
- unsigned int idx;
-
- for (idx = 0; idx < num_kick; ++idx) {
- ast_bridge_change_state(kick_me[idx], AST_BRIDGE_CHANNEL_STATE_HANGUP);
- bridge_channel_pull(kick_me[idx]);
- }
- }
-
- /* Move channels from src_bridge over to dst_bridge */
- while ((bridge_channel = AST_LIST_FIRST(&src_bridge->channels))) {
+ /*
+ * Move channels from src_bridge over to dst_bridge.
+ *
+ * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
+ * bridge_channel_pull() alters the list we are traversing.
+ */
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
+ if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
+ /*
+ * The channel is already leaving let it leave normally because
+ * pulling it may delete hooks that should run for this channel.
+ */
+ continue;
+ }
+ if (ast_test_flag(&bridge_channel->features->feature_flags,
+ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE)) {
+ continue;
+ }
+
+ if (kick_me) {
+ for (idx = 0; idx < num_kick; ++idx) {
+ if (bridge_channel == kick_me[idx]) {
+ ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+ }
+ }
+ }
bridge_channel_pull(bridge_channel);
+ if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
+ /*
+ * The channel died as a result of being pulled or it was
+ * kicked. Leave it pointing to the original bridge.
+ */
+ continue;
+ }
/* Point to new bridge.*/
ao2_ref(dst_bridge, +1);
@@ -3147,6 +3167,24 @@
ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
}
}
+ AST_LIST_TRAVERSE_SAFE_END;
+
+ if (kick_me) {
+ /*
+ * Now we can kick any channels in the dst_bridge without
+ * potentially dissolving the bridge.
+ */
+ for (idx = 0; idx < num_kick; ++idx) {
+ bridge_channel = kick_me[idx];
+ ast_bridge_channel_lock(bridge_channel);
+ if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
+ ast_bridge_change_state_nolock(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+ bridge_channel_pull(bridge_channel);
+ }
+ ast_bridge_channel_unlock(bridge_channel);
+ }
+ }
+
bridge_reconfigured(dst_bridge);
bridge_reconfigured(src_bridge);
@@ -3154,31 +3192,180 @@
src_bridge->uniqueid, dst_bridge->uniqueid);
}
-int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge)
-{
- int res = -1;
+struct merge_direction {
+ /*! Destination merge bridge. */
+ struct ast_bridge *dest;
+ /*! Source merge bridge. */
+ struct ast_bridge *src;
+};
+
+/*!
+ * \internal
+ * \brief Determine which bridge should merge into the other.
+ * \since 12.0.0
+ *
+ * \param bridge1 A bridge for merging
+ * \param bridge2 A bridge for merging
+ *
+ * \note The two bridges are assumed already locked.
+ *
+ * \return Which bridge merges into which or NULL bridges if cannot merge.
+ */
+static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
+{
+ struct merge_direction merge = { NULL, NULL };
+ int bridge1_priority;
+ int bridge2_priority;
+
+ if (!ast_test_flag(&bridge1->feature_flags,
+ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)
+ && !ast_test_flag(&bridge2->feature_flags,
[... 3415 lines stripped ...]
More information about the asterisk-commits
mailing list