summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES13
-rw-r--r--Makefile4
-rw-r--r--addons/res_config_mysql.c364
-rw-r--r--apps/app_dial.c56
-rw-r--r--apps/app_fax.c14
-rw-r--r--apps/app_minivm.c8
-rw-r--r--apps/app_queue.c23
-rw-r--r--apps/confbridge/conf_config_parser.c8
-rw-r--r--apps/confbridge/include/confbridge.h1
-rw-r--r--build_tools/menuselect-deps.in1
-rw-r--r--channels/chan_rtp.c2
-rw-r--r--channels/chan_sip.c7
-rw-r--r--configs/samples/calendar.conf.sample2
-rwxr-xr-xconfigure875
-rw-r--r--configure.ac61
-rw-r--r--contrib/ast-db-manage/README.md1
-rw-r--r--include/asterisk/autoconfig.h.in25
-rw-r--r--include/asterisk/calendar.h1
-rw-r--r--include/asterisk/channel.h10
-rw-r--r--include/asterisk/json.h35
-rw-r--r--include/asterisk/translate.h1
-rw-r--r--include/asterisk/vector.h14
-rw-r--r--main/aoc.c50
-rw-r--r--main/cdr.c19
-rw-r--r--main/cel.c4
-rw-r--r--main/channel.c83
-rw-r--r--main/cli.c14
-rw-r--r--main/json.c146
-rw-r--r--main/logger.c4
-rw-r--r--makeopts.in8
-rw-r--r--menuselect/aclocal.m4281
-rwxr-xr-xmenuselect/configure197
-rw-r--r--menuselect/configure.ac9
-rw-r--r--res/ari/ari_model_validators.c351
-rw-r--r--res/ari/ari_model_validators.h39
-rw-r--r--res/res_calendar.c5
-rw-r--r--res/res_fax.c19
-rw-r--r--res/res_rtp_asterisk.c17
-rw-r--r--res/stasis/app.c9
-rw-r--r--rest-api/api-docs/events.json5
-rw-r--r--tests/test_json.c34
-rw-r--r--tests/test_res_stasis.c6
-rw-r--r--third-party/Makefile.rules17
-rw-r--r--third-party/configure.m47
-rw-r--r--third-party/pjproject/Makefile51
-rwxr-xr-xthird-party/pjproject/apply_patches6
-rw-r--r--third-party/pjproject/configure.m487
-rw-r--r--third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch164
48 files changed, 2261 insertions, 897 deletions
diff --git a/CHANGES b/CHANGES
index be279879d..ea0cff9d5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -103,6 +103,19 @@ app_confbridge
instance, allows a channel to immediately exit the ConfBridge without having
to wait for a leave announcement to play.
+app_dial
+------------------
+ * Added the "Q" option which sets the Q.850/Q.931 cause on unanswered channels
+ when another channel answers the call. The default of ANSWERED_ELSEWHERE
+ is unchanged.
+
+res_ari
+------------------
+ * ARI events will all now include a new field in the root of the JSON message,
+ 'asterisk_id'. This will be the unique ID for the Asterisk system
+ transmitting the event. The value can be overridden using the 'entityid'
+ setting in asterisk.conf.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13 to Asterisk 14 --------------------
------------------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index 992e1d301..8e237e1fd 100644
--- a/Makefile
+++ b/Makefile
@@ -99,6 +99,10 @@ export WGET_EXTRA_ARGS
export LDCONFIG
export LDCONFIG_FLAGS
export PYTHON
+export TAR
+export PATCH
+export SED
+export NM
# makeopts is required unless the goal is clean or distclean
ifeq ($(findstring clean,$(MAKECMDGOALS)),)
diff --git a/addons/res_config_mysql.c b/addons/res_config_mysql.c
index c9fa7c744..e6b0e53c0 100644
--- a/addons/res_config_mysql.c
+++ b/addons/res_config_mysql.c
@@ -126,7 +126,6 @@ static char *handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd,
static char *handle_cli_realtime_mysql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn);
static int require_mysql(const char *database, const char *tablename, va_list ap);
-static int internal_require(const char *database, const char *table, ...) attribute_sentinel;
static struct ast_cli_entry cli_realtime_mysql_status[] = {
AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"),
@@ -165,16 +164,6 @@ static struct mysql_conn *find_database(const char *database, int for_write)
#define release_database(a) ast_mutex_unlock(&(a)->lock)
-static int internal_require(const char *database, const char *table, ...)
-{
- va_list ap;
- int res;
- va_start(ap, table);
- res = require_mysql(database, table, ap);
- va_end(ap);
- return res;
-}
-
static void destroy_table(struct tables *table)
{
struct columns *column;
@@ -600,11 +589,6 @@ static int update_mysql(const char *database, const char *tablename, const char
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, 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, field->name))) {
@@ -614,11 +598,6 @@ static int update_mysql(const char *database, const char *tablename, const char
ESCAPE_STRING(buf, field->value);
ast_str_append(&sql, 0, ", `%s` = '%s'", 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, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
}
ESCAPE_STRING(buf, lookup);
@@ -703,11 +682,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
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, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
}
first = 1;
@@ -721,11 +695,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
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, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
- }
}
release_table(table);
@@ -759,7 +728,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
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);
@@ -792,15 +760,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
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, 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));
- }
+ ast_str_append(&sql, 0, ", `%s`", field->name);
+ ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
}
ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2));
ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql));
@@ -812,18 +776,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
return -1;
}
- /*!\note The return value is non-portable and may change in future versions. */
- insertid = mysql_insert_id(&dbh->handle);
release_database(dbh);
- ast_debug(1, "MySQL RealTime: row inserted on table: %s, id: %llu\n", table, insertid);
+ ast_debug(1, "MySQL RealTime: row inserted on table: %s\n", table);
- /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html
- * An integer greater than zero indicates the number of rows affected
- * Zero indicates that no records were updated
- * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
- */
- return (int)insertid;
+ return 1;
}
static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
@@ -989,105 +946,14 @@ static int unload_mysql(const char *database, const char *tablename)
return cur ? 0 : -1;
}
-static int modify_mysql(const char *database, const char *tablename, struct columns *column, require_type type, int len)
-{
- /*!\note Cannot use ANY of the same scratch space as is used in other functions, as this one is interspersed. */
- struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *escbuf = ast_str_thread_get(&modify2_buf, 100);
- struct ast_str *typestr = ast_str_thread_get(&modify3_buf, 30);
- int waschar = strncasecmp(column->type, "char", 4) == 0 ? 1 : 0;
- int wasvarchar = strncasecmp(column->type, "varchar", 7) == 0 ? 1 : 0;
- int res = 0;
- struct mysql_conn *dbh;
-
- if (!(dbh = find_database(database, 1))) {
- return -1;
- }
-
- do {
- if (type == RQ_CHAR || waschar || wasvarchar) {
- if (wasvarchar) {
- ast_str_set(&typestr, 0, "VARCHAR(%d)", len);
- } else {
- ast_str_set(&typestr, 0, "CHAR(%d)", len);
- }
- } else if (type == RQ_UINTEGER1) {
- ast_str_set(&typestr, 0, "tinyint(3) unsigned");
- } else if (type == RQ_INTEGER1) {
- ast_str_set(&typestr, 0, "tinyint(4)");
- } else if (type == RQ_UINTEGER2) {
- ast_str_set(&typestr, 0, "smallint(5) unsigned");
- } else if (type == RQ_INTEGER2) {
- ast_str_set(&typestr, 0, "smallint(6)");
- } else if (type == RQ_UINTEGER3) {
- ast_str_set(&typestr, 0, "mediumint(8) unsigned");
- } else if (type == RQ_INTEGER3) {
- ast_str_set(&typestr, 0, "mediumint(8)");
- } else if (type == RQ_UINTEGER4) {
- ast_str_set(&typestr, 0, "int(10) unsigned");
- } else if (type == RQ_INTEGER4) {
- ast_str_set(&typestr, 0, "int(11)");
- } else if (type == RQ_UINTEGER8) {
- ast_str_set(&typestr, 0, "bigint(19) unsigned");
- } else if (type == RQ_INTEGER8) {
- ast_str_set(&typestr, 0, "bigint(20)");
- } else if (type == RQ_DATETIME) {
- ast_str_set(&typestr, 0, "datetime");
- } else if (type == RQ_DATE) {
- ast_str_set(&typestr, 0, "date");
- } else if (type == RQ_FLOAT) {
- ast_str_set(&typestr, 0, "FLOAT(%d,2)", len);
- } else {
- ast_log(LOG_ERROR, "Unknown type (should NEVER happen)\n");
- res = -1;
- break;
- }
- ast_str_set(&sql, 0, "ALTER TABLE %s MODIFY `%s` %s", tablename, column->name, ast_str_buffer(typestr));
- if (!column->null) {
- ast_str_append(&sql, 0, " NOT NULL");
- }
- if (!ast_strlen_zero(column->dflt)) {
- ESCAPE_STRING(escbuf, column->dflt);
- ast_str_append(&sql, 0, " DEFAULT '%s'", ast_str_buffer(escbuf));
- }
-
- if (!mysql_reconnect(dbh)) {
- ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
- res = -1;
- break;
- }
-
- /* Execution. */
- if (mysql_real_query(&dbh->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
- ast_log(LOG_WARNING, "MySQL RealTime: Failed to modify database: %s\n", mysql_error(&dbh->handle));
- ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
- res = -1;
- }
- } while (0);
-
- release_database(dbh);
- return res;
-}
-
-#define PICK_WHICH_ALTER_ACTION(stringtype) \
- if (table->database->requirements == RQ_WARN) { \
- ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
- "the required data length: %d (detected stringtype)\n", \
- tablename, database, column->name, size); \
- res = -1; \
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { \
- table_altered = 1; \
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { \
- table_altered = 1; \
- } else { \
- res = -1; \
- }
-
static int require_mysql(const char *database, const char *tablename, va_list ap)
{
struct columns *column;
struct tables *table = find_table(database, tablename);
char *elm;
- int type, size, res = 0, table_altered = 0;
+ int type;
+ int size;
+ int res = 0;
if (!table) {
ast_log(LOG_WARNING, "Table %s not found in database. This table should exist if you're using realtime.\n", tablename);
@@ -1097,55 +963,54 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
while ((elm = va_arg(ap, char *))) {
type = va_arg(ap, require_type);
size = va_arg(ap, int);
+
AST_LIST_TRAVERSE(&table->columns, column, list) {
if (strcmp(column->name, elm) == 0) {
/* Char can hold anything, as long as it is large enough */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
if ((size > column->len) && column->len != -1) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len);
- res = -1;
- } else if (modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", database, tablename, column->name, size, column->len);
+ res = -1;
}
} else if (strcasestr(column->type, "unsigned")) {
if (!ast_rq_is_int(type)) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
- database, tablename, column->name, column->type,
- type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
- type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
+ database, tablename, column->name, column->type,
+ type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
+ type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
+ res = -1;
} else if (strncasecmp(column->type, "tinyint", 1) == 0) {
if (type != RQ_UINTEGER1) {
- PICK_WHICH_ALTER_ACTION(unsigned tinyint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "smallint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) {
- PICK_WHICH_ALTER_ACTION(unsigned smallint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "mediumint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3) {
- PICK_WHICH_ALTER_ACTION(unsigned mediumint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "int", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4) {
- PICK_WHICH_ALTER_ACTION(unsigned int)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "bigint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
@@ -1153,45 +1018,52 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
type != RQ_UINTEGER8) {
- PICK_WHICH_ALTER_ACTION(unsigned bigint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
}
} else if (strcasestr(column->type, "int")) {
if (!ast_rq_is_int(type)) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
- database, tablename, column->name, column->type,
- type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
- type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
- "to get a life, rather than writing silly error messages");
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
+ database, tablename, column->name, column->type,
+ type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
+ type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
+ "to get a life, rather than writing silly error messages");
+ res = -1;
} else if (strncasecmp(column->type, "tinyint", 1) == 0) {
if (type != RQ_INTEGER1) {
- PICK_WHICH_ALTER_ACTION(tinyint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "smallint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) {
- PICK_WHICH_ALTER_ACTION(smallint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "mediumint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_INTEGER3) {
- PICK_WHICH_ALTER_ACTION(mediumint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "int", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_INTEGER4) {
- PICK_WHICH_ALTER_ACTION(int)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
} else if (strncasecmp(column->type, "bigint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
@@ -1199,137 +1071,41 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
type != RQ_INTEGER8) {
- PICK_WHICH_ALTER_ACTION(bigint)
+ ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
+ "the required data length: %d (detected stringtype)\n", \
+ tablename, database, column->name, size); \
+ res = -1; \
}
}
} else if (strncmp(column->type, "float", 5) == 0) {
if (!ast_rq_is_int(type) && type != RQ_FLOAT) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
+ res = -1;
}
} else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) {
if (type != RQ_DATETIME) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
+ res = -1;
}
} else if (strncmp(column->type, "date", 4) == 0) {
if (type != RQ_DATE) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
- res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
- res = -1;
- }
- }
- } else { /* Other, possibly unsupported types? */
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
+ ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
res = -1;
- } else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
- table_altered = 1;
- } else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
- table_altered = 1;
- } else {
}
+ } else { /* Other, possibly unsupported types? */
+ ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
+ res = -1;
}
break;
}
}
if (!column) {
- if (table->database->requirements == RQ_WARN) {
- ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
- } else {
- struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *fieldtype = ast_str_thread_get(&modify3_buf, 16);
-
- if (table->database->requirements == RQ_CREATECHAR || type == RQ_CHAR) {
- ast_str_set(&fieldtype, 0, "CHAR(%d)", size);
- } else if (type == RQ_UINTEGER1 || type == RQ_UINTEGER2 || type == RQ_UINTEGER3 || type == RQ_UINTEGER4 || type == RQ_UINTEGER8) {
- if (type == RQ_UINTEGER1) {
- ast_str_set(&fieldtype, 0, "TINYINT(3) UNSIGNED");
- } else if (type == RQ_UINTEGER2) {
- ast_str_set(&fieldtype, 0, "SMALLINT(5) UNSIGNED");
- } else if (type == RQ_UINTEGER3) {
- ast_str_set(&fieldtype, 0, "MEDIUMINT(8) UNSIGNED");
- } else if (type == RQ_UINTEGER4) {
- ast_str_set(&fieldtype, 0, "INT(10) UNSIGNED");
- } else if (type == RQ_UINTEGER8) {
- ast_str_set(&fieldtype, 0, "BIGINT(20) UNSIGNED");
- } else {
- ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to squash Tokyo.\n");
- continue;
- }
- } else if (ast_rq_is_int(type)) {
- if (type == RQ_INTEGER1) {
- ast_str_set(&fieldtype, 0, "TINYINT(3)");
- } else if (type == RQ_INTEGER2) {
- ast_str_set(&fieldtype, 0, "SMALLINT(5)");
- } else if (type == RQ_INTEGER3) {
- ast_str_set(&fieldtype, 0, "MEDIUMINT(8)");
- } else if (type == RQ_INTEGER4) {
- ast_str_set(&fieldtype, 0, "INT(10)");
- } else if (type == RQ_INTEGER8) {
- ast_str_set(&fieldtype, 0, "BIGINT(20)");
- } else {
- ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to eat Cincinnati.\n");
- continue;
- }
- } else if (type == RQ_FLOAT) {
- ast_str_set(&fieldtype, 0, "FLOAT");
- } else if (type == RQ_DATE) {
- ast_str_set(&fieldtype, 0, "DATE");
- } else if (type == RQ_DATETIME) {
- ast_str_set(&fieldtype, 0, "DATETIME");
- } else {
- continue;
- }
- ast_str_set(&sql, 0, "ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, ast_str_buffer(fieldtype));
-
- ast_mutex_lock(&table->database->lock);
- if (!mysql_reconnect(table->database)) {
- ast_mutex_unlock(&table->database->lock);
- ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
- continue;
- }
-
- /* Execution. */
- if (mysql_real_query(&table->database->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
- ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
- ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
- ast_debug(1, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&table->database->handle));
- } else {
- table_altered = 1;
- }
- }
+ ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
}
}
release_table(table);
- /* If we altered the table, we must refresh the cache */
- if (table_altered) {
- unload_mysql(database, tablename);
- release_table(find_table(database, tablename));
- }
return res;
}
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 316d38da1..b5d8f50c7 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -375,6 +375,25 @@ ASTERISK_REGISTER_FILE()
<para>Enable privacy mode. Use <replaceable>x</replaceable> as the family/key in the AstDB database if
it is provided. The current extension is used if a database family/key is not specified.</para>
</option>
+ <option name="Q">
+ <argument name="cause" required="true"/>
+ <para>Specify the Q.850/Q.931 <replaceable>cause</replaceable> to send on
+ unanswered channels when another channel answers the call.
+ As with <literal>Hangup()</literal>, <replaceable>cause</replaceable>
+ can be a numeric cause code or a name such as
+ <literal>NO_ANSWER</literal>,
+ <literal>USER_BUSY</literal>,
+ <literal>CALL_REJECTED</literal> or
+ <literal>ANSWERED_ELSEWHERE</literal> (the default if Q isn't specified).
+ You can also specify <literal>0</literal> or <literal>NONE</literal>
+ to send no cause. See the <filename>causes.h</filename> file for the
+ full list of valid causes and names.
+ </para>
+ <note>
+ <para>chan_sip does not support setting the cause on a CANCEL to anything
+ other than ANSWERED_ELSEWHERE.</para>
+ </note>
+ </option>
<option name="r">
<para>Default: Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
party until the called channel has answered.</para>
@@ -520,6 +539,9 @@ ASTERISK_REGISTER_FILE()
<example title="Dial with call length limit">
same => n,Dial(PJSIP/alice,,L(60000:30000:10000))
</example>
+ <example title="Dial alice and bob and send NO_ANSWER to bob instead of ANSWERED_ELSEWHERE when alice answers">
+ same => n,Dial(PJSIP/alice&amp;PJSIP/bob,,Q(NO_ANSWER))
+ </example>
<example title="Dial with pre-dial subroutines">
[default]
@@ -684,6 +706,7 @@ enum {
#define OPT_PREDIAL_CALLEE (1LLU << 41)
#define OPT_PREDIAL_CALLER (1LLU << 42)
#define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
+#define OPT_HANGUPCAUSE (1LLU << 44)
enum {
OPT_ARG_ANNOUNCE = 0,
@@ -705,6 +728,7 @@ enum {
OPT_ARG_FORCE_CID_PRES,
OPT_ARG_PREDIAL_CALLEE,
OPT_ARG_PREDIAL_CALLER,
+ OPT_ARG_HANGUPCAUSE,
/* note: this entry _MUST_ be the last one in the enum */
OPT_ARG_ARRAY_SIZE
};
@@ -738,6 +762,7 @@ AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
AST_APP_OPTION('p', OPT_SCREENING),
AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
+ AST_APP_OPTION_ARG('Q', OPT_HANGUPCAUSE, OPT_ARG_HANGUPCAUSE),
AST_APP_OPTION_ARG('r', OPT_RINGBACK, OPT_ARG_RINGBACK),
AST_APP_OPTION('R', OPT_RING_WITH_EARLY_MEDIA),
AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
@@ -796,7 +821,7 @@ static void chanlist_free(struct chanlist *outgoing)
ast_free(outgoing);
}
-static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int answered_elsewhere)
+static void hanguptree(struct dial_head *out_chans, struct ast_channel *exception, int hangupcause)
{
/* Hang up a tree of stuff */
struct chanlist *outgoing;
@@ -804,9 +829,9 @@ static void hanguptree(struct dial_head *out_chans, struct ast_channel *exceptio
while ((outgoing = AST_LIST_REMOVE_HEAD(out_chans, node))) {
/* Hangup any existing lines we have open */
if (outgoing->chan && (outgoing->chan != exception)) {
- if (answered_elsewhere) {
+ if (hangupcause >= 0) {
/* This is for the channel drivers */
- ast_channel_hangupcause_set(outgoing->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
+ ast_channel_hangupcause_set(outgoing->chan, hangupcause);
}
ast_hangup(outgoing->chan);
}
@@ -2768,6 +2793,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
} else {
const char *number;
int dial_end_raised = 0;
+ int cause = -1;
if (ast_test_flag64(&opts, OPT_CALLER_ANSWER))
ast_answer(chan);
@@ -2778,7 +2804,23 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
/* Ah ha! Someone answered within the desired timeframe. Of course after this
we will always return with -1 so that it is hung up properly after the
conversation. */
- hanguptree(&out_chans, peer, 1);
+
+ if (ast_test_flag64(&opts, OPT_HANGUPCAUSE)
+ && !ast_strlen_zero(opt_args[OPT_ARG_HANGUPCAUSE])) {
+ cause = ast_str2cause(opt_args[OPT_ARG_HANGUPCAUSE]);
+ if (cause <= 0) {
+ if (!strcasecmp(opt_args[OPT_ARG_HANGUPCAUSE], "NONE")) {
+ cause = 0;
+ } else if (sscanf(opt_args[OPT_ARG_HANGUPCAUSE], "%30d", &cause) != 1
+ || cause < 0) {
+ ast_log(LOG_WARNING, "Invalid cause given to Dial(...Q(<cause>)): \"%s\"\n",
+ opt_args[OPT_ARG_HANGUPCAUSE]);
+ cause = -1;
+ }
+ }
+ }
+ hanguptree(&out_chans, peer, cause >= 0 ? cause : AST_CAUSE_ANSWERED_ELSEWHERE);
+
/* If appropriate, log that we have a destination channel and set the answer time */
if (ast_channel_name(peer))
pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", ast_channel_name(peer));
@@ -3182,7 +3224,11 @@ out:
}
ast_channel_early_bridge(chan, NULL);
- hanguptree(&out_chans, NULL, ast_channel_hangupcause(chan)==AST_CAUSE_ANSWERED_ELSEWHERE || ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0 ); /* forward 'answered elsewhere' if we received it */
+ /* forward 'answered elsewhere' if we received it */
+ hanguptree(&out_chans, NULL,
+ ast_channel_hangupcause(chan) == AST_CAUSE_ANSWERED_ELSEWHERE
+ || ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE)
+ ? AST_CAUSE_ANSWERED_ELSEWHERE : -1);
pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
diff --git a/apps/app_fax.c b/apps/app_fax.c
index bf57d827d..6e174d4a7 100644
--- a/apps/app_fax.c
+++ b/apps/app_fax.c
@@ -262,13 +262,13 @@ static void phase_e_handler(t30_state_t *f, void *user_data, int result)
}
ast_json_ref(json_filenames);
json_object = ast_json_pack("{s: s, s: s, s: s, s: i, s: i, s: i, s: o}",
- "type", s->direction ? "send" : "receive",
- "remote_station_id", far_ident,
- "local_station_id", local_ident,
- "fax_pages", pages_transferred,
- "fax_resolution", stat.y_resolution,
- "fax_bitrate", stat.bit_rate,
- "filenames", json_filenames);
+ "type", s->direction ? "send" : "receive",
+ "remote_station_id", AST_JSON_UTF8_VALIDATE(far_ident),
+ "local_station_id", AST_JSON_UTF8_VALIDATE(local_ident),
+ "fax_pages", pages_transferred,
+ "fax_resolution", stat.y_resolution,
+ "fax_bitrate", stat.bit_rate,
+ "filenames", json_filenames);
message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(s->chan), ast_channel_fax_type(), json_object);
if (!message) {
return;
diff --git a/apps/app_minivm.c b/apps/app_minivm.c
index e97150b13..c84b7d7dd 100644
--- a/apps/app_minivm.c
+++ b/apps/app_minivm.c
@@ -1853,10 +1853,10 @@ static int notify_new_message(struct ast_channel *chan, const char *templatename
}
mwi_state->snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
- json_object = ast_json_pack("{s: s, s: s}",
- "Event", "MiniVoiceMail"
- "Action", "SentNotification",
- "Counter", counter);
+ json_object = ast_json_pack("{s: s, s: s, s: s}",
+ "Event", "MiniVoiceMail",
+ "Action", "SentNotification",
+ "Counter", counter ?: "");
if (!json_object) {
goto notify_cleanup;
}
diff --git a/apps/app_queue.c b/apps/app_queue.c
index a023b88ed..51741d374 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -2671,6 +2671,9 @@ static void init_queue(struct call_queue *q)
q->retry = DEFAULT_RETRY;
q->timeout = DEFAULT_TIMEOUT;
q->maxlen = 0;
+
+ ast_string_field_set(q, context, "");
+
q->announcefrequency = 0;
q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
q->announceholdtime = 1;
@@ -5645,12 +5648,12 @@ static void send_agent_complete(const char *queuename, struct ast_channel_snapsh
}
blob = ast_json_pack("{s: s, s: s, s: s, s: i, s: i, s: s}",
- "Queue", queuename,
- "Interface", member->interface,
- "MemberName", member->membername,
- "HoldTime", (long)(callstart - holdstart),
- "TalkTime", (long)(time(NULL) - callstart),
- "Reason", reason);
+ "Queue", queuename,
+ "Interface", member->interface,
+ "MemberName", member->membername,
+ "HoldTime", (long)(callstart - holdstart),
+ "TalkTime", (long)(time(NULL) - callstart),
+ "Reason", reason ?: "");
queue_publish_multi_channel_snapshot_blob(ast_queue_topic(queuename), caller, peer,
queue_agent_complete_type(), blob);
@@ -7232,12 +7235,12 @@ static void set_queue_member_pause(struct call_queue *q, struct member *mem, con
mem->paused = paused;
if (paused) {
- if (!ast_strlen_zero(reason)) {
- ast_copy_string(mem->reason_paused, reason, sizeof(mem->reason_paused));
- }
time(&mem->lastpause); /* update last pause field */
+ }
+ if (paused && !ast_strlen_zero(reason)) {
+ ast_copy_string(mem->reason_paused, reason, sizeof(mem->reason_paused));
} else {
- ast_copy_string(mem->reason_paused, "", sizeof(mem->reason_paused));
+ mem->reason_paused[0] = '\0';
}
ast_devstate_changed(mem->paused ? QUEUE_PAUSED_DEVSTATE : QUEUE_UNPAUSED_DEVSTATE,
diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c
index 69d6f69ea..6f8510552 100644
--- a/apps/confbridge/conf_config_parser.c
+++ b/apps/confbridge/conf_config_parser.c
@@ -284,6 +284,13 @@ ASTERISK_REGISTER_FILE()
or 80.
</para></description>
</configOption>
+ <configOption name="binaural_active">
+ <synopsis>If true binaural conferencing with stereo audio is active</synopsis>
+ <description><para>
+ Activates binaural mixing for a conference bridge.
+ Binaural features are disabled by default.
+ </para></description>
+ </configOption>
<configOption name="record_conference">
<synopsis>Record the conference starting with the first active user's entrance and ending with the last active user's exit</synopsis>
<description><para>
@@ -2172,6 +2179,7 @@ int conf_load_config(void)
aco_option_register(&cfg_info, "jitterbuffer", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), USER_OPT_JITTERBUFFER);
/* "auto" will fail to parse as a uint, but we use PARSE_DEFAULT to set the value to 0 in that case, which is the value that auto resolves to */
aco_option_register(&cfg_info, "internal_sample_rate", ACO_EXACT, bridge_types, "0", OPT_UINT_T, PARSE_DEFAULT, FLDSET(struct bridge_profile, internal_sample_rate), 0);
+ aco_option_register(&cfg_info, "binaural_active", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_BINAURAL_ACTIVE);
aco_option_register_custom(&cfg_info, "mixing_interval", ACO_EXACT, bridge_types, "20", mix_interval_handler, 0);
aco_option_register(&cfg_info, "record_conference", ACO_EXACT, bridge_types, "no", OPT_BOOLFLAG_T, 1, FLDSET(struct bridge_profile, flags), BRIDGE_OPT_RECORD_CONFERENCE);
aco_option_register_custom(&cfg_info, "video_mode", ACO_EXACT, bridge_types, NULL, video_mode_handler, 0);
diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h
index 93cac3a72..f91f2dc89 100644
--- a/apps/confbridge/include/confbridge.h
+++ b/apps/confbridge/include/confbridge.h
@@ -71,6 +71,7 @@ enum bridge_profile_flags {
BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER = (1 << 3), /*!< Set if conference set the video feed to follow the loudest talker. */
BRIDGE_OPT_RECORD_FILE_APPEND = (1 << 4), /*!< Set if the record file should be appended to between start/stops. */
BRIDGE_OPT_RECORD_FILE_TIMESTAMP = (1 << 5), /*< Set if the record file should have a timestamp appended */
+ BRIDGE_OPT_BINAURAL_ACTIVE = (1 << 6), /*< Set if binaural convolution is activated */
};
enum conf_menu_action_id {
diff --git a/build_tools/menuselect-deps.in b/build_tools/menuselect-deps.in
index 9b077680e..9f1aa7082 100644
--- a/build_tools/menuselect-deps.in
+++ b/build_tools/menuselect-deps.in
@@ -54,6 +54,7 @@ PORTAUDIO=@PBX_PORTAUDIO@
PRI=@PBX_PRI@
OPENR2=@PBX_OPENR2@
RESAMPLE=@PBX_RESAMPLE@
+FFTW3=@PBX_FFTW3@
RADIUS=@PBX_RADIUS@
LAUNCHD=@PBX_LAUNCHD@
SPANDSP=@PBX_SPANDSP@
diff --git a/channels/chan_rtp.c b/channels/chan_rtp.c
index 0fe66bd20..f1f4f05b9 100644
--- a/channels/chan_rtp.c
+++ b/channels/chan_rtp.c
@@ -314,7 +314,7 @@ static struct ast_channel *unicast_rtp_request(const char *type, struct ast_form
}
engine_name = S_COR(ast_test_flag(&opts, OPT_RTP_ENGINE),
- opt_args[OPT_ARG_RTP_ENGINE], NULL);
+ opt_args[OPT_ARG_RTP_ENGINE], "asterisk");
ast_ouraddrfor(&address, &local_address);
instance = ast_rtp_instance_new(engine_name, NULL, &local_address, NULL);
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index d8a3d5c7a..40ef6409a 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -8153,12 +8153,17 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
We also check for vrtp. If it's not there, we are not allowed do any video anyway.
*/
if (i->vrtp) {
- if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
+ if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS))
needvideo = 1;
else if (ast_format_cap_count(i->prefcaps))
needvideo = ast_format_cap_has_type(i->prefcaps, AST_MEDIA_TYPE_VIDEO); /* Outbound call */
else
needvideo = ast_format_cap_has_type(i->jointcaps, AST_MEDIA_TYPE_VIDEO); /* Inbound call */
+
+ if (!needvideo) {
+ ast_rtp_instance_destroy(i->vrtp);
+ i->vrtp = NULL;
+ }
}
if (i->trtp) {
diff --git a/configs/samples/calendar.conf.sample b/configs/samples/calendar.conf.sample
index 82b8702f0..d87b3b2c4 100644
--- a/configs/samples/calendar.conf.sample
+++ b/configs/samples/calendar.conf.sample
@@ -6,6 +6,8 @@
;refresh = 15 ; refresh calendar every n minutes
;timeframe = 60 ; number of minutes of calendar data to pull for each refresh period
; ; should always be >= refresh
+;fetch_again_at_reload = no ; to reload the calendar content when the module is reloaded
+;
;
; You can set up res_calendar to execute a call upon an upcoming busy status
; The following fields are available from the ${CALENDAR_EVENT(<field>)} dialplan function:
diff --git a/configure b/configure
index a5da739c0..1c7526f4d 100755
--- a/configure
+++ b/configure
@@ -827,8 +827,6 @@ PBX_SPANDSP
SPANDSP_DIR
SPANDSP_INCLUDE
SPANDSP_LIB
-EXTERNALS_CACHE_DIR
-SOUNDS_CACHE_DIR
PBX_SDL_IMAGE
SDL_IMAGE_DIR
SDL_IMAGE_INCLUDE
@@ -841,6 +839,10 @@ PBX_RESAMPLE
RESAMPLE_DIR
RESAMPLE_INCLUDE
RESAMPLE_LIB
+PBX_FFTW3
+FFTW3_DIR
+FFTW3_INCLUDE
+FFTW3_LIB
PBX_RADIUS
RADIUS_DIR
RADIUS_INCLUDE
@@ -977,11 +979,6 @@ PBX_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_DIR
PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_INCLUDE
PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_LIB
-PJPROJECT_BUNDLED
-PBX_PJPROJECT
-PJPROJECT_DIR
-PJPROJECT_INCLUDE
-PJPROJECT_LIB
PBX_PGSQL
PGSQL_DIR
PGSQL_INCLUDE
@@ -1198,11 +1195,18 @@ PBX_ALSA
ALSA_DIR
ALSA_INCLUDE
ALSA_LIB
+PJPROJECT_INCLUDE
+PJPROJECT_LIB
+PBX_PJPROJECT
+PJPROJECT_DIR
+PJPROJECT_BUNDLED
AST_C_COMPILER_FAMILY
AST_CLANG_BLOCKS
AST_CLANG_BLOCKS_LIBS
AST_NESTED_FUNCTIONS
AST_CODE_COVERAGE
+EXTERNALS_CACHE_DIR
+SOUNDS_CACHE_DIR
AST_DEVMODE_STRICT
AST_DEVMODE
NOISY_BUILD
@@ -1219,8 +1223,13 @@ PBX_BISON
OPENSSL
SHA1SUM
LDCONFIG
+DOWNLOAD_TO_STDOUT
DOWNLOAD
FETCH
+NM
+PATCH
+TAR
+BZIP2
ALEMBIC
GIT
BASH
@@ -1350,7 +1359,10 @@ ac_user_opts='
enable_option_checking
with_gnu_ld
enable_dev_mode
+with_sounds_cache
+with_externals_cache
enable_coverage
+with_pjproject_bundled
with_asound
with_bfd
with_execinfo
@@ -1402,17 +1414,15 @@ with_osptk
with_oss
with_postgres
with_pjproject
-with_pjproject_bundled
with_popt
with_portaudio
with_pri
with_pwlib
with_radius
+with_fftw3
with_resample
with_sdl
with_SDL_image
-with_sounds_cache
-with_externals_cache
with_spandsp
with_ss7
with_speex
@@ -2105,6 +2115,12 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sounds-cache=PATH
+ use cached sound tarfiles in PATH
+ --with-externals-cache=PATH
+ use cached external module tarfiles in PATH
+ --with-pjproject-bundled
+ Use bundled pjproject libraries
--with-asound=PATH use Advanced Linux Sound Architecture files in PATH
--with-bfd=PATH use Debug symbol decoding files in PATH
--with-execinfo=PATH use Stack Backtrace files in PATH
@@ -2160,20 +2176,15 @@ Optional Packages:
--with-oss=PATH use Open Sound System files in PATH
--with-postgres=PATH use PostgreSQL files in PATH
--with-pjproject=PATH use PJPROJECT files in PATH
- --with-pjproject-bundled
- Use bundled pjproject libraries
--with-popt=PATH use popt files in PATH
--with-portaudio=PATH use PortAudio files in PATH
--with-pri=PATH use ISDN PRI files in PATH
--with-pwlib=PATH use PWlib files in PATH
--with-radius=PATH use Radius Client files in PATH
+ --with-fftw3=PATH use LIBFFTW3 files in PATH
--with-resample=PATH use LIBRESAMPLE files in PATH
--with-sdl=PATH use Sdl files in PATH
--with-SDL_image=PATH use Sdl Image files in PATH
- --with-sounds-cache=PATH
- use cached sound tarfiles in PATH
- --with-externals-cache=PATH
- use cached external module tarfiles in PATH
--with-spandsp=PATH use SPANDSP files in PATH
--with-ss7=PATH use ISDN SS7 files in PATH
--with-speex=PATH use Speex files in PATH
@@ -7646,10 +7657,218 @@ $as_echo "no" >&6; }
fi
+# Extract the first word of "bzip2", so it can be a program name with args.
+set dummy bzip2; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_BZIP2+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $BZIP2 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_BZIP2="$BZIP2" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_BZIP2="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_BZIP2" && ac_cv_path_BZIP2=":"
+ ;;
+esac
+fi
+BZIP2=$ac_cv_path_BZIP2
+if test -n "$BZIP2"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BZIP2" >&5
+$as_echo "$BZIP2" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "tar", so it can be a program name with args.
+set dummy tar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_TAR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $TAR in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_TAR="$TAR" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_TAR" && ac_cv_path_TAR=":"
+ ;;
+esac
+fi
+TAR=$ac_cv_path_TAR
+if test -n "$TAR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TAR" >&5
+$as_echo "$TAR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "patch", so it can be a program name with args.
+set dummy patch; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PATCH+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PATCH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PATCH="$PATCH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PATCH="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PATCH" && ac_cv_path_PATCH=":"
+ ;;
+esac
+fi
+PATCH=$ac_cv_path_PATCH
+if test -n "$PATCH"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATCH" >&5
+$as_echo "$PATCH" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "sed", so it can be a program name with args.
+set dummy sed; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $SED in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SED="$SED" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_SED" && ac_cv_path_SED=":"
+ ;;
+esac
+fi
+SED=$ac_cv_path_SED
+if test -n "$SED"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5
+$as_echo "$SED" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "nm", so it can be a program name with args.
+set dummy nm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $NM in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_NM="$NM" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_NM="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=":"
+ ;;
+esac
+fi
+NM=$ac_cv_path_NM
+if test -n "$NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
+$as_echo "$NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
if test "${WGET}" != ":" ; then
DOWNLOAD=${WGET}
+ DOWNLOAD_TO_STDOUT="${WGET} -O-"
else if test "${CURL}" != ":" ; then
DOWNLOAD="${CURL} -O --progress-bar -w \"%{url_effective}\n\""
+ DOWNLOAD_TO_STDOUT="${CURL} -L --progress-bar -w \"%{url_effective}\n\""
else
# Extract the first word of "fetch", so it can be a program name with args.
set dummy fetch; ac_word=$2
@@ -7693,9 +7912,12 @@ fi
DOWNLOAD=${FETCH}
+ DOWNLOAD_TO_STDOUT="${FETCH} -o-"
fi
fi
+
+
# Extract the first word of "ldconfig", so it can be a program name with args.
set dummy ldconfig; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -8769,6 +8991,55 @@ fi
+
+
+# Check whether --with-sounds-cache was given.
+if test "${with_sounds_cache+set}" = set; then :
+ withval=$with_sounds_cache;
+ case ${withval} in
+ n|no)
+ unset SOUNDS_CACHE_DIR
+ ;;
+ *)
+ if test "x${withval}" = "x"; then
+ :
+ else
+ SOUNDS_CACHE_DIR="${withval}"
+ fi
+ ;;
+ esac
+
+else
+ :
+fi
+
+
+
+
+
+# Check whether --with-externals-cache was given.
+if test "${with_externals_cache+set}" = set; then :
+ withval=$with_externals_cache;
+ case ${withval} in
+ n|no)
+ unset EXTERNALS_CACHE_DIR
+ ;;
+ *)
+ if test "x${withval}" = "x"; then
+ :
+ else
+ EXTERNALS_CACHE_DIR="${withval}"
+ fi
+ ;;
+ esac
+
+else
+ :
+fi
+
+
+
+
AST_CODE_COVERAGE=no
# Check whether --enable-coverage was given.
if test "${enable_coverage+set}" = set; then :
@@ -8921,6 +9192,118 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$save_CFLAGS"
+PJPROJECT_BUNDLED=no
+
+
+
+# Check whether --with-pjproject-bundled was given.
+if test "${with_pjproject_bundled+set}" = set; then :
+ withval=$with_pjproject_bundled; case "${enableval}" in
+ n|no) PJPROJECT_BUNDLED=no ;;
+ *) PJPROJECT_BUNDLED=yes ;;
+ esac
+fi
+
+
+
+
+ if test "$PJPROJECT_BUNDLED" = "yes" ; then
+
+ if test "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then
+ as_fn_error $? "--with-pjproject and --with-pjproject-bundled can't both be specified" "$LINENO" 5
+ fi
+
+ ac_mandatory_list="$ac_mandatory_list PJPROJECT"
+ PJPROJECT_DIR="${ac_top_build_prefix}third-party/pjproject"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded pjproject (may have to download)" >&5
+$as_echo_n "checking for embedded pjproject (may have to download)... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring" >&5
+$as_echo "configuring" >&6; }
+
+ if test "x${DOWNLOAD_TO_STDOUT}" = "x" ; then
+ as_fn_error $? "A download utility (wget, curl or fetch) is required to download bundled pjproject" "$LINENO" 5
+ fi
+ if test "${BZIP2}" = ":" ; then
+ as_fn_error $? "bzip2 is required to extract the pjproject tar file" "$LINENO" 5
+ fi
+ if test "${TAR}" = ":" ; then
+ as_fn_error $? "tar is required to extract the pjproject tar file" "$LINENO" 5
+ fi
+ if test "${PATCH}" = ":" ; then
+ as_fn_error $? "patch is required to configure bundled pjproject" "$LINENO" 5
+ fi
+ if test "${SED}" = ":" ; then
+ as_fn_error $? "sed is required to configure bundled pjproject" "$LINENO" 5
+ fi
+ if test "${NM}" = ":" ; then
+ as_fn_error $? "nm is required to build bundled pjproject" "$LINENO" 5
+ fi
+
+ export TAR PATCH SED NM EXTERNALS_CACHE_DIR DOWNLOAD_TO_STDOUT
+ ${GNU_MAKE} --quiet --no-print-directory -C ${PJPROJECT_DIR} configure
+ if test $? -ne 0 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Unable to configure ${PJPROJECT_DIR}" >&5
+$as_echo "$as_me: Unable to configure ${PJPROJECT_DIR}" >&6;}
+ as_fn_error $? "Run \"${GNU_MAKE} -C ${PJPROJECT_DIR} NOISY_BUILD=yes configure\" to see error details." "$LINENO" 5
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bundled pjproject" >&5
+$as_echo_n "checking for bundled pjproject... " >&6; }
+
+ PJPROJECT_INCLUDE=$(${GNU_MAKE} --quiet --no-print-directory -C ${PJPROJECT_DIR} echo_cflags)
+ PJPROJECT_CFLAGS="$PJPROJECT_INCLUDE"
+ PBX_PJPROJECT=1
+
+
+$as_echo "#define HAVE_PJPROJECT 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJPROJECT_BUNDLED 1" >>confdefs.h
+
+
+
+$as_echo "#define HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJ_TRANSACTION_GRP_LOCK 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJSIP_REPLACE_MEDIA_STREAM 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJSIP_GET_DEST_INFO 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJSIP_EXTERNAL_RESOLVER 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJSIP_TLS_TRANSPORT_PROTO 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJSIP_EVSUB_GRP_LOCK 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PJSIP_INV_SESSION_REF 1" >>confdefs.h
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ fi
+
+
+
# AST_EXT_LIB_SETUP is used to tell configure to handle variables for
# various packages.
# $1 is the prefix for the variables in makeopts and autoconfig.h
@@ -10938,6 +11321,7 @@ fi
+if test "x${PBX_PJPROJECT}" != "x1" ; then
PJPROJECT_DESCRIP="PJPROJECT"
PJPROJECT_OPTION="pjproject"
@@ -10970,29 +11354,6 @@ fi
-PJPROJECT_BUNDLED=no
-
-
-
-# Check whether --with-pjproject-bundled was given.
-if test "${with_pjproject_bundled+set}" = set; then :
- withval=$with_pjproject_bundled; case "${enableval}" in
- n|no) PJPROJECT_BUNDLED=no ;;
- *) PJPROJECT_BUNDLED=yes ;;
- esac
-fi
-
-
-
-if test "$PJPROJECT_BUNDLED" = "yes" -a "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then
- as_fn_error $? "--with-pjproject and --with-pjproject-bundled can't both be specified" "$LINENO" 5
-fi
-
-if test "$PJPROJECT_BUNDLED" = "yes" ; then
- ac_mandatory_list="$ac_mandatory_list PJPROJECT"
- PJPROJECT_DIR="${ac_top_build_prefix}third-party/pjproject"
-fi
-
PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_DESCRIP="PJSIP Dialog Create UAS with Incremented Lock"
PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_OPTION=pjsip
@@ -11101,6 +11462,7 @@ PBX_PJSIP_INV_SESSION_REF=0
+fi
POPT_DESCRIP="popt"
@@ -11507,6 +11869,38 @@ fi
+ FFTW3_DESCRIP="LIBFFTW3"
+ FFTW3_OPTION="fftw3"
+ PBX_FFTW3=0
+
+# Check whether --with-fftw3 was given.
+if test "${with_fftw3+set}" = set; then :
+ withval=$with_fftw3;
+ case ${withval} in
+ n|no)
+ USE_FFTW3=no
+ # -1 is a magic value used by menuselect to know that the package
+ # was disabled, other than 'not found'
+ PBX_FFTW3=-1
+ ;;
+ y|ye|yes)
+ ac_mandatory_list="${ac_mandatory_list} FFTW3"
+ ;;
+ *)
+ FFTW3_DIR="${withval}"
+ ac_mandatory_list="${ac_mandatory_list} FFTW3"
+ ;;
+ esac
+
+fi
+
+
+
+
+
+
+
+
RESAMPLE_DESCRIP="LIBRESAMPLE"
RESAMPLE_OPTION="resample"
PBX_RESAMPLE=0
@@ -11603,54 +11997,6 @@ fi
-
-# Check whether --with-sounds-cache was given.
-if test "${with_sounds_cache+set}" = set; then :
- withval=$with_sounds_cache;
- case ${withval} in
- n|no)
- unset SOUNDS_CACHE_DIR
- ;;
- *)
- if test "x${withval}" = "x"; then
- :
- else
- SOUNDS_CACHE_DIR="${withval}"
- fi
- ;;
- esac
-
-else
- :
-fi
-
-
-
-
-
-# Check whether --with-externals-cache was given.
-if test "${with_externals_cache+set}" = set; then :
- withval=$with_externals_cache;
- case ${withval} in
- n|no)
- unset EXTERNALS_CACHE_DIR
- ;;
- *)
- if test "x${withval}" = "x"; then
- :
- else
- EXTERNALS_CACHE_DIR="${withval}"
- fi
- ;;
- esac
-
-else
- :
-fi
-
-
-
-
SPANDSP_DESCRIP="SPANDSP"
SPANDSP_OPTION="spandsp"
PBX_SPANDSP=0
@@ -25153,251 +25499,7 @@ $as_echo "$as_me: *** including --without-postgres" >&6;}
fi
if test "$USE_PJPROJECT" != "no" ; then
- if test "$PJPROJECT_BUNDLED" = "yes" ; then
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded pjproject (may have to download)" >&5
-$as_echo_n "checking for embedded pjproject (may have to download)... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: configuring" >&5
-$as_echo "configuring" >&6; }
- ${GNU_MAKE} --quiet --no-print-directory -C $PJPROJECT_DIR configure
- if test $? -ne 0 ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: Unable to configure $PJPROJECT_DIR" >&5
-$as_echo "$as_me: Unable to configure $PJPROJECT_DIR" >&6;}
- as_fn_error $? "Run \"${GNU_MAKE} -C $PJPROJECT_DIR NOISY_BUILD=yes configure\" to see error details." "$LINENO" 5
- fi
-
- PJPROJECT_INCLUDE=$(${GNU_MAKE} --quiet --no-print-directory -C $PJPROJECT_DIR echo_cflags)
- PJPROJECT_CFLAGS="$PJPROJECT_INCLUDE"
- PBX_PJPROJECT=1
- PJPROJECT_BUNDLED=yes
-
-$as_echo "#define HAVE_PJPROJECT 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_PJPROJECT_BUNDLED 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for embedded pjproject" >&5
-$as_echo_n "checking for embedded pjproject... " >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-
- PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_dlg_create_uas_and_inc_lock declared in pjsip.h" >&5
-$as_echo_n "checking for pjsip_dlg_create_uas_and_inc_lock declared in pjsip.h... " >&6; }
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <pjsip.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "pjsip_dlg_create_uas_and_inc_lock" >/dev/null 2>&1; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- PBX_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK=1
-
-$as_echo "#define HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 1" >>confdefs.h
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f conftest*
-
-
- CPPGLAGS="$saved_cpp"
- PJSIP_DLG_CREATE_UAS_AND_INC_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
-
-
- PJ_TRANSACTION_GRP_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_tsx_create_uac2 declared in pjsip.h" >&5
-$as_echo_n "checking for pjsip_tsx_create_uac2 declared in pjsip.h... " >&6; }
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <pjsip.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "pjsip_tsx_create_uac2" >/dev/null 2>&1; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- PBX_PJ_TRANSACTION_GRP_LOCK=1
-
-$as_echo "#define HAVE_PJ_TRANSACTION_GRP_LOCK 1" >>confdefs.h
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f conftest*
-
-
- CPPGLAGS="$saved_cpp"
- PJ_TRANSACTION_GRP_LOCK_INCLUDE="$PJPROJECT_INCLUDE"
-
-
- PJSIP_REPLACE_MEDIA_STREAM_INCLUDE="$PJPROJECT_INCLUDE"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE declared in pjmedia.h" >&5
-$as_echo_n "checking for PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE declared in pjmedia.h... " >&6; }
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <pjmedia.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE" >/dev/null 2>&1; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- PBX_PJSIP_REPLACE_MEDIA_STREAM=1
-
-$as_echo "#define HAVE_PJSIP_REPLACE_MEDIA_STREAM 1" >>confdefs.h
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f conftest*
-
-
- CPPGLAGS="$saved_cpp"
- PJSIP_REPLACE_MEDIA_STREAM_INCLUDE="$PJPROJECT_INCLUDE"
-
-
- PJSIP_GET_DEST_INFO_INCLUDE="$PJPROJECT_INCLUDE"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_get_dest_info declared in pjsip.h" >&5
-$as_echo_n "checking for pjsip_get_dest_info declared in pjsip.h... " >&6; }
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <pjsip.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "pjsip_get_dest_info" >/dev/null 2>&1; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- PBX_PJSIP_GET_DEST_INFO=1
-
-$as_echo "#define HAVE_PJSIP_GET_DEST_INFO 1" >>confdefs.h
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f conftest*
-
-
- CPPGLAGS="$saved_cpp"
- PJSIP_GET_DEST_INFO_INCLUDE="$PJPROJECT_INCLUDE"
-
-
- PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="$PJPROJECT_INCLUDE"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pj_ssl_cert_load_from_files2 declared in pjlib.h" >&5
-$as_echo_n "checking for pj_ssl_cert_load_from_files2 declared in pjlib.h... " >&6; }
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <pjlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "pj_ssl_cert_load_from_files2" >/dev/null 2>&1; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- PBX_PJ_SSL_CERT_LOAD_FROM_FILES2=1
-
-$as_echo "#define HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2 1" >>confdefs.h
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f conftest*
-
-
- CPPGLAGS="$saved_cpp"
- PJ_SSL_CERT_LOAD_FROM_FILES2_INCLUDE="$PJPROJECT_INCLUDE"
-
-
- PJSIP_EXTERNAL_RESOLVER_INCLUDE="$PJPROJECT_INCLUDE"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pjsip_endpt_set_ext_resolver declared in pjsip.h" >&5
-$as_echo_n "checking for pjsip_endpt_set_ext_resolver declared in pjsip.h... " >&6; }
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <pjsip.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "pjsip_endpt_set_ext_resolver" >/dev/null 2>&1; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- PBX_PJSIP_EXTERNAL_RESOLVER=1
-
-$as_echo "#define HAVE_PJSIP_EXTERNAL_RESOLVER 1" >>confdefs.h
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
-fi
-rm -f conftest*
-
-
- CPPGLAGS="$saved_cpp"
- PJSIP_EXTERNAL_RESOLVER_INCLUDE="$PJPROJECT_INCLUDE"
-
-
-$as_echo "#define HAVE_PJSIP_TLS_TRANSPORT_PROTO 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_PJSIP_EVSUB_GRP_LOCK 1" >>confdefs.h
-
-
-$as_echo "#define HAVE_PJSIP_INV_SESSION_REF 1" >>confdefs.h
-
-
- else
+ if test "$PJPROJECT_BUNDLED" = "no" ; then
if test "x${PBX_PJPROJECT}" != "x1" -a "${USE_PJPROJECT}" != "no"; then
@@ -28920,6 +29022,115 @@ fi
+if test "x${PBX_FFTW3}" != "x1" -a "${USE_FFTW3}" != "no"; then
+ pbxlibdir=""
+ # if --with-FFTW3=DIR has been specified, use it.
+ if test "x${FFTW3_DIR}" != "x"; then
+ if test -d ${FFTW3_DIR}/lib; then
+ pbxlibdir="-L${FFTW3_DIR}/lib"
+ else
+ pbxlibdir="-L${FFTW3_DIR}"
+ fi
+ fi
+ pbxfuncname="fftw_alloc_real"
+ if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers
+ AST_FFTW3_FOUND=yes
+ else
+ ast_ext_lib_check_save_CFLAGS="${CFLAGS}"
+ CFLAGS="${CFLAGS} "
+ as_ac_Lib=`$as_echo "ac_cv_lib_fftw3_${pbxfuncname}" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${pbxfuncname} in -lfftw3" >&5
+$as_echo_n "checking for ${pbxfuncname} in -lfftw3... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3 ${pbxlibdir} -lfftw3 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ${pbxfuncname} ();
+int
+main ()
+{
+return ${pbxfuncname} ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_ac_Lib=yes"
+else
+ eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+ AST_FFTW3_FOUND=yes
+else
+ AST_FFTW3_FOUND=no
+fi
+
+ CFLAGS="${ast_ext_lib_check_save_CFLAGS}"
+ fi
+
+ # now check for the header.
+ if test "${AST_FFTW3_FOUND}" = "yes"; then
+ FFTW3_LIB="${pbxlibdir} -lfftw3 -lfftw3"
+ # if --with-FFTW3=DIR has been specified, use it.
+ if test "x${FFTW3_DIR}" != "x"; then
+ FFTW3_INCLUDE="-I${FFTW3_DIR}/include"
+ fi
+ FFTW3_INCLUDE="${FFTW3_INCLUDE} "
+ if test "xfftw3.h" = "x" ; then # no header, assume found
+ FFTW3_HEADER_FOUND="1"
+ else # check for the header
+ ast_ext_lib_check_saved_CPPFLAGS="${CPPFLAGS}"
+ CPPFLAGS="${CPPFLAGS} ${FFTW3_INCLUDE}"
+ ac_fn_c_check_header_mongrel "$LINENO" "fftw3.h" "ac_cv_header_fftw3_h" "$ac_includes_default"
+if test "x$ac_cv_header_fftw3_h" = xyes; then :
+ FFTW3_HEADER_FOUND=1
+else
+ FFTW3_HEADER_FOUND=0
+fi
+
+
+ CPPFLAGS="${ast_ext_lib_check_saved_CPPFLAGS}"
+ fi
+ if test "x${FFTW3_HEADER_FOUND}" = "x0" ; then
+ FFTW3_LIB=""
+ FFTW3_INCLUDE=""
+ else
+ if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library
+ FFTW3_LIB=""
+ fi
+ PBX_FFTW3=1
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FFTW3 1
+_ACEOF
+
+ fi
+ fi
+fi
+
+
+if test "$PBX_FFTW3" = "1"; then
+
+$as_echo "#define HAVE_FFTW 1" >>confdefs.h
+
+fi
+
if test "x${PBX_SPANDSP}" != "x1" -a "${USE_SPANDSP}" != "no"; then
if test "xminimum version of SpanDSP" != "x"; then
diff --git a/configure.ac b/configure.ac
index 17b887266..0f2148b06 100644
--- a/configure.ac
+++ b/configure.ac
@@ -284,16 +284,27 @@ AC_PATH_PROG([XMLSTARLET], [xmlstarlet], :)
AC_PATH_PROG([BASH], [bash], :)
AC_PATH_PROG([GIT], [git], :)
AC_PATH_PROG([ALEMBIC], [alembic], :)
+AC_PATH_PROG([BZIP2], [bzip2], :)
+AC_PATH_PROG([TAR], [tar], :)
+AC_PATH_PROG([PATCH], [patch], :)
+AC_PATH_PROG([SED], [sed], :)
+AC_PATH_PROG([NM], [nm], :)
+
if test "${WGET}" != ":" ; then
DOWNLOAD=${WGET}
+ DOWNLOAD_TO_STDOUT="${WGET} -O-"
else if test "${CURL}" != ":" ; then
DOWNLOAD="${CURL} -O --progress-bar -w \"%{url_effective}\n\""
+ DOWNLOAD_TO_STDOUT="${CURL} -L --progress-bar -w \"%{url_effective}\n\""
else
AC_PATH_PROG([FETCH], [fetch], [:])
DOWNLOAD=${FETCH}
+ DOWNLOAD_TO_STDOUT="${FETCH} -o-"
fi
fi
+
AC_SUBST(DOWNLOAD)
+AC_SUBST(DOWNLOAD_TO_STDOUT)
AC_PATH_PROG([LDCONFIG], [ldconfig], :)
AC_PATH_PROG([SHA1SUM], [sha1sum], $ac_aux_dir/build_tools/sha1sum-sh)
AC_PATH_PROG([OPENSSL], [openssl], :)
@@ -390,6 +401,9 @@ AC_SUBST(NOISY_BUILD)
AC_SUBST(AST_DEVMODE)
AC_SUBST(AST_DEVMODE_STRICT)
+AST_OPTION_ONLY([sounds-cache], [SOUNDS_CACHE_DIR], [cached sound tarfiles], [])
+AST_OPTION_ONLY([externals-cache], [EXTERNALS_CACHE_DIR], [cached external module tarfiles], [])
+
AST_CODE_COVERAGE=no
AC_ARG_ENABLE([coverage],
[AS_HELP_STRING([--enable-coverage],
@@ -404,6 +418,19 @@ AC_SUBST(AST_CODE_COVERAGE)
AST_CHECK_RAII()
AST_CHECK_STRSEP_ARRAY_BOUNDS()
+PJPROJECT_BUNDLED=no
+AH_TEMPLATE(m4_bpatsubst([[HAVE_PJPROJECT_BUNDLED]], [(.*)]), [Define to 1 when using the bundled pjproject.])
+
+AC_ARG_WITH([pjproject-bundled],
+ [AS_HELP_STRING([--with-pjproject-bundled],
+ [Use bundled pjproject libraries])],
+ [case "${enableval}" in
+ n|no) PJPROJECT_BUNDLED=no ;;
+ *) PJPROJECT_BUNDLED=yes ;;
+ esac])
+
+THIRD_PARTY_CONFIGURE()
+
# AST_EXT_LIB_SETUP is used to tell configure to handle variables for
# various packages.
# $1 is the prefix for the variables in makeopts and autoconfig.h
@@ -472,28 +499,8 @@ AST_EXT_LIB_SETUP([OSPTK], [OSP Toolkit], [osptk])
AST_EXT_LIB_SETUP([OSS], [Open Sound System], [oss])
AST_EXT_LIB_SETUP([PGSQL], [PostgreSQL], [postgres])
+if test "x${PBX_PJPROJECT}" != "x1" ; then
AST_EXT_LIB_SETUP([PJPROJECT], [PJPROJECT], [pjproject])
-PJPROJECT_BUNDLED=no
-AH_TEMPLATE(m4_bpatsubst([[HAVE_PJPROJECT_BUNDLED]], [(.*)]), [Define to 1 when using the bundled pjproject.])
-
-AC_ARG_WITH([pjproject-bundled],
- [AS_HELP_STRING([--with-pjproject-bundled],
- [Use bundled pjproject libraries])],
- [case "${enableval}" in
- n|no) PJPROJECT_BUNDLED=no ;;
- *) PJPROJECT_BUNDLED=yes ;;
- esac])
-AC_SUBST(PJPROJECT_BUNDLED)
-
-if test "$PJPROJECT_BUNDLED" = "yes" -a "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then
- AC_MSG_ERROR(--with-pjproject and --with-pjproject-bundled can't both be specified)
-fi
-
-if test "$PJPROJECT_BUNDLED" = "yes" ; then
- ac_mandatory_list="$ac_mandatory_list PJPROJECT"
- PJPROJECT_DIR="${ac_top_build_prefix}third-party/pjproject"
-fi
-
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [PJSIP Dialog Create UAS with Incremented Lock], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJ_TRANSACTION_GRP_LOCK], [PJSIP Transaction Group Lock Support], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_REPLACE_MEDIA_STREAM], [PJSIP Media Stream Replacement Support], [PJPROJECT], [pjsip])
@@ -503,6 +510,7 @@ AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_EXTERNAL_RESOLVER], [PJSIP External Resolver S
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_TLS_TRANSPORT_PROTO], [PJSIP TLS Transport proto field support], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_EVSUB_GRP_LOCK], [PJSIP EVSUB Group Lock support], [PJPROJECT], [pjsip])
AST_EXT_LIB_SETUP_OPTIONAL([PJSIP_INV_SESSION_REF], [PJSIP INVITE Session Reference Count support], [PJPROJECT], [pjsip])
+fi
AST_EXT_LIB_SETUP([POPT], [popt], [popt])
AST_EXT_LIB_SETUP([PORTAUDIO], [PortAudio], [portaudio])
@@ -533,11 +541,10 @@ AST_EXT_LIB_SETUP_OPTIONAL([PRI_REVERSE_CHARGE], [ISDN reverse charge], [PRI], [
# ------------------------------------^
AST_EXT_LIB_SETUP([PWLIB], [PWlib], [pwlib])
AST_EXT_LIB_SETUP([RADIUS], [Radius Client], [radius])
+AST_EXT_LIB_SETUP([FFTW3], [LIBFFTW3], [fftw3])
AST_EXT_LIB_SETUP([RESAMPLE], [LIBRESAMPLE], [resample])
AST_EXT_LIB_SETUP([SDL], [Sdl], [sdl])
AST_EXT_LIB_SETUP([SDL_IMAGE], [Sdl Image], [SDL_image])
-AST_OPTION_ONLY([sounds-cache], [SOUNDS_CACHE_DIR], [cached sound tarfiles], [])
-AST_OPTION_ONLY([externals-cache], [EXTERNALS_CACHE_DIR], [cached external module tarfiles], [])
AST_EXT_LIB_SETUP([SPANDSP], [SPANDSP], [spandsp])
AST_EXT_LIB_SETUP([SS7], [ISDN SS7], [ss7])
AST_EXT_LIB_SETUP([SPEEX], [Speex], [speex])
@@ -2198,9 +2205,7 @@ if test "${PG_CONFIG}" != No; then
fi
if test "$USE_PJPROJECT" != "no" ; then
- if test "$PJPROJECT_BUNDLED" = "yes" ; then
- PJPROJECT_CONFIGURE([$PJPROJECT_DIR])
- else
+ if test "$PJPROJECT_BUNDLED" = "no" ; then
AST_PKG_CONFIG_CHECK([PJPROJECT], [libpjproject])
AST_EXT_LIB_CHECK([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [pjsip], [pjsip_dlg_create_uas_and_inc_lock], [pjsip.h], [$PJPROJECT_LIBS], [$PJPROJECT_CFLAGS])
@@ -2267,6 +2272,10 @@ AST_EXT_LIB_CHECK([PRI_REVERSE_CHARGE], [pri], [pri_sr_set_reversecharge], [libp
# ------------------------------------^
AST_EXT_LIB_CHECK([RESAMPLE], [resample], [resample_open], [libresample.h], [-lm])
+AST_EXT_LIB_CHECK([FFTW3], [fftw3], [fftw_alloc_real], [fftw3.h], [-lfftw3])
+if test "$PBX_FFTW3" = "1"; then
+ AC_DEFINE([HAVE_FFTW], 1, [Define 1 if your system has fftw.])
+fi
AST_C_COMPILE_CHECK([SPANDSP], [
#if SPANDSP_RELEASE_DATE < 20080516
diff --git a/contrib/ast-db-manage/README.md b/contrib/ast-db-manage/README.md
index 3444dd5cd..7add3ee66 100644
--- a/contrib/ast-db-manage/README.md
+++ b/contrib/ast-db-manage/README.md
@@ -9,6 +9,7 @@ This is implemented as a set of repositories that contain database schema
migrations, using [Alembic](http://alembic.readthedocs.org). The existing
repositories include:
+ * `cdr` - Table used for Asterisk to store CDR records
* `config` - Tables used for Asterisk realtime configuration
* `voicemail` - Tables used for `ODBC_STOARGE` of voicemail messages
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index e16b66861..706798ced 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -239,6 +239,12 @@
/* Define to 1 if you have the `ffsll' function. */
#undef HAVE_FFSLL
+/* Define 1 if your system has fftw. */
+#undef HAVE_FFTW
+
+/* Define to 1 if you have the LIBFFTW3 library. */
+#undef HAVE_FFTW3
+
/* Define to 1 if you have the `floor' function. */
#undef HAVE_FLOOR
@@ -586,19 +592,22 @@
/* Define if your system has PJPROJECT_BUNDLED */
#undef HAVE_PJPROJECT_BUNDLED
-/* Define if your system has pjsip_dlg_create_uas_and_inc_lock declared. */
+/* Define to 1 if PJPROJECT has the PJSIP Dialog Create UAS with Incremented
+ Lock feature. */
#undef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
-/* Define if your system has PJSIP_EVSUB_GRP_LOCK */
+/* Define to 1 if PJPROJECT has the PJSIP EVSUB Group Lock support feature. */
#undef HAVE_PJSIP_EVSUB_GRP_LOCK
-/* Define if your system has pjsip_endpt_set_ext_resolver declared. */
+/* Define to 1 if PJPROJECT has the PJSIP External Resolver Support feature.
+ */
#undef HAVE_PJSIP_EXTERNAL_RESOLVER
-/* Define if your system has pjsip_get_dest_info declared. */
+/* Define to 1 if PJPROJECT has the pjsip_get_dest_info support feature. */
#undef HAVE_PJSIP_GET_DEST_INFO
-/* Define if your system has PJSIP_INV_SESSION_REF */
+/* Define to 1 if PJPROJECT has the PJSIP INVITE Session Reference Count
+ support feature. */
#undef HAVE_PJSIP_INV_SESSION_REF
/* Define if your system has the PJSIP_REPLACE_MEDIA_STREAM headers. */
@@ -607,10 +616,12 @@
/* Define if your system has the PJSIP_TLS_TRANSPORT_PROTO headers. */
#undef HAVE_PJSIP_TLS_TRANSPORT_PROTO
-/* Define if your system has pj_ssl_cert_load_from_files2 declared. */
+/* Define to 1 if PJPROJECT has the pj_ssl_cert_load_from_files2 support
+ feature. */
#undef HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2
-/* Define if your system has pjsip_tsx_create_uac2 declared. */
+/* Define to 1 if PJPROJECT has the PJSIP Transaction Group Lock Support
+ feature. */
#undef HAVE_PJ_TRANSACTION_GRP_LOCK
/* Define to 1 if your system defines IP_PKTINFO. */
diff --git a/include/asterisk/calendar.h b/include/asterisk/calendar.h
index da4af01ef..e9dcd8809 100644
--- a/include/asterisk/calendar.h
+++ b/include/asterisk/calendar.h
@@ -129,6 +129,7 @@ struct ast_calendar {
int autoreminder; /*!< If set, override any calendar_tech specific notification times and use this time (in mins) */
int notify_waittime; /*!< Maxiumum time to allow for a notification attempt */
int refresh; /*!< When to refresh the calendar events */
+ int fetch_again_at_reload; /*!< To reload the calendar content when the module is reloaded */
int timeframe; /*!< Span (in mins) of calendar data to pull with each request */
pthread_t thread; /*!< The thread that the calendar is loaded/updated in */
ast_cond_t unload;
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 3293dd77b..df752c902 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -2017,6 +2017,16 @@ int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_ca
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format);
/*!
+ * \brief Sets write format for a channel.
+ * All internal data will than be handled in an interleaved format. (needed by binaural opus)
+ *
+ * \param chan channel to change
+ * \param format format to set for writing
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_write_format_interleaved_stereo(struct ast_channel *chan, struct ast_format *format);
+
+/*!
* \brief Sends text to a channel
*
* \param chan channel to act upon
diff --git a/include/asterisk/json.h b/include/asterisk/json.h
index 28ebfbd51..cfd9a2997 100644
--- a/include/asterisk/json.h
+++ b/include/asterisk/json.h
@@ -217,6 +217,41 @@ const char *ast_json_typename(enum ast_json_type type);
/*!@{*/
/*!
+ * \brief Check the string of the given length for UTF-8 format.
+ * \since 13.12.0
+ *
+ * \param str String to check.
+ * \param len Length of string to check.
+ *
+ * \retval 0 if not UTF-8 encoded or str is NULL.
+ * \retval 1 if UTF-8 encoded.
+ */
+int ast_json_utf8_check_len(const char *str, size_t len);
+
+/*!
+ * \brief Check the nul terminated string for UTF-8 format.
+ * \since 13.12.0
+ *
+ * \param str String to check.
+ *
+ * \retval 0 if not UTF-8 encoded or str is NULL.
+ * \retval 1 if UTF-8 encoded.
+ */
+int ast_json_utf8_check(const char *str);
+
+/*!
+ * \brief Check str for UTF-8 and replace with an empty string if fails the check.
+ *
+ * \note The convenience macro is normally used with ast_json_pack()
+ * or a function wrapper that calls ast_json_vpack().
+ */
+#define AST_JSON_UTF8_VALIDATE(str) (ast_json_utf8_check(str) ? (str) : "")
+
+/*!@}*/
+
+/*!@{*/
+
+/*!
* \brief Get the JSON true value.
* \since 12.0.0
*
diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h
index b8cd21971..8188eb8eb 100644
--- a/include/asterisk/translate.h
+++ b/include/asterisk/translate.h
@@ -231,6 +231,7 @@ struct ast_trans_pvt {
* explicit_dst contains an attribute which describes whether both parties
* want to do forward-error correction (FEC). */
struct ast_format *explicit_dst;
+ int interleaved_stereo; /*!< indicates if samples are in interleaved order, for stereo lin */
};
/*! \brief generic frameout function */
diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h
index b4a8a2c11..c74f0a89b 100644
--- a/include/asterisk/vector.h
+++ b/include/asterisk/vector.h
@@ -367,11 +367,13 @@
int count = 0; \
size_t idx; \
typeof(value) __value = (value); \
- for (idx = 0; idx < (vec)->current; ++idx) { \
+ for (idx = 0; idx < (vec)->current; ) { \
if (cmp((vec)->elems[idx], __value)) { \
cleanup((vec)->elems[idx]); \
AST_VECTOR_REMOVE_UNORDERED((vec), idx); \
++count; \
+ } else { \
+ ++idx; \
} \
} \
count; \
@@ -417,14 +419,16 @@
int count = 0; \
size_t idx; \
typeof(value) __value = (value); \
- for (idx = 0; idx < (vec)->current; ++idx) { \
+ for (idx = 0; idx < (vec)->current; ) { \
if (cmp((vec)->elems[idx], __value)) { \
cleanup((vec)->elems[idx]); \
- AST_VECTOR_REMOVE_ORDERED((vec), idx); \
+ AST_VECTOR_REMOVE_ORDERED((vec), idx); \
++count; \
+ } else { \
+ ++idx; \
} \
} \
- oount; \
+ count; \
})
/*!
@@ -445,7 +449,7 @@
for (idx = 0; idx < (vec)->current; ++idx) { \
if (cmp((vec)->elems[idx], __value)) { \
cleanup((vec)->elems[idx]); \
- AST_VECTOR_REMOVE_ORDERED((vec), idx); \
+ AST_VECTOR_REMOVE_ORDERED((vec), idx); \
res = 0; \
break; \
} \
diff --git a/main/aoc.c b/main/aoc.c
index cd9c461c1..8d4332901 100644
--- a/main/aoc.c
+++ b/main/aoc.c
@@ -1656,8 +1656,10 @@ static struct ast_json *units_to_json(const struct ast_aoc_decoded *decoded)
static struct ast_json *currency_to_json(const char *name, int cost,
enum ast_aoc_currency_multiplier mult)
{
- return ast_json_pack("{s:s, s:i, s:s}", "Name", name,
- "Cost", cost, "Multiplier", aoc_multiplier_str(mult));
+ return ast_json_pack("{s:s, s:i, s:s}",
+ "Name", AST_JSON_UTF8_VALIDATE(name),
+ "Cost", cost,
+ "Multiplier", aoc_multiplier_str(mult));
}
static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
@@ -1667,8 +1669,8 @@ static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
if (decoded->charge_type != AST_AOC_CHARGE_CURRENCY &&
decoded->charge_type != AST_AOC_CHARGE_UNIT) {
- return ast_json_pack("{s:s}", "Type",
- aoc_charge_type_str(decoded->charge_type));
+ return ast_json_pack("{s:s}",
+ "Type", aoc_charge_type_str(decoded->charge_type));
}
if (decoded->charge_type == AST_AOC_CHARGE_CURRENCY) {
@@ -1680,8 +1682,7 @@ static struct ast_json *charge_to_json(const struct ast_aoc_decoded *decoded)
obj = units_to_json(decoded);
}
- return ast_json_pack(
- "{s:s, s:s, s:s, s:o}",
+ return ast_json_pack("{s:s, s:s, s:s, s:o}",
"Type", aoc_charge_type_str(decoded->charge_type),
"BillingID", aoc_billingid_str(decoded->billing_id),
"TotalType", aoc_type_of_totaling_str(decoded->total_type),
@@ -1692,13 +1693,11 @@ static struct ast_json *association_to_json(const struct ast_aoc_decoded *decode
{
switch (decoded->charging_association.charging_type) {
case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
- return ast_json_pack(
- "{s:s, s:i}",
- "Number", decoded->charging_association.charge.number.number,
+ return ast_json_pack("{s:s, s:i}",
+ "Number", AST_JSON_UTF8_VALIDATE(decoded->charging_association.charge.number.number),
"Plan", decoded->charging_association.charge.number.plan);
case AST_AOC_CHARGING_ASSOCIATION_ID:
- return ast_json_pack(
- "{s:i}", "ID", decoded->charging_association.charge.id);
+ return ast_json_pack("{s:i}", "ID", decoded->charging_association.charge.id);
case AST_AOC_CHARGING_ASSOCIATION_NA:
default:
return ast_json_null();
@@ -1740,22 +1739,22 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
decoded->aoc_s_entries[i].rate.duration.amount,
decoded->aoc_s_entries[i].rate.duration.multiplier);
- time = ast_json_pack(
- "{s:i, s:s}",
+ time = ast_json_pack("{s:i, s:i}",
"Length", decoded->aoc_s_entries[i].rate.duration.time,
"Scale", decoded->aoc_s_entries[i].rate.duration.time_scale);
if (decoded->aoc_s_entries[i].rate.duration.granularity_time) {
- granularity = ast_json_pack(
- "{s:i, s:s}",
+ granularity = ast_json_pack("{s:i, s:i}",
"Length", decoded->aoc_s_entries[i].rate.duration.granularity_time,
"Scale", decoded->aoc_s_entries[i].rate.duration.granularity_time_scale);
}
- type = ast_json_pack("{s:o, s:s, s:o, s:o}", "Currency", ast_json_ref(currency), "ChargingType",
- decoded->aoc_s_entries[i].rate.duration.charging_type ?
- "StepFunction" : "ContinuousCharging", "Time", ast_json_ref(time),
- "Granularity", granularity ? ast_json_ref(granularity) : ast_json_ref(ast_json_null()));
+ type = ast_json_pack("{s:o, s:s, s:o, s:o}",
+ "Currency", ast_json_ref(currency),
+ "ChargingType", decoded->aoc_s_entries[i].rate.duration.charging_type
+ ? "StepFunction" : "ContinuousCharging",
+ "Time", ast_json_ref(time),
+ "Granularity", granularity ? ast_json_ref(granularity) : ast_json_null());
break;
}
@@ -1773,21 +1772,22 @@ static struct ast_json *s_to_json(const struct ast_aoc_decoded *decoded)
decoded->aoc_s_entries[i].rate.volume.amount,
decoded->aoc_s_entries[i].rate.volume.multiplier);
- type = ast_json_pack(
- "{s:s, s:o}", "Unit", aoc_volume_unit_str(
+ type = ast_json_pack("{s:s, s:o}",
+ "Unit", aoc_volume_unit_str(
decoded->aoc_s_entries[i].rate.volume.volume_unit),
"Currency", ast_json_ref(currency));
break;
case AST_AOC_RATE_TYPE_SPECIAL_CODE:
- type = ast_json_pack("{s:i}", "SpecialCode",
- decoded->aoc_s_entries[i].rate.special_code);
+ type = ast_json_pack("{s:i}",
+ "SpecialCode", decoded->aoc_s_entries[i].rate.special_code);
break;
default:
break;
}
- rate = ast_json_pack("{s:s, s:o}", "Chargeable", charge_item,
- aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), ast_json_ref(type));
+ rate = ast_json_pack("{s:s, s:o}",
+ "Chargeable", charge_item,
+ aoc_rate_type_str(decoded->aoc_s_entries[i].rate_type), ast_json_ref(type));
if (ast_json_array_append(rates, rate)) {
break;
}
diff --git a/main/cdr.c b/main/cdr.c
index e2f9b764c..baa17b967 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -698,6 +698,7 @@ struct cdr_object {
);
struct cdr_object *next; /*!< The next CDR object in the chain */
struct cdr_object *last; /*!< The last CDR object in the chain */
+ int is_root; /*!< True if this is the first CDR in the chain */
};
/*!
@@ -853,7 +854,22 @@ static void cdr_object_dtor(void *obj)
}
ast_string_field_free_memory(cdr);
- ao2_cleanup(cdr->next);
+ /* CDR destruction used to work by calling ao2_cleanup(next) and
+ * allowing the chain to destroy itself neatly. Unfortunately, for
+ * really long chains, this can result in a stack overflow. So now
+ * when the root CDR is destroyed, it is responsible for unreffing
+ * all CDRs in the chain
+ */
+ if (cdr->is_root) {
+ struct cdr_object *curr = cdr->next;
+ struct cdr_object *next;
+
+ while (curr) {
+ next = curr->next;
+ ao2_cleanup(curr);
+ curr = next;
+ }
+ }
}
/*!
@@ -2100,6 +2116,7 @@ static void handle_channel_cache_message(void *data, struct stasis_subscription
if (!cdr) {
return;
}
+ cdr->is_root = 1;
ao2_link(active_cdrs_by_channel, cdr);
}
diff --git a/main/cel.c b/main/cel.c
index ad75c0186..aafeea432 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -1237,10 +1237,10 @@ static void cel_parking_cb(
if (parked_payload->retriever) {
extra = ast_json_pack("{s: s, s: s}",
- "reason", reason,
+ "reason", reason ?: "",
"retriever", parked_payload->retriever->name);
} else {
- extra = ast_json_pack("{s: s}", "reason", reason);
+ extra = ast_json_pack("{s: s}", "reason", reason ?: "");
}
if (extra) {
diff --git a/main/channel.c b/main/channel.c
index 94505ad0e..6804496f4 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3914,6 +3914,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
struct ast_frame *readq_tail = AST_LIST_LAST(ast_channel_readq(chan));
struct ast_control_read_action_payload *read_action_payload;
struct ast_party_connected_line connected;
+ int hooked = 0;
/* if the channel driver returned more than one frame, stuff the excess
into the readq for the next ast_read call
@@ -4191,15 +4192,22 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
break;
}
}
- /* Send frame to audiohooks if present */
- if (ast_channel_audiohooks(chan)) {
+ /*
+ * Send frame to audiohooks if present, if frametype is linear, to preserve
+ * functional compatibility with previous behavior. If not linear, hold off
+ * until transcoding is done where we are more likely to have a linear frame
+ */
+ if (ast_channel_audiohooks(chan) && ast_format_cache_is_slinear(f->subclass.format)) {
+ /* Place hooked after declaration */
struct ast_frame *old_frame = f;
+ hooked = 1;
f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
if (old_frame != f) {
ast_frfree(old_frame);
}
}
+
if (ast_channel_monitor(chan) && ast_channel_monitor(chan)->read_stream) {
/* XXX what does this do ? */
#ifndef MONITOR_CONSTANT_DELAY
@@ -4242,6 +4250,16 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
}
}
+ /* Second chance at hooking a linear frame, also the last chance */
+ if (ast_channel_audiohooks(chan) && !hooked) {
+ struct ast_frame *old_frame = f;
+
+ f = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_READ, f);
+ if (old_frame != f) {
+ ast_frfree(old_frame);
+ }
+ }
+
/*
* It is possible for the translation process on the channel to have
* produced multiple frames from the single input frame we passed it; if
@@ -5032,6 +5050,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
int res = -1;
struct ast_frame *f = NULL;
int count = 0;
+ int hooked = 0;
/*Deadlock avoidance*/
while(ast_channel_trylock(chan)) {
@@ -5149,6 +5168,22 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
apply_plc(chan, fr);
}
+ /*
+ * Send frame to audiohooks if present, if frametype is linear (else, later as per
+ * previous behavior)
+ */
+ if (ast_channel_audiohooks(chan)) {
+ if (ast_format_cache_is_slinear(fr->subclass.format)) {
+ struct ast_frame *old_frame;
+ hooked = 1;
+ old_frame = fr;
+ fr = ast_audiohook_write_list(chan, ast_channel_audiohooks(chan), AST_AUDIOHOOK_DIRECTION_WRITE, fr);
+ if (old_frame != fr) {
+ ast_frfree(old_frame);
+ }
+ }
+ }
+
/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
if (ast_format_cmp(fr->subclass.format, ast_channel_rawwriteformat(chan)) == AST_FORMAT_CMP_EQUAL) {
f = fr;
@@ -5186,7 +5221,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
break;
}
- if (ast_channel_audiohooks(chan)) {
+ if (ast_channel_audiohooks(chan) && !hooked) {
struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
int freeoldlist = 0;
@@ -5407,7 +5442,7 @@ static const struct set_format_access set_format_access_write = {
.setoption = AST_OPTION_FORMAT_WRITE,
};
-static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, const int direction)
+static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set, const int direction, int interleaved_stereo)
{
struct ast_trans_pvt *trans_pvt;
struct ast_format_cap *cap_native;
@@ -5509,16 +5544,20 @@ static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set,
}
/* Now we have a good choice for both. */
+ trans_pvt = access->get_trans(chan);
if ((ast_format_cmp(rawformat, best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
(ast_format_cmp(format, best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || access->get_trans(chan))) {
- /* the channel is already in these formats, so nothing to do */
- ast_channel_unlock(chan);
- return 0;
+ /* the channel is already in these formats, so nothing to do, unless the interleaved format is not set correctly */
+ if (trans_pvt != NULL) {
+ if (trans_pvt->interleaved_stereo == interleaved_stereo) {
+ ast_channel_unlock(chan);
+ return 0;
+ }
+ }
}
/* Free any translation we have right now */
- trans_pvt = access->get_trans(chan);
if (trans_pvt) {
ast_translator_free_path(trans_pvt);
access->set_trans(chan, NULL);
@@ -5536,9 +5575,11 @@ static int set_format(struct ast_channel *chan, struct ast_format_cap *cap_set,
if (!direction) {
/* reading */
trans_pvt = ast_translator_build_path(best_set_fmt, best_native_fmt);
+ trans_pvt->interleaved_stereo = 0;
} else {
/* writing */
trans_pvt = ast_translator_build_path(best_native_fmt, best_set_fmt);
+ trans_pvt->interleaved_stereo = interleaved_stereo;
}
access->set_trans(chan, trans_pvt);
res = trans_pvt ? 0 : -1;
@@ -5578,7 +5619,7 @@ int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
}
ast_format_cap_append(cap, format, 0);
- res = set_format(chan, cap, 0);
+ res = set_format(chan, cap, 0, 0);
ao2_cleanup(cap);
return res;
@@ -5586,7 +5627,25 @@ int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
{
- return set_format(chan, cap, 0);
+ return set_format(chan, cap, 0, 0);
+}
+
+int ast_set_write_format_interleaved_stereo(struct ast_channel *chan, struct ast_format *format)
+{
+ struct ast_format_cap *cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+ int res;
+
+ ast_assert(format != NULL);
+
+ if (!cap) {
+ return -1;
+ }
+ ast_format_cap_append(cap, format, 0);
+
+ res = set_format(chan, cap, 1, 1);
+
+ ao2_cleanup(cap);
+ return res;
}
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
@@ -5601,7 +5660,7 @@ int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
}
ast_format_cap_append(cap, format, 0);
- res = set_format(chan, cap, 1);
+ res = set_format(chan, cap, 1, 0);
ao2_cleanup(cap);
return res;
@@ -5609,7 +5668,7 @@ int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
{
- return set_format(chan, cap, 1);
+ return set_format(chan, cap, 1, 0);
}
const char *ast_channel_reason2str(int reason)
diff --git a/main/cli.c b/main/cli.c
index 8af20b61b..3ba743d75 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -449,19 +449,11 @@ static char *handle_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args
case CLI_INIT:
e->command = "core set debug";
e->usage =
-#if !defined(LOW_MEMORY)
"Usage: core set debug [atleast] <level> [module]\n"
-#else
- "Usage: core set debug [atleast] <level>\n"
-#endif
" core set debug off\n"
"\n"
-#if !defined(LOW_MEMORY)
" Sets level of debug messages to be displayed or\n"
" sets a module name to display debug messages from.\n"
-#else
- " Sets level of debug messages to be displayed.\n"
-#endif
" 0 or off means no messages should be displayed.\n"
" Equivalent to -d[d[...]] on startup\n";
return NULL;
@@ -489,13 +481,9 @@ static char *handle_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args
} else if (a->n == (22 - numbermatch) && a->pos == 3 && ast_strlen_zero(argv3)) {
return ast_strdup("atleast");
}
-#if !defined(LOW_MEMORY)
} else if ((a->pos == 4 && !atleast && strcasecmp(argv3, "off") && strcasecmp(argv3, "channel"))
|| (a->pos == 5 && atleast)) {
- const char *pos = S_OR(a->argv[a->pos], "");
-
- return ast_complete_source_filename(pos, a->n);
-#endif
+ return ast_module_helper(a->line, a->word, a->pos, a->n, a->pos, 0);
}
return NULL;
}
diff --git a/main/json.c b/main/json.c
index 12d5fc865..ca74f85dc 100644
--- a/main/json.c
+++ b/main/json.c
@@ -269,6 +269,127 @@ const char *ast_json_typename(enum ast_json_type type)
return "?";
}
+/* Ported from libjansson utf.c:utf8_check_first() */
+static size_t json_utf8_check_first(char byte)
+{
+ unsigned char ch = (unsigned char) byte;
+
+ if (ch < 0x80) {
+ return 1;
+ }
+
+ if (0x80 <= ch && ch <= 0xBF) {
+ /* second, third or fourth byte of a multi-byte
+ sequence, i.e. a "continuation byte" */
+ return 0;
+ } else if (ch == 0xC0 || ch == 0xC1) {
+ /* overlong encoding of an ASCII byte */
+ return 0;
+ } else if (0xC2 <= ch && ch <= 0xDF) {
+ /* 2-byte sequence */
+ return 2;
+ } else if (0xE0 <= ch && ch <= 0xEF) {
+ /* 3-byte sequence */
+ return 3;
+ } else if (0xF0 <= ch && ch <= 0xF4) {
+ /* 4-byte sequence */
+ return 4;
+ } else { /* ch >= 0xF5 */
+ /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
+ UTF-8 */
+ return 0;
+ }
+}
+
+/* Ported from libjansson utf.c:utf8_check_full() */
+static size_t json_utf8_check_full(const char *str, size_t len)
+{
+ size_t pos;
+ int32_t value;
+ unsigned char ch = (unsigned char) str[0];
+
+ if (len == 2) {
+ value = ch & 0x1F;
+ } else if (len == 3) {
+ value = ch & 0xF;
+ } else if (len == 4) {
+ value = ch & 0x7;
+ } else {
+ return 0;
+ }
+
+ for (pos = 1; pos < len; ++pos) {
+ ch = (unsigned char) str[pos];
+ if (ch < 0x80 || ch > 0xBF) {
+ /* not a continuation byte */
+ return 0;
+ }
+
+ value = (value << 6) + (ch & 0x3F);
+ }
+
+ if (value > 0x10FFFF) {
+ /* not in Unicode range */
+ return 0;
+ } else if (0xD800 <= value && value <= 0xDFFF) {
+ /* invalid code point (UTF-16 surrogate halves) */
+ return 0;
+ } else if ((len == 2 && value < 0x80)
+ || (len == 3 && value < 0x800)
+ || (len == 4 && value < 0x10000)) {
+ /* overlong encoding */
+ return 0;
+ }
+
+ return 1;
+}
+
+int ast_json_utf8_check_len(const char *str, size_t len)
+{
+ size_t pos;
+ size_t count;
+ int res = 1;
+
+ if (!str) {
+ return 0;
+ }
+
+ /*
+ * Since the json library does not make the check function
+ * public we recreate/copy the function in our interface
+ * module.
+ *
+ * Loop ported from libjansson utf.c:utf8_check_string()
+ */
+ for (pos = 0; pos < len; pos += count) {
+ count = json_utf8_check_first(str[pos]);
+ if (count == 0) {
+ res = 0;
+ break;
+ } else if (count > 1) {
+ if (count > len - pos) {
+ /* UTF-8 needs more than we have left in the string. */
+ res = 0;
+ break;
+ }
+
+ if (!json_utf8_check_full(&str[pos], count)) {
+ res = 0;
+ break;
+ }
+ }
+ }
+
+ if (!res) {
+ ast_debug(1, "String '%.*s' is not UTF-8 for json conversion\n", (int) len, str);
+ }
+ return res;
+}
+
+int ast_json_utf8_check(const char *str)
+{
+ return str ? ast_json_utf8_check_len(str, strlen(str)) : 0;
+}
struct ast_json *ast_json_true(void)
{
@@ -721,16 +842,16 @@ struct ast_json *ast_json_deep_copy(const struct ast_json *value)
struct ast_json *ast_json_name_number(const char *name, const char *number)
{
return ast_json_pack("{s: s, s: s}",
- "name", name,
- "number", number);
+ "name", AST_JSON_UTF8_VALIDATE(name),
+ "number", AST_JSON_UTF8_VALIDATE(number));
}
struct ast_json *ast_json_dialplan_cep(const char *context, const char *exten, int priority)
{
return ast_json_pack("{s: o, s: o, s: o}",
- "context", context ? ast_json_string_create(context) : ast_json_null(),
- "exten", exten ? ast_json_string_create(exten) : ast_json_null(),
- "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null());
+ "context", context ? ast_json_string_create(context) : ast_json_null(),
+ "exten", exten ? ast_json_string_create(exten) : ast_json_null(),
+ "priority", priority != -1 ? ast_json_integer_create(priority) : ast_json_null());
}
struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone)
@@ -821,7 +942,7 @@ static struct ast_json *json_party_number(struct ast_party_number *number)
return NULL;
}
return ast_json_pack("{s: s, s: i, s: i, s: s}",
- "number", number->str,
+ "number", AST_JSON_UTF8_VALIDATE(number->str),
"plan", number->plan,
"presentation", number->presentation,
"presentation_txt", ast_describe_caller_presentation(number->presentation));
@@ -833,7 +954,7 @@ static struct ast_json *json_party_name(struct ast_party_name *name)
return NULL;
}
return ast_json_pack("{s: s, s: s, s: i, s: s}",
- "name", name->str,
+ "name", AST_JSON_UTF8_VALIDATE(name->str),
"character_set", ast_party_name_charset_describe(name->char_set),
"presentation", name->presentation,
"presentation_txt", ast_describe_caller_presentation(name->presentation));
@@ -845,7 +966,7 @@ static struct ast_json *json_party_subaddress(struct ast_party_subaddress *subad
return NULL;
}
return ast_json_pack("{s: s, s: i, s: b}",
- "subaddress", subaddress->str,
+ "subaddress", AST_JSON_UTF8_VALIDATE(subaddress->str),
"type", subaddress->type,
"odd", subaddress->odd_even_indicator);
}
@@ -865,17 +986,20 @@ struct ast_json *ast_json_party_id(struct ast_party_id *party)
}
/* Party number */
- if (party->number.valid && ast_json_object_set(json_party_id, "number", json_party_number(&party->number))) {
+ if (party->number.valid
+ && ast_json_object_set(json_party_id, "number", json_party_number(&party->number))) {
return NULL;
}
/* Party name */
- if (party->name.valid && ast_json_object_set(json_party_id, "name", json_party_name(&party->name))) {
+ if (party->name.valid
+ && ast_json_object_set(json_party_id, "name", json_party_name(&party->name))) {
return NULL;
}
/* Party subaddress */
- if (party->subaddress.valid && ast_json_object_set(json_party_id, "subaddress", json_party_subaddress(&party->subaddress))) {
+ if (party->subaddress.valid
+ && ast_json_object_set(json_party_id, "subaddress", json_party_subaddress(&party->subaddress))) {
return NULL;
}
diff --git a/main/logger.c b/main/logger.c
index d4cd25122..7d0d2de1e 100644
--- a/main/logger.c
+++ b/main/logger.c
@@ -1867,6 +1867,10 @@ static void __attribute__((format(printf, 7, 0))) ast_log_full(int level, int su
int res = 0;
char datestring[256];
+ if (level == __LOG_VERBOSE && ast_opt_remote && ast_opt_exec) {
+ return;
+ }
+
if (!(buf = ast_str_thread_get(&log_buf, LOG_BUF_INIT_SIZE)))
return;
diff --git a/makeopts.in b/makeopts.in
index b2b394b5f..a145b02e6 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -27,6 +27,7 @@ STRIP=@STRIP@
WGET=@WGET@
FETCH=@FETCH@
DOWNLOAD=@DOWNLOAD@
+DOWNLOAD_TO_STDOUT=@DOWNLOAD_TO_STDOUT@
SOUNDS_CACHE_DIR=@SOUNDS_CACHE_DIR@
EXTERNALS_CACHE_DIR=@EXTERNALS_CACHE_DIR@
RUBBER=@RUBBER@
@@ -41,6 +42,10 @@ OPENSSL=@OPENSSL@
LDCONFIG=@LDCONFIG@
GIT=@GIT@
ALEMBIC=@ALEMBIC@
+TAR=@TAR@
+PATCH=@PATCH@
+SED=@SED@
+NM=@NM@
BUILD_PLATFORM=@BUILD_PLATFORM@
BUILD_CPU=@BUILD_CPU@
@@ -254,6 +259,9 @@ PYTHONDEV_LIB=@PYTHONDEV_LIB@
RESAMPLE_INCLUDE=@RESAMPLE_INCLUDE@
RESAMPLE_LIB=@RESAMPLE_LIB@
+FFTW3_INCLUDE=@FFTW3_INCLUDE@
+FFTW3_LIB=@FFTW3_LIB@
+
RT_LIB=@RT_LIB@
SS7_INCLUDE=@SS7_INCLUDE@
diff --git a/menuselect/aclocal.m4 b/menuselect/aclocal.m4
index 8b547156d..e67774c06 100644
--- a/menuselect/aclocal.m4
+++ b/menuselect/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -12,8 +12,285 @@
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
m4_include([../autoconf/ast_check_gnu_make.m4])
m4_include([../autoconf/ast_ext_lib.m4])
m4_include([../autoconf/ast_ext_tool_check.m4])
m4_include([../autoconf/ast_gcc_attribute.m4])
+m4_include([../autoconf/ast_pkgconfig.m4])
m4_include([../autoconf/ast_prog_sed.m4])
diff --git a/menuselect/configure b/menuselect/configure
index 648091e5f..4235ea0a4 100755
--- a/menuselect/configure
+++ b/menuselect/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.ac Revision: 418850 .
+# From configure.ac Revision.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
#
@@ -628,7 +628,11 @@ LIBOBJS
GTK2_LIB
GTK2_INCLUDE
PBX_GTK2
-PKGCONFIG
+GTK2_LIBS
+GTK2_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
CONFIG_LIBXML2
SED
PBX_LIBXML2
@@ -725,7 +729,12 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
-CPP'
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+GTK2_CFLAGS
+GTK2_LIBS'
# Initialize some variables set by options.
@@ -1356,6 +1365,13 @@ Some influential environment variables:
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
CPP C preprocessor
+ PKG_CONFIG path to pkg-config utility
+ PKG_CONFIG_PATH
+ directories to add to pkg-config's search path
+ PKG_CONFIG_LIBDIR
+ path overriding pkg-config's built-in search path
+ GTK2_CFLAGS C compiler flags for GTK2, overriding pkg-config
+ GTK2_LIBS linker flags for GTK2, overriding pkg-config
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@@ -4752,26 +4768,35 @@ if test "${PBX_LIBXML2}" != 1; then
as_fn_error $? "Could not find required 'Libxml2' development package" "$LINENO" 5
fi
-PBX_GTK2=0
-if test -n "$ac_tool_prefix"; then
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PKGCONFIG+:} false; then :
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
- if test -n "$PKGCONFIG"; then
- ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_PKGCONFIG="${ac_tool_prefix}pkg-config"
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -4779,12 +4804,13 @@ done
done
IFS=$as_save_IFS
+ ;;
+esac
fi
-fi
-PKGCONFIG=$ac_cv_prog_PKGCONFIG
-if test -n "$PKGCONFIG"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5
-$as_echo "$PKGCONFIG" >&6; }
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -4792,26 +4818,28 @@ fi
fi
-if test -z "$ac_cv_prog_PKGCONFIG"; then
- ac_ct_PKGCONFIG=$PKGCONFIG
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_PKGCONFIG+:} false; then :
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
- if test -n "$ac_ct_PKGCONFIG"; then
- ac_cv_prog_ac_ct_PKGCONFIG="$ac_ct_PKGCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_PKGCONFIG="pkg-config"
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
@@ -4819,19 +4847,20 @@ done
done
IFS=$as_save_IFS
+ ;;
+esac
fi
-fi
-ac_ct_PKGCONFIG=$ac_cv_prog_ac_ct_PKGCONFIG
-if test -n "$ac_ct_PKGCONFIG"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKGCONFIG" >&5
-$as_echo "$ac_ct_PKGCONFIG" >&6; }
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
- if test "x$ac_ct_PKGCONFIG" = x; then
- PKGCONFIG="No"
+ if test "x$ac_pt_PKG_CONFIG" = x; then
+ PKG_CONFIG=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
@@ -4839,20 +4868,114 @@ yes:)
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
- PKGCONFIG=$ac_ct_PKGCONFIG
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
fi
else
- PKGCONFIG="$ac_cv_prog_PKGCONFIG"
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.9.0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PKG_CONFIG=""
+ fi
fi
-if test ! "x${PKGCONFIG}" = xNo; then
- GTK2_INCLUDE=$(${PKGCONFIG} gtk+-2.0 --cflags 2>/dev/null)
- GTK2_LIB=$(${PKGCONFIG} gtk+-2.0 --libs)
- PBX_GTK2=1
+ if test "x${PBX_GTK2}" != "x1" -a "${USE_GTK2}" != "no"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK2" >&5
+$as_echo_n "checking for GTK2... " >&6; }
+
+if test -n "$GTK2_CFLAGS"; then
+ pkg_cv_GTK2_CFLAGS="$GTK2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTK2_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GTK2_LIBS"; then
+ pkg_cv_GTK2_LIBS="$GTK2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTK2_LIBS=`$PKG_CONFIG --libs "gtk+-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GTK2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-2.0" 2>&1`
+ else
+ GTK2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GTK2_PKG_ERRORS" >&5
+
+
+ PBX_GTK2=0
+
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+ PBX_GTK2=0
+
+
+else
+ GTK2_CFLAGS=$pkg_cv_GTK2_CFLAGS
+ GTK2_LIBS=$pkg_cv_GTK2_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ PBX_GTK2=1
+ GTK2_INCLUDE="$GTK2_CFLAGS"
+ GTK2_LIB="$GTK2_LIBS"
$as_echo "#define HAVE_GTK2 1" >>confdefs.h
+
fi
+ fi
+
diff --git a/menuselect/configure.ac b/menuselect/configure.ac
index 5989f5cd3..29c43cb50 100644
--- a/menuselect/configure.ac
+++ b/menuselect/configure.ac
@@ -134,14 +134,7 @@ if test "${PBX_LIBXML2}" != 1; then
AC_MSG_ERROR([Could not find required 'Libxml2' development package])
fi
-PBX_GTK2=0
-AC_CHECK_TOOL(PKGCONFIG, pkg-config, No)
-if test ! "x${PKGCONFIG}" = xNo; then
- GTK2_INCLUDE=$(${PKGCONFIG} gtk+-2.0 --cflags 2>/dev/null)
- GTK2_LIB=$(${PKGCONFIG} gtk+-2.0 --libs)
- PBX_GTK2=1
- AC_DEFINE([HAVE_GTK2], 1, [Define if your system has the GTK2 libraries.])
-fi
+AST_PKG_CONFIG_CHECK([GTK2], [gtk+-2.0])
AC_SUBST(PBX_GTK2)
AC_SUBST(GTK2_INCLUDE)
AC_SUBST(GTK2_LIB)
diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index 8f05db035..633a94c1b 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -1941,6 +1941,15 @@ int ast_ari_validate_application_replaced(struct ast_json *json)
int has_application = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ApplicationReplaced field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2009,6 +2018,15 @@ int ast_ari_validate_bridge_attended_transfer(struct ast_json *json)
int has_transferer_second_leg = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI BridgeAttendedTransfer field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2251,6 +2269,15 @@ int ast_ari_validate_bridge_blind_transfer(struct ast_json *json)
int has_result = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI BridgeBlindTransfer field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2417,6 +2444,15 @@ int ast_ari_validate_bridge_created(struct ast_json *json)
int has_bridge = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI BridgeCreated field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2496,6 +2532,15 @@ int ast_ari_validate_bridge_destroyed(struct ast_json *json)
int has_bridge = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI BridgeDestroyed field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2576,6 +2621,15 @@ int ast_ari_validate_bridge_merged(struct ast_json *json)
int has_bridge_from = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI BridgeMerged field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2672,6 +2726,15 @@ int ast_ari_validate_channel_caller_id(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelCallerId field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2781,6 +2844,15 @@ int ast_ari_validate_channel_connected_line(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelConnectedLine field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2860,6 +2932,15 @@ int ast_ari_validate_channel_created(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelCreated field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -2941,6 +3022,15 @@ int ast_ari_validate_channel_destroyed(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDestroyed field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3052,6 +3142,15 @@ int ast_ari_validate_channel_dialplan(struct ast_json *json)
int has_dialplan_app_data = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDialplan field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3163,6 +3262,15 @@ int ast_ari_validate_channel_dtmf_received(struct ast_json *json)
int has_duration_ms = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelDtmfReceived field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3272,6 +3380,15 @@ int ast_ari_validate_channel_entered_bridge(struct ast_json *json)
int has_bridge = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelEnteredBridge field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3360,6 +3477,15 @@ int ast_ari_validate_channel_hangup_request(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelHangupRequest field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3457,6 +3583,15 @@ int ast_ari_validate_channel_hold(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelHold field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3546,6 +3681,15 @@ int ast_ari_validate_channel_left_bridge(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelLeftBridge field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3640,6 +3784,15 @@ int ast_ari_validate_channel_state_change(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelStateChange field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3720,6 +3873,15 @@ int ast_ari_validate_channel_talking_finished(struct ast_json *json)
int has_duration = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelTalkingFinished field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3814,6 +3976,15 @@ int ast_ari_validate_channel_talking_started(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelTalkingStarted field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3893,6 +4064,15 @@ int ast_ari_validate_channel_unhold(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelUnhold field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -3973,6 +4153,15 @@ int ast_ari_validate_channel_userevent(struct ast_json *json)
int has_userevent = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelUserevent field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4095,6 +4284,15 @@ int ast_ari_validate_channel_varset(struct ast_json *json)
int has_variable = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ChannelVarset field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4278,6 +4476,15 @@ int ast_ari_validate_contact_status_change(struct ast_json *json)
int has_endpoint = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI ContactStatusChange field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4372,6 +4579,15 @@ int ast_ari_validate_device_state_changed(struct ast_json *json)
int has_device_state = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI DeviceStateChanged field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4452,6 +4668,15 @@ int ast_ari_validate_dial(struct ast_json *json)
int has_peer = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Dial field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4582,6 +4807,15 @@ int ast_ari_validate_endpoint_state_change(struct ast_json *json)
int has_endpoint = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI EndpointStateChange field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4784,6 +5018,15 @@ int ast_ari_validate_event(struct ast_json *json)
}
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Event field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -4976,6 +5219,15 @@ int ast_ari_validate_message(struct ast_json *json)
}
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI Message field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5015,6 +5267,15 @@ int ast_ari_validate_missing_params(struct ast_json *json)
int has_params = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI MissingParams field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5146,6 +5407,15 @@ int ast_ari_validate_peer_status_change(struct ast_json *json)
int has_peer = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI PeerStatusChange field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5240,6 +5510,15 @@ int ast_ari_validate_playback_continuing(struct ast_json *json)
int has_playback = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI PlaybackContinuing field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5319,6 +5598,15 @@ int ast_ari_validate_playback_finished(struct ast_json *json)
int has_playback = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI PlaybackFinished field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5398,6 +5686,15 @@ int ast_ari_validate_playback_started(struct ast_json *json)
int has_playback = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI PlaybackStarted field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5477,6 +5774,15 @@ int ast_ari_validate_recording_failed(struct ast_json *json)
int has_recording = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI RecordingFailed field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5556,6 +5862,15 @@ int ast_ari_validate_recording_finished(struct ast_json *json)
int has_recording = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI RecordingFinished field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5635,6 +5950,15 @@ int ast_ari_validate_recording_started(struct ast_json *json)
int has_recording = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI RecordingStarted field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5714,6 +6038,15 @@ int ast_ari_validate_stasis_end(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI StasisEnd field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5794,6 +6127,15 @@ int ast_ari_validate_stasis_start(struct ast_json *json)
int has_channel = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI StasisStart field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
@@ -5898,6 +6240,15 @@ int ast_ari_validate_text_message_received(struct ast_json *json)
int has_message = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("asterisk_id", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI TextMessageReceived field asterisk_id failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("type", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_type = 1;
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index 2634528ba..0b08ce85e 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -1486,10 +1486,12 @@ ari_validator ast_ari_validate_application_fn(void);
* - new_messages: int (required)
* - old_messages: int (required)
* ApplicationReplaced
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* BridgeAttendedTransfer
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1510,6 +1512,7 @@ ari_validator ast_ari_validate_application_fn(void);
* - transferer_second_leg: Channel (required)
* - transferer_second_leg_bridge: Bridge
* BridgeBlindTransfer
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1522,22 +1525,26 @@ ari_validator ast_ari_validate_application_fn(void);
* - result: string (required)
* - transferee: Channel
* BridgeCreated
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - bridge: Bridge (required)
* BridgeDestroyed
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - bridge: Bridge (required)
* BridgeMerged
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - bridge: Bridge (required)
* - bridge_from: Bridge (required)
* ChannelCallerId
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1545,16 +1552,19 @@ ari_validator ast_ari_validate_application_fn(void);
* - caller_presentation_txt: string (required)
* - channel: Channel (required)
* ChannelConnectedLine
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* ChannelCreated
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* ChannelDestroyed
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1562,6 +1572,7 @@ ari_validator ast_ari_validate_application_fn(void);
* - cause_txt: string (required)
* - channel: Channel (required)
* ChannelDialplan
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1569,6 +1580,7 @@ ari_validator ast_ari_validate_application_fn(void);
* - dialplan_app: string (required)
* - dialplan_app_data: string (required)
* ChannelDtmfReceived
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1576,12 +1588,14 @@ ari_validator ast_ari_validate_application_fn(void);
* - digit: string (required)
* - duration_ms: int (required)
* ChannelEnteredBridge
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - bridge: Bridge (required)
* - channel: Channel
* ChannelHangupRequest
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1589,39 +1603,46 @@ ari_validator ast_ari_validate_application_fn(void);
* - channel: Channel (required)
* - soft: boolean
* ChannelHold
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* - musicclass: string
* ChannelLeftBridge
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - bridge: Bridge (required)
* - channel: Channel (required)
* ChannelStateChange
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* ChannelTalkingFinished
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* - duration: int (required)
* ChannelTalkingStarted
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* ChannelUnhold
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* ChannelUserevent
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1631,6 +1652,7 @@ ari_validator ast_ari_validate_application_fn(void);
* - eventname: string (required)
* - userevent: object (required)
* ChannelVarset
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1643,17 +1665,20 @@ ari_validator ast_ari_validate_application_fn(void);
* - roundtrip_usec: string
* - uri: string (required)
* ContactStatusChange
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - contact_info: ContactInfo (required)
* - endpoint: Endpoint (required)
* DeviceStateChanged
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - device_state: DeviceState (required)
* Dial
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1664,17 +1689,21 @@ ari_validator ast_ari_validate_application_fn(void);
* - forwarded: Channel
* - peer: Channel (required)
* EndpointStateChange
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - endpoint: Endpoint (required)
* Event
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* Message
+ * - asterisk_id: string
* - type: string (required)
* MissingParams
+ * - asterisk_id: string
* - type: string (required)
* - params: List[string] (required)
* Peer
@@ -1684,47 +1713,56 @@ ari_validator ast_ari_validate_application_fn(void);
* - port: string
* - time: string
* PeerStatusChange
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - endpoint: Endpoint (required)
* - peer: Peer (required)
* PlaybackContinuing
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - playback: Playback (required)
* PlaybackFinished
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - playback: Playback (required)
* PlaybackStarted
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - playback: Playback (required)
* RecordingFailed
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - recording: LiveRecording (required)
* RecordingFinished
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - recording: LiveRecording (required)
* RecordingStarted
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - recording: LiveRecording (required)
* StasisEnd
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
* - channel: Channel (required)
* StasisStart
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
@@ -1732,6 +1770,7 @@ ari_validator ast_ari_validate_application_fn(void);
* - channel: Channel (required)
* - replace_channel: Channel
* TextMessageReceived
+ * - asterisk_id: string
* - type: string (required)
* - application: string (required)
* - timestamp: Date
diff --git a/res/res_calendar.c b/res/res_calendar.c
index 6f6f711b3..029ecebd0 100644
--- a/res/res_calendar.c
+++ b/res/res_calendar.c
@@ -436,6 +436,7 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c
cal->refresh = 3600;
cal->timeframe = 60;
cal->notify_waittime = 30000;
+ cal->fetch_again_at_reload = 0;
for (v = ast_variable_browse(cfg, cat); v; v = v->next) {
if (!strcasecmp(v->name, "autoreminder")) {
@@ -457,6 +458,8 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c
ast_string_field_set(cal, notify_appdata, v->value);
} else if (!strcasecmp(v->name, "refresh")) {
cal->refresh = atoi(v->value);
+ } else if (!strcasecmp(v->name, "fetch_again_at_reload")) {
+ cal->fetch_again_at_reload = ast_true(v->value);
} else if (!strcasecmp(v->name, "timeframe")) {
cal->timeframe = atoi(v->value);
} else if (!strcasecmp(v->name, "setvar")) {
@@ -482,7 +485,7 @@ static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *c
}
}
- if (new_calendar) {
+ if (new_calendar || cal->fetch_again_at_reload) {
cal->thread = AST_PTHREADT_NULL;
ast_cond_init(&cal->unload, NULL);
ao2_link(calendars, cal);
diff --git a/res/res_fax.c b/res/res_fax.c
index a2e179323..f602ba965 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -1415,11 +1415,13 @@ static int report_fax_status(struct ast_channel *chan, struct ast_fax_session_de
}
json_object = ast_json_pack("{s: s, s: s, s: s, s: s, s: o}",
- "type", "status",
- "operation", (details->caps & AST_FAX_TECH_GATEWAY) ? "gateway" : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
- "status", status,
- "local_station_id", details->localstationid,
- "filenames", json_filenames);
+ "type", "status",
+ "operation", (details->caps & AST_FAX_TECH_GATEWAY)
+ ? "gateway"
+ : (details->caps & AST_FAX_TECH_RECEIVE) ? "receive" : "send",
+ "status", status,
+ "local_station_id", AST_JSON_UTF8_VALIDATE(details->localstationid),
+ "filenames", json_filenames);
if (!json_object) {
return -1;
}
@@ -1600,6 +1602,13 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
chancount = 1;
+ /* Make sure one or the other is set to avoid race condition */
+ if (t38negotiated) {
+ details->caps |= AST_FAX_TECH_T38;
+ } else {
+ details->caps |= AST_FAX_TECH_AUDIO;
+ }
+
/* create the FAX session */
if (!(fax = fax_session_new(details, chan, reserved, token))) {
ast_log(LOG_ERROR, "Can't create a FAX session, FAX attempt failed.\n");
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index d6eea3ce0..520fd7602 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -4284,6 +4284,7 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
int reconstruct = ntohl(rtpheader[0]);
struct ast_sockaddr remote_address = { {0,} };
int ice;
+ unsigned int timestamp = ntohl(rtpheader[1]);
/* Get fields from packet */
payload = (reconstruct & 0x7f0000) >> 16;
@@ -4313,6 +4314,22 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
return -1;
}
+ /* If bridged peer is in dtmf, feed all packets to core until it finishes to avoid infinite dtmf */
+ if (bridged->sending_digit) {
+ ast_debug(1, "Feeding packets to core until DTMF finishes\n");
+ return -1;
+ }
+
+ /*
+ * Even if we are no longer in dtmf, we could still be receiving
+ * re-transmissions of the last dtmf end still. Feed those to the
+ * core so they can be filtered accordingly.
+ */
+ if (rtp->last_end_timestamp == timestamp) {
+ ast_debug(1, "Feeding packet with duplicate timestamp to core\n");
+ return -1;
+ }
+
/* If the marker bit has been explicitly set turn it on */
if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
mark = 1;
diff --git a/res/stasis/app.c b/res/stasis/app.c
index 6e5a396be..8bd1bc05a 100644
--- a/res/stasis/app.c
+++ b/res/stasis/app.c
@@ -455,7 +455,7 @@ static struct ast_json *channel_dialplan(
"type", "ChannelDialplan",
"timestamp", ast_json_timeval(*tv, NULL),
"dialplan_app", new_snapshot->appl,
- "dialplan_app_data", new_snapshot->data,
+ "dialplan_app_data", AST_JSON_UTF8_VALIDATE(new_snapshot->data),
"channel", json_channel);
}
@@ -929,8 +929,15 @@ struct stasis_topic *ast_app_get_topic(struct stasis_app *app)
void app_send(struct stasis_app *app, struct ast_json *message)
{
stasis_app_cb handler;
+ char eid[20];
RAII_VAR(void *, data, NULL, ao2_cleanup);
+ if (ast_json_object_set(message, "asterisk_id", ast_json_string_create(
+ ast_eid_to_str(eid, sizeof(eid), &ast_eid_default)))) {
+ ast_log(AST_LOG_WARNING, "Failed to append EID to outgoing event %s\n",
+ ast_json_string_get(ast_json_object_get(message, "type")));
+ }
+
/* Copy off mutable state with lock held */
{
SCOPED_AO2LOCK(lock, app);
diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json
index ca2616101..4ef1d21a4 100644
--- a/rest-api/api-docs/events.json
+++ b/rest-api/api-docs/events.json
@@ -110,6 +110,11 @@
"type": "string",
"required": true,
"description": "Indicates the type of this message."
+ },
+ "asterisk_id": {
+ "type": "string",
+ "required": false,
+ "description": "The unique ID for the Asterisk instance that raised this event."
}
},
"subTypes": [
diff --git a/tests/test_json.c b/tests/test_json.c
index 915578128..7362a6127 100644
--- a/tests/test_json.c
+++ b/tests/test_json.c
@@ -1598,11 +1598,26 @@ AST_TEST_DEFINE(json_test_clever_circle)
return AST_TEST_PASS;
}
-AST_TEST_DEFINE(json_test_name_number)
+static int test_name_number(const char *name, const char *number)
{
- RAII_VAR(struct ast_json *, uut, NULL, ast_json_unref);
- RAII_VAR(struct ast_json *, expected, NULL, ast_json_unref);
+ int res;
+ struct ast_json *uut;
+ struct ast_json *expected;
+
+ expected = ast_json_pack("{s: s, s: s}",
+ "name", name ?: "",
+ "number", number ?: "");
+ uut = ast_json_name_number(name, number);
+
+ res = ast_json_equal(expected, uut);
+ ast_json_unref(expected);
+ ast_json_unref(uut);
+ return res;
+}
+
+AST_TEST_DEFINE(json_test_name_number)
+{
switch (cmd) {
case TEST_INIT:
info->name = "name_number";
@@ -1614,15 +1629,10 @@ AST_TEST_DEFINE(json_test_name_number)
break;
}
- ast_test_validate(test, NULL == ast_json_name_number("name", NULL));
- ast_test_validate(test, NULL == ast_json_name_number(NULL, "1234"));
- ast_test_validate(test, NULL == ast_json_name_number(NULL, NULL));
-
- expected = ast_json_pack("{s: s, s: s}",
- "name", "Jenny",
- "number", "867-5309");
- uut = ast_json_name_number("Jenny", "867-5309");
- ast_test_validate(test, ast_json_equal(expected, uut));
+ ast_test_validate(test, test_name_number("name", NULL));
+ ast_test_validate(test, test_name_number(NULL, "1234"));
+ ast_test_validate(test, test_name_number(NULL, NULL));
+ ast_test_validate(test, test_name_number("Jenny", "867-5309"));
return AST_TEST_PASS;
}
diff --git a/tests/test_res_stasis.c b/tests/test_res_stasis.c
index 4e28d44c6..459890373 100644
--- a/tests/test_res_stasis.c
+++ b/tests/test_res_stasis.c
@@ -138,6 +138,7 @@ AST_TEST_DEFINE(app_replaced)
RAII_VAR(struct ast_json *, expected_message1, NULL, ast_json_unref);
RAII_VAR(struct ast_json *, message, NULL, ast_json_unref);
RAII_VAR(struct ast_json *, expected_message2, NULL, ast_json_unref);
+ char eid[20];
int res;
switch (cmd) {
@@ -158,9 +159,10 @@ AST_TEST_DEFINE(app_replaced)
stasis_app_register(app_name, test_handler, app_data1);
stasis_app_register(app_name, test_handler, app_data2);
- expected_message1 = ast_json_pack("[{s: s, s: s}]",
+ expected_message1 = ast_json_pack("[{s: s, s: s, s: s}]",
"type", "ApplicationReplaced",
- "application", app_name);
+ "application", app_name,
+ "asterisk_id", ast_eid_to_str(eid, sizeof(eid), &ast_eid_default));
message = ast_json_pack("{ s: o }", "test-message", ast_json_null());
expected_message2 = ast_json_pack("[o]", ast_json_ref(message));
diff --git a/third-party/Makefile.rules b/third-party/Makefile.rules
index 92e4ebc85..4f804dd0e 100644
--- a/third-party/Makefile.rules
+++ b/third-party/Makefile.rules
@@ -13,18 +13,6 @@ QUIET_CONFIGURE=
REALLY_QUIET=
endif
-DOWNLOAD := $(shell which wget 2>/dev/null)
-DOWNLOAD := $(if $(DOWNLOAD),$(DOWNLOAD) -O- ,)
-
-ifeq ($(DOWNLOAD),)
-DOWNLOAD := $(shell which curl 2>/dev/null)
-DOWNLOAD := $(if $(DOWNLOAD), $(DOWNLOAD) -L ,)
-endif
-
-ifeq ($(DOWNLOAD),)
-DOWNLOAD := echo "No download program available" ; exit 1;
-endif
-
export SUBMAKE
export ECHO_PREFIX
export CMD_PREFIX
@@ -34,3 +22,8 @@ export ASTTOPDIR
export ASTSBINDIR
export DESTDIR
export ASTDATADIR
+export TAR
+export PATCH
+export SED
+export NM
+export DOWNLOAD
diff --git a/third-party/configure.m4 b/third-party/configure.m4
new file mode 100644
index 000000000..635446638
--- /dev/null
+++ b/third-party/configure.m4
@@ -0,0 +1,7 @@
+
+
+AC_DEFUN([THIRD_PARTY_CONFIGURE],
+[
+ PJPROJECT_CONFIGURE()
+])
+
diff --git a/third-party/pjproject/Makefile b/third-party/pjproject/Makefile
index bb98a09e3..65875224f 100644
--- a/third-party/pjproject/Makefile
+++ b/third-party/pjproject/Makefile
@@ -7,8 +7,6 @@ SPECIAL_TARGETS :=
ifneq ($(findstring configure,$(MAKECMDGOALS))$(findstring echo_cflags,$(MAKECMDGOALS)),)
# Run from $(ASTTOPDIR)/configure
SPECIAL_TARGETS += configure
- include ../Makefile.rules
- include Makefile.rules
endif
ifeq ($(findstring echo_cflags,$(MAKECMDGOALS)),echo_cflags)
@@ -19,8 +17,10 @@ endif
ifeq ($(findstring clean,$(MAKECMDGOALS)),clean)
# clean or distclean
SPECIAL_TARGETS += clean
- include ../Makefile.rules
- include Makefile.rules
+endif
+
+ifneq ($(wildcard ../../makeopts),)
+ include ../../makeopts
endif
ifeq ($(SPECIAL_TARGETS),)
@@ -28,17 +28,17 @@ ifeq ($(SPECIAL_TARGETS),)
ifeq ($(wildcard ../../makeopts),)
$(error ASTTOPDIR/configure hasn't been run)
endif
- include ../../makeopts
ifeq ($(PJPROJECT_BUNDLED),yes)
- -include ../../menuselect.makeopts
- include ../Makefile.rules
+ ifneq ($(wildcard ../../menuselect.makeopts),)
+ include ../../menuselect.makeopts
+ else
+ $(warning ASTTOPDIR/menuselect hasn't been run yet. Can't find debug options.)
+ endif
all: _all
install: _install
- include ../../Makefile.rules
- include Makefile.rules
include source/user.mak
include source/build.mak
CF := $(filter-out -W%,$(CC_CFLAGS))
@@ -66,25 +66,25 @@ ifeq ($(SPECIAL_TARGETS),)
endif
endif
+include ../../Makefile.rules
+include ../Makefile.rules
+include Makefile.rules
+
ECHO_PREFIX := $(ECHO_PREFIX) echo '[pjproject] '
-ifndef $(TMPDIR)
- ifneq ($(wildcard /tmp),)
- TMPDIR=/tmp
- else
- TMPDIR=.
- endif
-endif
+_all: $(TARGETS)
+
+EXTERNALS_CACHE_DIR ?= $(or $(TMPDIR),$(wildcard /tmp),.)
-$(TMPDIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 : ../versions.mak
- $(ECHO_PREFIX) Downloading $@ with $(DOWNLOAD)
- $(CMD_PREFIX) $(DOWNLOAD) $(PJPROJECT_URL)/$(@F) > $@
+$(EXTERNALS_CACHE_DIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2 : ../versions.mak
+ $(ECHO_PREFIX) Downloading $(PJPROJECT_URL)/$(@F) to $@
+ $(CMD_PREFIX) $(DOWNLOAD_TO_STDOUT) $(PJPROJECT_URL)/$(@F) > $@
-source/.unpacked: $(TMPDIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2
+source/.unpacked: $(EXTERNALS_CACHE_DIR)/pjproject-$(PJPROJECT_VERSION).tar.bz2
$(ECHO_PREFIX) Unpacking $<
-@rm -rf source >/dev/null 2>&1
-@mkdir source >/dev/null 2>&1
- $(CMD_PREFIX) tar --strip-components=1 -C source -xjf $<
+ $(CMD_PREFIX) $(TAR) --strip-components=1 -C source -xjf $<
$(ECHO_PREFIX) Applying patches
$(CMD_PREFIX) ./apply_patches $(QUIET_CONFIGURE) ./patches ./source
-@touch source/.unpacked
@@ -99,8 +99,8 @@ source/pjlib/include/pj/%.h : ./patches/%.h
build.mak: source/.unpacked $(addprefix source/pjlib/include/pj/,$(notdir $(wildcard ./patches/*.h))) source/user.mak Makefile.rules
$(ECHO_PREFIX) Configuring with $(PJPROJECT_CONFIG_OPTS)
- $(CMD_PREFIX) (cd source ; autoconf aconfigure.ac > aconfigure && ./aconfigure $(QUIET_CONFIGURE) $(PJPROJECT_CONFIG_OPTS))
- @sed -r -e "/prefix|export PJ_SHARED_LIBRARIES|MACHINE_NAME|OS_NAME|HOST_NAME|CC_NAME|CROSS_COMPILE|LINUX_POLL/d" source/build.mak > build.mak
+ $(CMD_PREFIX) (cd source ; ./aconfigure $(QUIET_CONFIGURE) $(PJPROJECT_CONFIG_OPTS))
+ $(SED) -r -e "/prefix|export PJ_SHARED_LIBRARIES|MACHINE_NAME|OS_NAME|HOST_NAME|CC_NAME|CROSS_COMPILE|LINUX_POLL/d" source/build.mak > build.mak
configure: build.mak
@@ -128,7 +128,7 @@ $(LIB_FILES): $(PJLIB_UTIL_LIB_FILES)
pjproject.symbols: $(ALL_LIB_FILES)
$(ECHO_PREFIX) Generating symbols
- $(CMD_PREFIX) nm -Pog $(ALL_LIB_FILES) | sed -n -r -e "s/.+: ([pP][jJ][^ ]+) .+/\1/gp" | sort -u > pjproject.symbols
+ $(CMD_PREFIX) $(NM) -Pog $(PJ_LIB_FILES) | $(SED) -n -r -e "s/.+: ([pP][jJ][^ ]+) .+/\1/gp" | sort -u > pjproject.symbols
source/pjsip-apps/src/asterisk_malloc_debug.c: patches/asterisk_malloc_debug.c
$(ECHO_PREFIX) Copying $< to $@
@@ -155,8 +155,6 @@ source/pjsip-apps/src/python/_pjsua.so: source/pjsip-apps/src/python/_pjsua.o
$(ECHO_PREFIX) Linking python bindings $(@F)
$(CMD_PREFIX) gcc -shared -pthread -o $@ $< $(LDFLAGS) $(PJ_LDFLAGS) $(APP_LDLIBS) $(PYTHONDEV_LIB) $(REALLY_QUIET)
-_all: $(TARGETS)
-
_install: _all
@if [ ! -d "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject" ]; then \
$(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/third-party/pjproject"; \
@@ -188,4 +186,3 @@ clean:
distclean:
$(ECHO_PREFIX) Distcleaning
-$(CMD_PREFIX) rm -rf source pjproject.symbols pjproject-*.tar.bz2 build.mak .rebuild_needed
-
diff --git a/third-party/pjproject/apply_patches b/third-party/pjproject/apply_patches
index 5dfdd2a3c..c28f40301 100755
--- a/third-party/pjproject/apply_patches
+++ b/third-party/pjproject/apply_patches
@@ -5,6 +5,8 @@ if [ "$1" = "-q" ] ; then
shift
fi
+PATCH=${PATCH:-patch}
+
patchdir=${1:?You must supply a patches directory}
sourcedir=${2?:You must supply a source directory}
@@ -27,12 +29,12 @@ if [ ! "$(ls -A $patchdir/*.patch 2>/dev/null)" ] ; then
fi
for patchfile in $patchdir/*.patch ; do
- patch -d $sourcedir -p1 -s -r- -f -N --dry-run -i "$patchfile" || (echo "Patchfile $(basename $patchfile) failed to apply" >&2 ; exit 1) || exit 1
+ ${PATCH} -d $sourcedir -p1 -s -r- -f -N --dry-run -i "$patchfile" || (echo "Patchfile $(basename $patchfile) failed to apply" >&2 ; exit 1) || exit 1
done
for patchfile in "$patchdir"/*.patch ; do
[ -z $quiet ] && echo "Applying patch $(basename $patchfile)"
- patch -d "$sourcedir" -p1 -s -i "$patchfile" || exit 1
+ ${PATCH} -d "$sourcedir" -p1 -s -i "$patchfile" || exit 1
done
exit 0
diff --git a/third-party/pjproject/configure.m4 b/third-party/pjproject/configure.m4
index 7a079f657..7b62c0f16 100644
--- a/third-party/pjproject/configure.m4
+++ b/third-party/pjproject/configure.m4
@@ -1,49 +1,72 @@
-AC_DEFUN([PJPROJECT_SYMBOL_CHECK],
+AC_DEFUN([_PJPROJECT_CONFIGURE],
[
- $1_INCLUDE="$PJPROJECT_INCLUDE"
- AC_MSG_CHECKING([for $2 declared in $3])
-
- saved_cpp="$CPPFLAGS"
- CPPFLAGS="$PJPROJECT_INCLUDE"
- AC_EGREP_HEADER($2, $3, [
- AC_MSG_RESULT(yes)
- PBX_$1=1
- AC_DEFINE([HAVE_$1], 1, [Define if your system has $2 declared.])
- ], [
- AC_MSG_RESULT(no)
- ])
-
- CPPGLAGS="$saved_cpp"
- $1_INCLUDE="$PJPROJECT_INCLUDE"
-])
+ if test "${ac_mandatory_list#*PJPROJECT*}" != "$ac_mandatory_list" ; then
+ AC_MSG_ERROR(--with-pjproject and --with-pjproject-bundled can't both be specified)
+ fi
+
+ ac_mandatory_list="$ac_mandatory_list PJPROJECT"
+ PJPROJECT_DIR="${ac_top_build_prefix}third-party/pjproject"
-AC_DEFUN([PJPROJECT_CONFIGURE],
-[
AC_MSG_CHECKING(for embedded pjproject (may have to download))
AC_MSG_RESULT(configuring)
- ${GNU_MAKE} --quiet --no-print-directory -C $1 configure
+
+ if test "x${DOWNLOAD_TO_STDOUT}" = "x" ; then
+ AC_MSG_ERROR(A download utility (wget, curl or fetch) is required to download bundled pjproject)
+ fi
+ if test "${BZIP2}" = ":" ; then
+ AC_MSG_ERROR(bzip2 is required to extract the pjproject tar file)
+ fi
+ if test "${TAR}" = ":" ; then
+ AC_MSG_ERROR(tar is required to extract the pjproject tar file)
+ fi
+ if test "${PATCH}" = ":" ; then
+ AC_MSG_ERROR(patch is required to configure bundled pjproject)
+ fi
+ if test "${SED}" = ":" ; then
+ AC_MSG_ERROR(sed is required to configure bundled pjproject)
+ fi
+ if test "${NM}" = ":" ; then
+ AC_MSG_ERROR(nm is required to build bundled pjproject)
+ fi
+
+ export TAR PATCH SED NM EXTERNALS_CACHE_DIR DOWNLOAD_TO_STDOUT
+ ${GNU_MAKE} --quiet --no-print-directory -C ${PJPROJECT_DIR} configure
if test $? -ne 0 ; then
AC_MSG_RESULT(failed)
- AC_MSG_NOTICE(Unable to configure $1)
- AC_MSG_ERROR(Run "${GNU_MAKE} -C $1 NOISY_BUILD=yes configure" to see error details.)
+ AC_MSG_NOTICE(Unable to configure ${PJPROJECT_DIR})
+ AC_MSG_ERROR(Run "${GNU_MAKE} -C ${PJPROJECT_DIR} NOISY_BUILD=yes configure" to see error details.)
fi
- PJPROJECT_INCLUDE=$(${GNU_MAKE} --quiet --no-print-directory -C $1 echo_cflags)
+ AC_MSG_CHECKING(for bundled pjproject)
+
+ PJPROJECT_INCLUDE=$(${GNU_MAKE} --quiet --no-print-directory -C ${PJPROJECT_DIR} echo_cflags)
PJPROJECT_CFLAGS="$PJPROJECT_INCLUDE"
PBX_PJPROJECT=1
- PJPROJECT_BUNDLED=yes
+
AC_DEFINE([HAVE_PJPROJECT], 1, [Define if your system has PJPROJECT])
AC_DEFINE([HAVE_PJPROJECT_BUNDLED], 1, [Define if your system has PJPROJECT_BUNDLED])
- AC_MSG_CHECKING(for embedded pjproject)
- AC_MSG_RESULT(yes)
- PJPROJECT_SYMBOL_CHECK([PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], [pjsip_dlg_create_uas_and_inc_lock], [pjsip.h])
- PJPROJECT_SYMBOL_CHECK([PJ_TRANSACTION_GRP_LOCK], [pjsip_tsx_create_uac2], [pjsip.h])
- PJPROJECT_SYMBOL_CHECK([PJSIP_REPLACE_MEDIA_STREAM], [PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE], [pjmedia.h])
- PJPROJECT_SYMBOL_CHECK([PJSIP_GET_DEST_INFO], [pjsip_get_dest_info], [pjsip.h])
- PJPROJECT_SYMBOL_CHECK([PJ_SSL_CERT_LOAD_FROM_FILES2], [pj_ssl_cert_load_from_files2], [pjlib.h])
- PJPROJECT_SYMBOL_CHECK([PJSIP_EXTERNAL_RESOLVER], [pjsip_endpt_set_ext_resolver], [pjsip.h])
+ AC_DEFINE([HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK], 1, [Define if your system has pjsip_dlg_create_uas_and_inc_lock declared.])
+ AC_DEFINE([HAVE_PJ_TRANSACTION_GRP_LOCK], 1, [Define if your system has pjsip_tsx_create_uac2 declared.])
+ AC_DEFINE([HAVE_PJSIP_REPLACE_MEDIA_STREAM], 1, [Define if your system has PJSIP_REPLACE_MEDIA_STREAM declared])
+ AC_DEFINE([HAVE_PJSIP_GET_DEST_INFO], 1, [Define if your system has pjsip_get_dest_info declared.])
+ AC_DEFINE([HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2], 1, [Define if your system has pj_ssl_cert_load_from_files2 declared.])
+ AC_DEFINE([HAVE_PJSIP_EXTERNAL_RESOLVER], 1, [Define if your system has pjsip_endpt_set_ext_resolver declared.])
AC_DEFINE([HAVE_PJSIP_TLS_TRANSPORT_PROTO], 1, [Define if your system has PJSIP_TLS_TRANSPORT_PROTO])
AC_DEFINE([HAVE_PJSIP_EVSUB_GRP_LOCK], 1, [Define if your system has PJSIP_EVSUB_GRP_LOCK])
AC_DEFINE([HAVE_PJSIP_INV_SESSION_REF], 1, [Define if your system has PJSIP_INV_SESSION_REF])
+
+ AC_SUBST([PJPROJECT_BUNDLED])
+ AC_SUBST([PJPROJECT_DIR])
+ AC_SUBST([PBX_PJPROJECT])
+ AC_SUBST([PJPROJECT_LIB])
+ AC_SUBST([PJPROJECT_INCLUDE])
+ AC_MSG_RESULT(yes)
+])
+
+AC_DEFUN([PJPROJECT_CONFIGURE],
+[
+ if test "$PJPROJECT_BUNDLED" = "yes" ; then
+ _PJPROJECT_CONFIGURE()
+ fi
])
diff --git a/third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch b/third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch
new file mode 100644
index 000000000..551e61ab6
--- /dev/null
+++ b/third-party/pjproject/patches/0005-Re-1969-Fix-crash-on-using-an-already-destroyed-SSL-.patch
@@ -0,0 +1,164 @@
+From 9e67e0d5c3fdc747530a956038b374fca4748b76 Mon Sep 17 00:00:00 2001
+From: riza <riza@localhost>
+Date: Thu, 13 Oct 2016 09:02:50 +0000
+Subject: [PATCH 1/4] Re #1969: Fix crash on using an already destroyed SSL
+ socket.
+
+---
+ pjlib/src/pj/ssl_sock_ossl.c | 66 ++++++++++++++++++++++++++++----------------
+ 1 file changed, 42 insertions(+), 24 deletions(-)
+
+diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
+index fa0db2d..ceab67a 100644
+--- a/pjlib/src/pj/ssl_sock_ossl.c
++++ b/pjlib/src/pj/ssl_sock_ossl.c
+@@ -822,7 +822,10 @@ static void close_sockets(pj_ssl_sock_t *ssock)
+ pj_lock_acquire(ssock->write_mutex);
+ asock = ssock->asock;
+ if (asock) {
+- ssock->asock = NULL;
++ // Don't set ssock->asock to NULL, as it may trigger assertion in
++ // send operation. This should be safe as active socket will simply
++ // return PJ_EINVALIDOP on any operation if it is already closed.
++ //ssock->asock = NULL;
+ ssock->sock = PJ_INVALID_SOCKET;
+ }
+ sock = ssock->sock;
+@@ -841,9 +844,9 @@ static void close_sockets(pj_ssl_sock_t *ssock)
+ /* Reset SSL socket state */
+ static void reset_ssl_sock_state(pj_ssl_sock_t *ssock)
+ {
++ pj_lock_acquire(ssock->write_mutex);
+ ssock->ssl_state = SSL_STATE_NULL;
+-
+- destroy_ssl(ssock);
++ pj_lock_release(ssock->write_mutex);
+
+ close_sockets(ssock);
+
+@@ -1612,6 +1615,21 @@ static pj_status_t do_handshake(pj_ssl_sock_t *ssock)
+ return PJ_EPENDING;
+ }
+
++static void ssl_on_destroy(void *arg)
++{
++ pj_pool_t *pool = NULL;
++ pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)arg;
++
++ destroy_ssl(ssock);
++
++ pj_lock_destroy(ssock->write_mutex);
++
++ pool = ssock->pool;
++ ssock->pool = NULL;
++ if (pool)
++ pj_pool_release(pool);
++}
++
+
+ /*
+ *******************************************************************
+@@ -1830,7 +1848,7 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
+
+ /* Create new SSL socket instance */
+ status = pj_ssl_sock_create(ssock_parent->pool,
+- &ssock_parent->newsock_param, &ssock);
++ &ssock_parent->newsock_param, &ssock);
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+@@ -1906,12 +1924,10 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+- /* Temporarily add ref the group lock until active socket creation,
+- * to make sure that group lock is destroyed if the active socket
+- * creation fails.
+- */
+ pj_grp_lock_add_ref(glock);
+ asock_cfg.grp_lock = ssock->param.grp_lock = glock;
++ pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock,
++ ssl_on_destroy);
+ }
+
+ pj_bzero(&asock_cb, sizeof(asock_cb));
+@@ -1927,11 +1943,6 @@ static pj_bool_t asock_on_accept_complete (pj_activesock_t *asock,
+ ssock,
+ &ssock->asock);
+
+- /* This will destroy the group lock if active socket creation fails */
+- if (asock_cfg.grp_lock) {
+- pj_grp_lock_dec_ref(asock_cfg.grp_lock);
+- }
+-
+ if (status != PJ_SUCCESS)
+ goto on_return;
+
+@@ -2251,17 +2262,26 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
+ /* Create secure socket mutex */
+ status = pj_lock_create_recursive_mutex(pool, pool->obj_name,
+ &ssock->write_mutex);
+- if (status != PJ_SUCCESS)
++ if (status != PJ_SUCCESS) {
++ pj_pool_release(pool);
+ return status;
++ }
+
+ /* Init secure socket param */
+ pj_ssl_sock_param_copy(pool, &ssock->param, param);
++
++ if (ssock->param.grp_lock) {
++ pj_grp_lock_add_ref(ssock->param.grp_lock);
++ pj_grp_lock_add_handler(ssock->param.grp_lock, pool, ssock,
++ ssl_on_destroy);
++ }
++
+ ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3;
+ if (!ssock->param.timer_heap) {
+ PJ_LOG(3,(ssock->pool->obj_name, "Warning: timer heap is not "
+ "available. It is recommended to supply one to avoid "
+- "a race condition if more than one worker threads "
+- "are used."));
++ "a race condition if more than one worker threads "
++ "are used."));
+ }
+
+ /* Finally */
+@@ -2277,8 +2297,6 @@ PJ_DEF(pj_status_t) pj_ssl_sock_create (pj_pool_t *pool,
+ */
+ PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
+ {
+- pj_pool_t *pool;
+-
+ PJ_ASSERT_RETURN(ssock, PJ_EINVAL);
+
+ if (!ssock->pool)
+@@ -2290,12 +2308,11 @@ PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock)
+ }
+
+ reset_ssl_sock_state(ssock);
+- pj_lock_destroy(ssock->write_mutex);
+-
+- pool = ssock->pool;
+- ssock->pool = NULL;
+- if (pool)
+- pj_pool_release(pool);
++ if (ssock->param.grp_lock) {
++ pj_grp_lock_dec_ref(ssock->param.grp_lock);
++ } else {
++ ssl_on_destroy(ssock);
++ }
+
+ return PJ_SUCCESS;
+ }
+@@ -2782,6 +2799,7 @@ pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock,
+
+ /* Start accepting */
+ pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param);
++ ssock->newsock_param.grp_lock = NULL;
+ status = pj_activesock_start_accept(ssock->asock, pool);
+ if (status != PJ_SUCCESS)
+ goto on_error;
+--
+2.7.4
+