Merge branch 'master' into v1.10

This commit is contained in:
Andrey Volk 2019-08-20 20:54:04 +04:00
commit f9990221e6
18 changed files with 345 additions and 90 deletions

View File

@ -1 +1 @@
1.10.0-release
1.10.1-release

View File

@ -3,10 +3,10 @@
# Must change all of the below together
# For a release, set revision for that tagged release as well and uncomment
AC_INIT([freeswitch], [1.10.0-release], bugs@freeswitch.org)
AC_INIT([freeswitch], [1.10.1-release], bugs@freeswitch.org)
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
AC_SUBST(SWITCH_VERSION_MINOR, [10])
AC_SUBST(SWITCH_VERSION_MICRO, [0-release])
AC_SUBST(SWITCH_VERSION_MICRO, [1-release])
AC_SUBST(SWITCH_VERSION_REVISION, [])
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])

View File

@ -1 +1 @@
Wed Jul 17 14:35:37 EDT 2019
Mon Aug 19 16:25:57 CDT 2019

View File

@ -2797,3 +2797,118 @@ char const *sip_via_port(sip_via_t const *v, int *using_rport)
else
return SIP_DEFAULT_SERV; /* 5060 */
}
/**@SIP_HEADER sip_identity Identity Header
*
* The Identity header field specifies the "logical" recipient of the
* request. It is defined in @RFC8224 with semantics shown below,
* though for now it's parsed to a single 'value' field.
*
* @code
* Identity = "Identity" HCOLON signed-identity-digest SEMI
* ident-info *( SEMI ident-info-params )
* signed-identity-digest = 1*(base64-char / ".")
* ident-info = "info" EQUAL ident-info-uri
* ident-info-uri = LAQUOT absoluteURI RAQUOT
* ident-info-params = ident-info-alg / ident-type /
* ident-info-extension
* ident-info-alg = "alg" EQUAL token
* ident-type = "ppt" EQUAL token
* ident-info-extension = generic-param
*
* base64-char = ALPHA / DIGIT / "/" / "+"
* @endcode
*
* The parsed Identity header is stored in #sip_identity_t structure.
*/
/**@ingroup sip_identity
* @typedef typedef struct sip_identity_s sip_identity_t;
*
* The structure #sip_identity_t contains representation of @Identity header.
*
* The #sip_identity_t is defined as follows:
* @code
* typedef struct {
* sip_common_t id_common[1]; // Common fragment info
* sip_error_t *id_next; // Link to next (dummy)
* char const *id_value; // Identity
* char const *id_info; // Info param containing URL of the cert, with no '<','>'
* } sip_identity_t;
* @endcode
*
*/
static msg_xtra_f sip_identity_dup_xtra;
static msg_dup_f sip_identity_dup_one;
static msg_update_f sip_identity_update;
msg_hclass_t sip_identity_class[] =
SIP_HEADER_CLASS(identity, "Identity", "", id_common, single, identity);
issize_t sip_identity_d(su_home_t *home, sip_header_t *h, char *s, isize_t slen)
{
sip_identity_t *id = (sip_identity_t *)h;
char const *p = NULL, *pp = NULL, *ppp = NULL, *ie = NULL;
char *result = NULL;
size_t len = 0;
id->id_value = strdup(s);
id->id_info = NULL;
p = strstr(s, "info=");
if (p) {
ie = strchr(p, ';');
pp = strchr(p, '<');
ppp = strchr(p, '>');
// allow for a spaces between "info=" and opening '<'
// extract URI from inside "<>" but allow empty - let the higher level app decide what to do about it
if (ie && pp && ppp && (pp < ppp) && (ppp < ie)) {
len = ppp - pp;
if ((result = malloc(len))) {
memcpy(result, pp + 1, len - 1);
result[len - 1] = '\0';
id->id_info = result;
}
}
}
return 0;
}
issize_t sip_identity_e(char b[], isize_t bsiz, sip_header_t const *h, int flags)
{
sip_identity_t const *id = (sip_identity_t *)h;
return snprintf(b, bsiz, "%s", id->id_value);
}
isize_t sip_identity_dup_xtra(sip_header_t const *h, isize_t offset)
{
sip_identity_t const *id = (sip_identity_t *)h;
return offset + MSG_STRING_SIZE(id->id_value);
}
char *sip_identity_dup_one(sip_header_t *dst, sip_header_t const *src,
char *b, isize_t xtra)
{
sip_identity_t *id = (sip_identity_t *)dst;
sip_identity_t const *o = (sip_identity_t *)src;
MSG_STRING_DUP(b, id->id_value, o->id_value);
return b;
}
static int sip_identity_update(msg_common_t *h,
char const *name, isize_t namelen,
char const *value)
{
sip_identity_t *id = (sip_identity_t *)h;
id->id_value = strdup(value);
return 0;
}

View File

@ -64,6 +64,7 @@ char const sip_version_2_0[] = "SIP/2.0";
extern msg_mclass_t sip_mclass[];
static msg_mclass_t const *_default = sip_mclass;
static msg_mclass_t *_default_parser_cloned = NULL;
/** Return a built-in SIP parser object. */
msg_mclass_t const *sip_default_mclass(void)
@ -71,6 +72,15 @@ msg_mclass_t const *sip_default_mclass(void)
return _default;
}
/** Release SIP parser object if it was cloned. */
void sip_cloned_parser_destroy(void)
{
if (_default_parser_cloned) {
free(_default_parser_cloned);
_default_parser_cloned = NULL;
}
}
/** Update the default SIP parser.
*
* Use the extended SIP parser as default one.
@ -128,10 +138,12 @@ msg_mclass_t *sip_extend_mclass(msg_mclass_t *input)
{
msg_mclass_t *mclass;
if (input == NULL || input == _default)
mclass = msg_mclass_clone(_default, 0, 0);
else
if (input == NULL || input == _default) {
_default_parser_cloned = msg_mclass_clone(_default, 0, 0);
mclass = _default_parser_cloned;
} else {
mclass = input;
}
if (mclass) {
extern msg_hclass_t * const sip_extensions[];
@ -143,8 +155,10 @@ msg_mclass_t *sip_extend_mclass(msg_mclass_t *input)
continue;
if (msg_mclass_insert_header(mclass, hclass, 0) < 0) {
if (input != mclass)
if (input != mclass) {
free(mclass);
_default_parser_cloned = NULL;
}
return mclass = NULL;
}
}

View File

@ -215,6 +215,9 @@ typedef msg_list_t sip_allow_events_t;
/* RFC 3323 - @Privacy */
typedef struct sip_privacy_s sip_privacy_t;
/* SIP Identity Header, e.g. STIR-Shaken SIP Identity Header, RFC 8224 */
typedef struct sip_identity_s sip_identity_t;
/* RFC 3327 - @Path */
typedef struct sip_route_s sip_path_t;
@ -259,6 +262,7 @@ struct sip_s {
sip_to_t *sip_to; /**< To (t) */
sip_call_id_t *sip_call_id; /**< Call-ID (i) */
sip_cseq_t *sip_cseq; /**< CSeq */
sip_identity_t *sip_identity; /**< Identity */
sip_contact_t *sip_contact; /**< Contact (m) */
sip_rseq_t *sip_rseq; /**< RSeq */
sip_rack_t *sip_rack; /**< RAck */
@ -474,6 +478,17 @@ struct sip_cseq_s
char const *cs_method_name; /**< Method name */
};
/**@ingroup sip_identity
* @brief Structure for @Identity SIP header.
*/
struct sip_identity_s
{
sip_common_t id_common[1]; /**< Common fragment info */
sip_error_t *id_next; /**< Link to next (dummy) */
char const *id_value; /**< Identity text as shown in SIP Header */
char const *id_info; /**< Info param containing URL of the cert */
};
/**@ingroup sip_contact
* @brief Structure for @Contact header field.
*/
@ -920,6 +935,7 @@ union sip_header_u
sip_separator_t sh_separator[1];
sip_payload_t sh_payload[1];
sip_identity_t sh_identity[1];
};
SOFIA_END_DECLS

View File

@ -60,6 +60,9 @@ SOFIA_BEGIN_DECLS
/** Return a built-in SIP parser object. */
SOFIAPUBFUN msg_mclass_t const *sip_default_mclass(void);
/** Release SIP parser object if it was cloned. */
SOFIAPUBFUN void sip_cloned_parser_destroy(void);
SOFIAPUBFUN int sip_update_default_mclass(msg_mclass_t const *mclass);
SOFIAPUBFUN msg_mclass_t *sip_extend_mclass(msg_mclass_t *input);
@ -224,6 +227,10 @@ SOFIAPUBFUN sip_call_id_t *sip_call_id_create(su_home_t *home,
SOFIAPUBFUN sip_cseq_t *sip_cseq_create(su_home_t *, uint32_t seq,
unsigned method, char const *name);
/** Create a @Identity header object. */
SOFIAPUBFUN sip_identity_t *sip_identity_create(su_home_t *, uint32_t seq,
unsigned method, char const *name);
/** Create a @Contact header object. */
SOFIAPUBFUN sip_contact_t * sip_contact_create(su_home_t *,
url_string_t const *url,

View File

@ -26,6 +26,7 @@
* Marc Olivier Chouinard <mochouinard@moctel.com>
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
* Ítalo Rossi <italorossib@gmail.com>
* Fernando Santos <fernando@nextbilling.com.br>
*
* mod_callcenter.c -- Call Center Module
*
@ -185,7 +186,7 @@ typedef enum {
static char members_sql[] =
"CREATE TABLE members (\n"
" queue VARCHAR(255),\n"
" system VARCHAR(255),\n"
" instance_id VARCHAR(255),\n"
" uuid VARCHAR(255) NOT NULL DEFAULT '',\n"
" session_uuid VARCHAR(255) NOT NULL DEFAULT '',\n"
" cid_number VARCHAR(255),\n"
@ -208,7 +209,7 @@ static char members_sql[] =
static char agents_sql[] =
"CREATE TABLE agents (\n"
" name VARCHAR(255),\n"
" system VARCHAR(255),\n"
" instance_id VARCHAR(255),\n"
" uuid VARCHAR(255),\n"
" type VARCHAR(255),\n" /* Callback , Dial in...*/
" contact VARCHAR(1024),\n"
@ -906,7 +907,7 @@ cc_status_t cc_agent_add(const char *agent, const char *type)
/* Add Agent */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding Agent %s with type %s with default status %s\n",
agent, type, cc_agent_status2str(CC_AGENT_STATUS_LOGGED_OUT));
sql = switch_mprintf("INSERT INTO agents (name, system, type, status, state) VALUES('%q', 'single_box', '%q', '%q', '%q');",
sql = switch_mprintf("INSERT INTO agents (name, instance_id, type, status, state) VALUES('%q', 'single_box', '%q', '%q', '%q');",
agent, type, cc_agent_status2str(CC_AGENT_STATUS_LOGGED_OUT), cc_agent_state2str(CC_AGENT_STATE_WAITING));
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -1075,13 +1076,13 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
goto done;
}
} else if (!strcasecmp(key, "uuid")) {
sql = switch_mprintf("UPDATE agents SET uuid = '%q', system = 'single_box' WHERE name = '%q'", value, agent);
sql = switch_mprintf("UPDATE agents SET uuid = '%q', instance_id = 'single_box' WHERE name = '%q'", value, agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
result = CC_STATUS_SUCCESS;
} else if (!strcasecmp(key, "contact")) {
sql = switch_mprintf("UPDATE agents SET contact = '%q', system = 'single_box' WHERE name = '%q'", value, agent);
sql = switch_mprintf("UPDATE agents SET contact = '%q', instance_id = 'single_box' WHERE name = '%q'", value, agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -1094,25 +1095,25 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
switch_event_fire(&event);
}
} else if (!strcasecmp(key, "ready_time")) {
sql = switch_mprintf("UPDATE agents SET ready_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
sql = switch_mprintf("UPDATE agents SET ready_time = '%ld', instance_id = 'single_box' WHERE name = '%q'", atol(value), agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
result = CC_STATUS_SUCCESS;
} else if (!strcasecmp(key, "busy_delay_time")) {
sql = switch_mprintf("UPDATE agents SET busy_delay_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
sql = switch_mprintf("UPDATE agents SET busy_delay_time = '%ld', instance_id = 'single_box' WHERE name = '%q'", atol(value), agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
result = CC_STATUS_SUCCESS;
} else if (!strcasecmp(key, "reject_delay_time")) {
sql = switch_mprintf("UPDATE agents SET reject_delay_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
sql = switch_mprintf("UPDATE agents SET reject_delay_time = '%ld', instance_id = 'single_box' WHERE name = '%q'", atol(value), agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
result = CC_STATUS_SUCCESS;
} else if (!strcasecmp(key, "no_answer_delay_time")) {
sql = switch_mprintf("UPDATE agents SET no_answer_delay_time = '%ld', system = 'single_box' WHERE name = '%q'", atol(value), agent);
sql = switch_mprintf("UPDATE agents SET no_answer_delay_time = '%ld', instance_id = 'single_box' WHERE name = '%q'", atol(value), agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -1130,14 +1131,14 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
result = CC_STATUS_SUCCESS;
} else if (!strcasecmp(key, "max_no_answer")) {
sql = switch_mprintf("UPDATE agents SET max_no_answer = '%d', system = 'single_box' WHERE name = '%q'", atoi(value), agent);
sql = switch_mprintf("UPDATE agents SET max_no_answer = '%d', instance_id = 'single_box' WHERE name = '%q'", atoi(value), agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
result = CC_STATUS_SUCCESS;
} else if (!strcasecmp(key, "wrap_up_time")) {
sql = switch_mprintf("UPDATE agents SET wrap_up_time = '%d', system = 'single_box' WHERE name = '%q'", atoi(value), agent);
sql = switch_mprintf("UPDATE agents SET wrap_up_time = '%d', instance_id = 'single_box' WHERE name = '%q'", atoi(value), agent);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -1460,6 +1461,46 @@ end:
return result;
}
struct sqlite_column_rename_callback_data {
const char *table;
switch_cache_db_handle_t *dbh;
};
typedef struct sqlite_column_rename_callback_data sqlite_column_rename_callback_data_t;
static int sqlite_column_rename_callback(void *pArg, const char *errmsg)
{
sqlite_column_rename_callback_data_t *callback_data = (sqlite_column_rename_callback_data_t *)pArg;
char tmptable[4096];
char *sql = NULL;
if (!strcasecmp("agents", callback_data->table)) {
if (NULL != (sql = strstr(agents_sql, "TABLE agents ("))) {
sql += 14;
sprintf(tmptable, "CREATE TABLE agents_tmp (%s", sql);
switch_cache_db_execute_sql_callback(callback_data->dbh, tmptable, NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "INSERT INTO agents_tmp SELECT * FROM agents;", NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "drop table agents", NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, agents_sql, NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "INSERT INTO agents SELECT * FROM agents_tmp;", NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "drop table agents_tmp", NULL, NULL, NULL);
}
}
else if (!strcasecmp("members", callback_data->table)) {
if (NULL != (sql = strstr(members_sql, "TABLE members ("))) {
sql += 15;
sprintf(tmptable, "CREATE TABLE members_tmp (%s", sql);
switch_cache_db_execute_sql_callback(callback_data->dbh, tmptable, NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "INSERT INTO members_tmp SELECT * FROM members;", NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "drop table members", NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, members_sql, NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "INSERT INTO members SELECT * FROM members_tmp;", NULL, NULL, NULL);
switch_cache_db_execute_sql_callback(callback_data->dbh, "drop table members_tmp", NULL, NULL, NULL);
}
}
return 0;
}
static switch_status_t load_config(void)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
@ -1531,16 +1572,34 @@ static switch_status_t load_config(void)
"alter table agents add busy_delay_time integer not null default 0;");
switch_cache_db_test_reactive(dbh, "select count(no_answer_delay_time) from agents", NULL, "alter table agents add no_answer_delay_time integer not null default 0;");
switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", "drop table agents", agents_sql);
switch_cache_db_test_reactive(dbh, "select external_calls_count from agents", NULL, "alter table agents add external_calls_count integer not null default 0;");
switch_cache_db_test_reactive(dbh, "select count(external_calls_count) from agents", NULL, "alter table agents add external_calls_count integer not null default 0;");
switch_cache_db_test_reactive(dbh, "select count(queue) from tiers", "drop table tiers" , tiers_sql);
/* This will rename column system for SQLite */
if (switch_cache_db_get_type(dbh) == SCDB_TYPE_CORE_DB) {
char *errmsg = NULL;
sqlite_column_rename_callback_data_t callback_data;
/* SQLite < 3.27.0 ( https://www.sqlite.org/changes.html ) has issues with renaming columns and tables */
callback_data.dbh = dbh;
callback_data.table = "agents";
switch_cache_db_execute_sql_callback_err(dbh, "select count(instance_id) from agents", NULL, sqlite_column_rename_callback, &callback_data, &errmsg);
callback_data.table = "members";
switch_cache_db_execute_sql_callback_err(dbh, "select count(instance_id) from members", NULL, sqlite_column_rename_callback, &callback_data, &errmsg);
} else {
/* This will rename column system for MySQL */
switch_cache_db_test_reactive(dbh, "select count(instance_id) from agents", NULL, "alter table agents rename column `system` TO instance_id;");
switch_cache_db_test_reactive(dbh, "select count(instance_id) from members", NULL, "alter table members rename column `system` TO instance_id;");
/* This will rename column system for PGSql */
switch_cache_db_test_reactive(dbh, "select count(instance_id) from agents", NULL, "alter table agents rename system TO instance_id;");
switch_cache_db_test_reactive(dbh, "select count(instance_id) from members", NULL, "alter table members rename system TO instance_id;");
}
switch_cache_db_release_db_handle(&dbh);
/* Reset a unclean shutdown */
sql = switch_mprintf("update agents set state = 'Waiting', uuid = '' where system = 'single_box';"
"update tiers set state = 'Ready' where agent IN (select name from agents where system = 'single_box');"
"update members set state = '%q', session_uuid = '' where system = '%q';"
"update agents set external_calls_count = 0 where system = 'single_box';",
sql = switch_mprintf("update agents set state = 'Waiting', uuid = '' where instance_id = 'single_box';"
"update tiers set state = 'Ready' where agent IN (select name from agents where instance_id = 'single_box');"
"update members set state = '%q', session_uuid = '' where instance_id = '%q';"
"update agents set external_calls_count = 0 where instance_id = 'single_box';",
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), globals.cc_instance_id);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -1646,7 +1705,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Member %s <%s> with uuid %s in queue %s is gone just before we assigned an agent\n", h->member_cid_name, h->member_cid_number, h->member_session_uuid, h->queue_name);
bridged = 0;
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND system = '%q' AND state != '%q'",
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND instance_id = '%q' AND state != '%q'",
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), h->member_uuid, globals.cc_instance_id, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
cc_execute_sql(NULL, sql, NULL);
@ -1848,7 +1907,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
char res[256];
/* Map the Agent to the member */
sql = switch_mprintf("UPDATE members SET serving_agent = '%q', serving_system = 'single_box', state = '%q'"
" WHERE state = '%q' AND uuid = '%q' AND system = '%q' AND serving_agent = '%q'",
" WHERE state = '%q' AND uuid = '%q' AND instance_id = '%q' AND serving_agent = '%q'",
h->agent_name, cc_member_state2str(CC_MEMBER_STATE_TRYING),
cc_member_state2str(CC_MEMBER_STATE_TRYING), h->member_uuid, globals.cc_instance_id, h->queue_strategy);
cc_execute_sql(NULL, sql, NULL);
@ -1857,7 +1916,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* Check if we won the race to get the member to our selected agent (Used for Multi system purposes) */
sql = switch_mprintf("SELECT count(*) FROM members"
" WHERE serving_agent = '%q' AND serving_system = 'single_box' AND uuid = '%q' AND system = '%q'",
" WHERE serving_agent = '%q' AND serving_system = 'single_box' AND uuid = '%q' AND instance_id = '%q'",
h->agent_name, h->member_uuid, globals.cc_instance_id);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
@ -1942,7 +2001,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
} else if (!bridged && !switch_channel_up(agent_channel)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Failed to bridge, agent %s has no session\n", h->agent_name);
/* Put back member on Waiting state, previous Trying */
sql = switch_mprintf("UPDATE members SET state = 'Waiting' WHERE uuid = '%q' AND system = '%q'", h->member_uuid, globals.cc_instance_id);
sql = switch_mprintf("UPDATE members SET state = 'Waiting' WHERE uuid = '%q' AND instance_id = '%q'", h->member_uuid, globals.cc_instance_id);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
} else {
@ -1960,7 +2019,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
/* Set UUID of the Agent channel */
sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%" SWITCH_TIME_T_FMT "', calls_answered = calls_answered + 1, no_answer_count = 0"
" WHERE name = '%q' AND system = '%q'",
" WHERE name = '%q' AND instance_id = '%q'",
agent_uuid, local_epoch_time_now(NULL),
h->agent_name, h->agent_system);
cc_execute_sql(NULL, sql, NULL);
@ -2012,13 +2071,13 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* Update Agents Items */
/* Do not remove uuid of the agent if we are a standby agent */
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %" SWITCH_TIME_T_FMT ", talk_time = talk_time + (%" SWITCH_TIME_T_FMT "-last_bridge_start) WHERE name = '%q' AND system = '%q';"
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %" SWITCH_TIME_T_FMT ", talk_time = talk_time + (%" SWITCH_TIME_T_FMT "-last_bridge_start) WHERE name = '%q' AND instance_id = '%q';"
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), local_epoch_time_now(NULL), local_epoch_time_now(NULL), h->agent_name, h->agent_system);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
/* Remove the member entry from the db (Could become optional to support latter processing) */
sql = switch_mprintf("DELETE FROM members WHERE uuid = '%q' AND system = '%q'", h->member_uuid, globals.cc_instance_id);
sql = switch_mprintf("DELETE FROM members WHERE uuid = '%q' AND instance_id = '%q'", h->member_uuid, globals.cc_instance_id);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -2057,7 +2116,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_channel_t *member_channel = switch_core_session_get_channel(member_session);
switch_channel_clear_app_flag_key(CC_APP_KEY, member_channel, CC_APP_AGENT_CONNECTING);
sql = switch_mprintf("UPDATE members SET state = case state when '%q' then '%q' else state end, serving_agent = '', serving_system = ''"
" WHERE serving_agent = '%q' AND serving_system = '%q' AND uuid = '%q' AND system = '%q'",
" WHERE serving_agent = '%q' AND serving_system = '%q' AND uuid = '%q' AND instance_id = '%q'",
cc_member_state2str(CC_MEMBER_STATE_TRYING), /* Only switch to Waiting from Trying (state may be set to Abandoned in callcenter_function()) */
cc_member_state2str(CC_MEMBER_STATE_WAITING),
h->agent_name, h->agent_system, h->member_uuid, globals.cc_instance_id);
@ -2091,7 +2150,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
tiers_state = CC_TIER_STATE_NO_ANSWER;
/* Update Agent NO Answer count */
sql = switch_mprintf("UPDATE agents SET no_answer_count = no_answer_count + 1 WHERE name = '%q' AND system = '%q';",
sql = switch_mprintf("UPDATE agents SET no_answer_count = no_answer_count + 1 WHERE name = '%q' AND instance_id = '%q';",
h->agent_name, h->agent_system);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -2297,21 +2356,21 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
if (!strcasecmp(cbt->strategy,"ring-all") || !strcasecmp(cbt->strategy,"ring-progressively")) {
/* Check if member is a ring-all mode */
sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = '%q' AND uuid = '%q' AND system = '%q'", cbt->strategy, cbt->member_uuid, globals.cc_instance_id);
sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = '%q' AND uuid = '%q' AND instance_id = '%q'", cbt->strategy, cbt->member_uuid, globals.cc_instance_id);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
} else {
/* Map the Agent to the member */
sql = switch_mprintf("UPDATE members SET serving_agent = '%q', serving_system = '%q', state = '%q'"
" WHERE state = '%q' AND uuid = '%q' AND system = '%q'",
" WHERE state = '%q' AND uuid = '%q' AND instance_id = '%q'",
agent_name, agent_system, cc_member_state2str(CC_MEMBER_STATE_TRYING),
cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt->member_uuid, globals.cc_instance_id);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
/* Check if we won the race to get the member to our selected agent (Used for Multi system purposes) */
sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = '%q' AND serving_system = '%q' AND uuid = '%q' AND system = '%q'",
sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = '%q' AND serving_system = '%q' AND uuid = '%q' AND instance_id = '%q'",
agent_name, agent_system, cbt->member_uuid, globals.cc_instance_id);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
@ -2431,7 +2490,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
if (!cbt.queue_name || !(queue = get_queue(cbt.queue_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, delete this member\n", cbt.queue_name);
sql = switch_mprintf("DELETE FROM members WHERE uuid = '%q' AND system = '%q'", cbt.member_uuid, cbt.member_system);
sql = switch_mprintf("DELETE FROM members WHERE uuid = '%q' AND instance_id = '%q'", cbt.member_uuid, cbt.member_system);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
goto end;
@ -2465,7 +2524,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
}
/* Once we pass a certain point, we want to get rid of the abandoned call */
if (abandoned_epoch + discard_abandoned_after < local_epoch_time_now(NULL)) {
sql = switch_mprintf("DELETE FROM members WHERE uuid = '%q' AND system = '%q' AND (abandoned_epoch = '%" SWITCH_TIME_T_FMT "' OR joined_epoch = '%q')", cbt.member_uuid, cbt.member_system, abandoned_epoch, cbt.member_joined_epoch);
sql = switch_mprintf("DELETE FROM members WHERE uuid = '%q' AND instance_id = '%q' AND (abandoned_epoch = '%" SWITCH_TIME_T_FMT "' OR joined_epoch = '%q')", cbt.member_uuid, cbt.member_system, abandoned_epoch, cbt.member_joined_epoch);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
}
@ -2557,13 +2616,13 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
switch_core_session_rwunlock(member_session);
}
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
sql = switch_mprintf("SELECT instance_id, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
" WHERE tiers.queue = '%q'"
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
" AND tiers.position > %d"
" AND tiers.level = %d"
" UNION "
"SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
"SELECT instance_id, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
" WHERE tiers.queue = '%q'"
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
" AND tiers.level > %d"
@ -2577,13 +2636,13 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
level
);
} else if (!strcasecmp(queue->strategy, "round-robin")) {
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
sql = switch_mprintf("SELECT instance_id, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 1 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
" WHERE tiers.queue = '%q'"
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
" AND tiers.position > (SELECT tiers.position FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent) WHERE tiers.queue = '%q' AND agents.last_offered_call > 0 ORDER BY agents.last_offered_call DESC LIMIT 1)"
" AND tiers.level = (SELECT tiers.level FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent) WHERE tiers.queue = '%q' AND agents.last_offered_call > 0 ORDER BY agents.last_offered_call DESC LIMIT 1)"
" UNION "
"SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
"SELECT instance_id, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position as tiers_position, tiers.level as tiers_level, agents.type, agents.uuid, external_calls_count, agents.last_offered_call as agents_last_offered_call, 2 as dyn_order FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
" WHERE tiers.queue = '%q'"
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
" ORDER BY dyn_order asc, tiers_level, tiers_position, agents_last_offered_call",
@ -2604,7 +2663,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
} else if (!strcasecmp(queue_strategy, "agent-with-fewest-calls")) {
sql_order_by = switch_mprintf("level, agents.calls_answered, position");
} else if (!strcasecmp(queue_strategy, "ring-all") || !strcasecmp(queue_strategy, "ring-progressively")) {
sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = '%q'",
sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND instance_id = '%q'",
cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.member_uuid, cbt.member_system);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -2618,7 +2677,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
sql_order_by = switch_mprintf("level, position, agents.last_offered_call");
}
sql = switch_mprintf("SELECT system, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position, tiers.level, agents.type, agents.uuid, external_calls_count FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
sql = switch_mprintf("SELECT instance_id, name, status, contact, no_answer_count, max_no_answer, reject_delay_time, busy_delay_time, no_answer_delay_time, tiers.state, agents.last_bridge_end, agents.wrap_up_time, agents.state, agents.ready_time, tiers.position, tiers.level, agents.type, agents.uuid, external_calls_count FROM agents LEFT JOIN tiers ON (agents.name = tiers.agent)"
" WHERE tiers.queue = '%q'"
" AND (agents.status = '%q' OR agents.status = '%q' OR agents.status = '%q')"
" ORDER BY %q",
@ -2706,8 +2765,8 @@ void *SWITCH_THREAD_FUNC cc_agent_dispatch_thread_run(switch_thread_t *thread, v
while (globals.running == 1) {
char *sql = NULL;
sql = switch_mprintf("SELECT queue,uuid,session_uuid,cid_number,cid_name,joined_epoch,(%" SWITCH_TIME_T_FMT "-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch, serving_agent, system FROM members"
" WHERE (state = '%q' OR state = '%q' OR (serving_agent = 'ring-all' AND state = '%q') OR (serving_agent = 'ring-progressively' AND state = '%q')) AND system = '%q' ORDER BY score DESC",
sql = switch_mprintf("SELECT queue,uuid,session_uuid,cid_number,cid_name,joined_epoch,(%" SWITCH_TIME_T_FMT "-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch, serving_agent, instance_id FROM members"
" WHERE (state = '%q' OR state = '%q' OR (serving_agent = 'ring-all' AND state = '%q') OR (serving_agent = 'ring-progressively' AND state = '%q')) AND instance_id = '%q' ORDER BY score DESC",
local_epoch_time_now(NULL),
cc_member_state2str(CC_MEMBER_STATE_WAITING), cc_member_state2str(CC_MEMBER_STATE_ABANDONED), cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_TRYING), globals.cc_instance_id);
@ -3013,7 +3072,7 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> restoring it previous position in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
/* Update abandoned member */
sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%" SWITCH_TIME_T_FMT "', system = '%q' WHERE uuid = '%q' AND state = '%q'",
sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%" SWITCH_TIME_T_FMT "', instance_id = '%q' WHERE uuid = '%q' AND state = '%q'",
member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), local_epoch_time_now(NULL), globals.cc_instance_id, member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
cc_execute_sql(queue, sql, NULL);
switch_safe_free(sql);
@ -3059,7 +3118,7 @@ SWITCH_STANDARD_APP(callcenter_function)
strategy_str = "";
}
sql = switch_mprintf("INSERT INTO members"
" (queue,system,uuid,session_uuid,system_epoch,joined_epoch,base_score,skill_score,cid_number,cid_name,serving_agent,serving_system,state)"
" (queue,instance_id,uuid,session_uuid,system_epoch,joined_epoch,base_score,skill_score,cid_number,cid_name,serving_agent,serving_system,state)"
" VALUES('%q','%q','%q','%q','%q','%" SWITCH_TIME_T_FMT "','%d','%d','%q','%q','%q','','%q')",
queue_name,
globals.cc_instance_id,
@ -3182,7 +3241,7 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> abandoned waiting in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
/* Update member state */
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND system = '%q'",
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND instance_id = '%q'",
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), member_uuid, globals.cc_instance_id);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@ -3224,7 +3283,7 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> is answered by an agent in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
/* Update member state */
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND system = '%q'",
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND instance_id = '%q'",
cc_member_state2str(CC_MEMBER_STATE_ANSWERED), local_epoch_time_now(NULL), member_uuid, globals.cc_instance_id);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);

View File

@ -75,6 +75,9 @@ static struct {
int retries;
int random;
char *nameserver[ENUM_MAXNAMESERVERS];
#ifdef _MSC_VER
char *nameserver_buf;
#endif
} globals;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_root, globals.root);
@ -164,7 +167,6 @@ static switch_status_t load_config(void)
if (!globals.nameserver[0]) {
HKEY hKey;
DWORD data_sz;
char* buf;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0, KEY_QUERY_VALUE, &hKey);
@ -172,15 +174,15 @@ static switch_status_t load_config(void)
if (hKey) {
RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, NULL, &data_sz);
if (data_sz) {
buf = (char*)malloc(data_sz + 1);
globals.nameserver_buf = (char*)malloc(data_sz + 1);
RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE)buf, &data_sz);
RegQueryValueEx(hKey, "DhcpNameServer", NULL, NULL, (LPBYTE)globals.nameserver_buf, &data_sz);
if(buf[data_sz - 1] != 0) {
buf[data_sz] = 0;
if(globals.nameserver_buf[data_sz - 1] != 0) {
globals.nameserver_buf[data_sz] = 0;
}
switch_replace_char(buf, ' ', 0, SWITCH_FALSE); /* only use the first entry ex "192.168.1.1 192.168.1.2" */
globals.nameserver[0] = buf;
switch_replace_char(globals.nameserver_buf, ' ', 0, SWITCH_FALSE); /* only use the first entry ex "192.168.1.1 192.168.1.2" */
globals.nameserver[0] = globals.nameserver_buf;
}
RegCloseKey(hKey);
@ -924,6 +926,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_enum_shutdown)
switch_safe_free(globals.root);
switch_safe_free(globals.isn_root);
#ifdef _MSC_VER
switch_safe_free(globals.nameserver_buf);
#endif
return SWITCH_STATUS_UNLOAD;
}

View File

@ -933,6 +933,7 @@ static void pres_event_handler(switch_event_t *event)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_valet_parking_shutdown)
{
switch_event_unbind_callback(pres_event_handler);
switch_core_hash_destroy(&globals.hash);
return SWITCH_STATUS_SUCCESS;
}

View File

@ -6473,6 +6473,12 @@ void mod_sofia_shutdown_cleanup() {
su_deinit();
/*
Release the clone of the default SIP parser
created by `sip_update_default_mclass(sip_extend_mclass(NULL))` call with NULL argument
*/
sip_cloned_parser_destroy();
switch_mutex_lock(mod_sofia_globals.hash_mutex);
switch_core_hash_destroy(&mod_sofia_globals.profile_hash);
switch_core_hash_destroy(&mod_sofia_globals.gateway_hash);

View File

@ -4290,6 +4290,7 @@ switch_status_t sofia_init(void)
su_init();
if (sip_update_default_mclass(sip_extend_mclass(NULL)) < 0) {
su_deinit();
sip_cloned_parser_destroy();
return SWITCH_STATUS_GENERR;
}

View File

@ -614,14 +614,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_reset(switch_codec_t *codec)
SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec,
const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool)
{
uint32_t codec_rate;
switch_assert(codec != NULL);
switch_assert(new_codec != NULL);
codec_rate = !strcasecmp(codec->implementation->iananame, "g722")
? codec->implementation->samples_per_second : codec->implementation->actual_samples_per_second;
return switch_core_codec_init(new_codec,
codec->implementation->iananame,
codec->implementation->modname,
codec->fmtp_in,
codec->implementation->actual_samples_per_second,
codec_rate,
codec->implementation->microseconds_per_packet / 1000,
codec->implementation->number_of_channels,
codec->flags,

View File

@ -818,6 +818,7 @@ SWITCH_DECLARE(int) switch_cache_db_affected_rows(switch_cache_db_handle_t *dbh)
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
int affected_rows = 0;
database_interface->affected_rows(dbh->native_handle.database_interface_dbh, &affected_rows);
return affected_rows;
}
break;
}
@ -1188,11 +1189,10 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback(switc
case SCDB_TYPE_DATABASE_INTERFACE:
{
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
switch_status_t result;
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, helper_callback, &h, err)) != SWITCH_STATUS_SUCCESS) {
if ((status = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, helper_callback, &h, err)) != SWITCH_STATUS_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_event_callback", result);
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_event_callback", status);
}
}
break;
@ -1249,17 +1249,16 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback_err(s
case SCDB_TYPE_DATABASE_INTERFACE:
{
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
switch_status_t result;
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, helper_callback, &h, err)) != SWITCH_STATUS_SUCCESS) {
if ((status = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, helper_callback, &h, err)) != SWITCH_STATUS_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_event_callback_err", result);
} else {
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_event_callback_err", status);
}
if (err && *err) {
(*err_callback)(pdata, (const char*)*err);
}
}
}
break;
case SCDB_TYPE_ODBC:
{
@ -1316,11 +1315,10 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach
case SCDB_TYPE_DATABASE_INTERFACE:
{
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
switch_status_t result;
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, callback, pdata, err)) != SWITCH_STATUS_SUCCESS) {
if ((status = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, callback, pdata, err)) != SWITCH_STATUS_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_callback", result);
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_callback", status);
}
}
break;
@ -1372,17 +1370,16 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback_err(switch_
case SCDB_TYPE_DATABASE_INTERFACE:
{
switch_database_interface_t *database_interface = dbh->native_handle.database_interface_dbh->connection_options.database_interface;
switch_status_t result;
if ((result = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, callback, pdata, err)) != SWITCH_STATUS_SUCCESS) {
if ((status = database_interface_handle_callback_exec(database_interface, dbh->native_handle.database_interface_dbh, sql, callback, pdata, err)) != SWITCH_STATUS_SUCCESS) {
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_callback_err", result);
} else {
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to execute_sql_callback_err", status);
}
if (err && *err) {
(*err_callback)(pdata, (const char*)*err);
}
}
}
break;
case SCDB_TYPE_ODBC:
{
@ -1491,6 +1488,7 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive_ex(switch_cache_db_h
char tmp[100];
switch_snprintfv(tmp, sizeof(tmp), "%q-%i", "Unable to test_reactive with drop_sql", result);
}
}
if ((result = database_interface_handle_exec(database_interface, dbh->native_handle.database_interface_dbh, reactive_sql, NULL)) != SWITCH_STATUS_SUCCESS) {
char tmp[100];
@ -1506,7 +1504,6 @@ SWITCH_DECLARE(switch_bool_t) switch_cache_db_test_reactive_ex(switch_cache_db_h
r = (result == SWITCH_STATUS_SUCCESS);
}
}
}
break;
case SCDB_TYPE_ODBC:
{

View File

@ -1360,7 +1360,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "json_api");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "description", switch_str_nil(ptr->desc));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "syntax", switch_str_nil(ptr->syntax));
@ -2515,6 +2515,7 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void)
switch_core_hash_destroy(&loadable_modules.limit_hash);
switch_core_hash_destroy(&loadable_modules.database_hash);
switch_core_hash_destroy(&loadable_modules.dialplan_hash);
switch_core_hash_destroy(&loadable_modules.secondary_recover_hash);
switch_core_destroy_memory_pool(&loadable_modules.pool);
}

View File

@ -479,6 +479,10 @@ static switch_status_t _timerfd_next(switch_timer_t *timer)
interval_timer_t *it = timer->private_info;
uint64_t u64 = 0;
if (!it) {
return SWITCH_STATUS_GENERR;
}
if (read(it->fd, &u64, sizeof(u64)) < 0) {
return SWITCH_STATUS_GENERR;
} else {
@ -495,6 +499,10 @@ static switch_status_t _timerfd_check(switch_timer_t *timer, switch_bool_t step)
struct itimerspec val;
int diff;
if (!it) {
return SWITCH_STATUS_GENERR;
}
timerfd_gettime(it->fd, &val);
diff = val.it_interval.tv_nsec / 1000;
@ -515,9 +523,12 @@ static switch_status_t _timerfd_check(switch_timer_t *timer, switch_bool_t step)
static switch_status_t _timerfd_destroy(switch_timer_t *timer)
{
interval_timer_t *it = timer->private_info;
int rc;
int rc = SWITCH_STATUS_GENERR;
if (it) {
rc = timerfd_stop_interval(it);
}
return rc;
}

View File

@ -8,6 +8,9 @@
<load module="mod_console"/>
<load module="mod_loopback"/>
<load module="mod_opus"/>
<load module="mod_spandsp"/>
<load module="mod_amr"/>
<load module="mod_amrwb"/>
</modules>
</configuration>

View File

@ -51,6 +51,7 @@ FST_CORE_BEGIN("./conf")
FST_SETUP_BEGIN()
{
fst_requires_module("mod_opus");
fst_requires_module("mod_spandsp");
}
FST_SETUP_END()
@ -102,6 +103,20 @@ FST_CORE_BEGIN("./conf")
fst_check(orig_codec.implementation->samples_per_second == new_codec.implementation->samples_per_second);
fst_check(orig_codec.implementation->actual_samples_per_second == new_codec.implementation->actual_samples_per_second);
status = switch_core_codec_init(&orig_codec,
"G722",
"mod_spandsp",
NULL,
8000,
20,
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
&codec_settings, fst_pool);
fst_check(status == SWITCH_STATUS_SUCCESS);
switch_core_codec_copy(&orig_codec, &new_codec, NULL, NULL);
fst_check(orig_codec.implementation->samples_per_second == new_codec.implementation->samples_per_second);
fst_check(orig_codec.implementation->actual_samples_per_second == new_codec.implementation->actual_samples_per_second);
}
FST_TEST_END()
}