From 780797f226cd4de9839609bb56e158346807f03e Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 22 May 2014 18:40:24 +0000 Subject: [PATCH 01/79] basic mutex model for coverity --- build/coverity_model.c | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 build/coverity_model.c diff --git a/build/coverity_model.c b/build/coverity_model.c new file mode 100644 index 0000000000..b72daa6639 --- /dev/null +++ b/build/coverity_model.c @@ -0,0 +1,47 @@ +/* Coverity Scan model + * + * This is a modelling file for Coverity Scan. Modelling helps to avoid false + * positives. + * + * - A model file can't import any header files. + * - Therefore only some built-in primitives like int, char and void are + * available but not NULL etc. + * - Modelling doesn't need full structs and typedefs. Rudimentary structs + * and similar types are sufficient. + * - An uninitialised local pointer is not an error. It signifies that the + * variable could be either NULL or have some data. + * + * Coverity Scan doesn't pick up modifications automatically. The model file + * must be uploaded by an admin in the analysis. + * + * Based on: + * http://hg.python.org/cpython/file/tip/Misc/coverity_model.c + * Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + * 2011, 2012, 2013 Python Software Foundation; All Rights Reserved + * + */ + +/* + * Useful references: + * https://scan.coverity.com/models + */ + +typedef unsigned int switch_status_t; + +struct pthread_mutex_t {}; + +struct switch_mutex +{ + struct pthread_mutex_t lock; +}; +typedef struct switch_mutex switch_mutex_t; + +switch_status_t switch_mutex_lock(switch_mutex_t *lock) +{ + __coverity_recursive_lock_acquire__(&lock->lock); +} + +switch_status_t switch_mutex_unlock(switch_mutex_t *lock) +{ + __coverity_recursive_lock_release__(&lock->lock); +} From dc671d9d82e5ccdc5617f53c68c272c44a56b535 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 22 May 2014 16:41:21 -0400 Subject: [PATCH 02/79] fix name of fs_ivrd --- libs/esl/Makefile.am | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/esl/Makefile.am b/libs/esl/Makefile.am index 3d701a7951..cc84ae3aae 100644 --- a/libs/esl/Makefile.am +++ b/libs/esl/Makefile.am @@ -17,7 +17,7 @@ endif $(MYLIB): libesl.la -bin_PROGRAMS = fs_cli ivrd +bin_PROGRAMS = fs_cli fs_ivrd noinst_PROGRAMS = testclient testserver testserver_fork fs_cli_SOURCES = fs_cli.c @@ -40,10 +40,10 @@ testserver_fork_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include testserver_fork_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) testserver_fork_LDADD = libesl.la -ivrd_SOURCES = ivrd.c -ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include -ivrd_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) -ivrd_LDADD = libesl.la +fs_ivrd_SOURCES = ivrd.c +fs_ivrd_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include +fs_ivrd_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) +fs_ivrd_LDADD = libesl.la reswig: swigclean $(MAKE) -C perl reswig From ed6dd184f725a63f72fe20ed9cb3a1e96137ad8f Mon Sep 17 00:00:00 2001 From: Marc Olivier Chouinard Date: Fri, 23 May 2014 08:42:16 -0400 Subject: [PATCH 03/79] FS-6482 Commit 7e15c938e21ec39ceaaf0d67772156129d85ceb9 broke MWI for device having no transport parameters (plain UDP connection) --- src/mod/endpoints/mod_sofia/sofia_glue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 14063bdbe2..e644dacf3d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2680,7 +2680,6 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use break; } } else { - user_via = sofia_glue_create_external_via(NULL, profile, SOFIA_TRANSPORT_UDP); contact_str = profile->url; } } From 757b7440104e34cf57ab30a411e081470ce2e180 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 23 May 2014 08:11:03 -0500 Subject: [PATCH 04/79] Since we're all about WebRTC, We should compile and enable OPUS by default to lower the number of steps to complete a WebRTC setup --- build/modules.conf.in | 2 +- conf/vanilla/autoload_configs/modules.conf.xml | 2 +- conf/vanilla/vars.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/modules.conf.in b/build/modules.conf.in index 953613b2fb..ddcf9474f2 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -68,7 +68,7 @@ codecs/mod_vp8 #codecs/mod_ilbc #codecs/mod_isac #codecs/mod_mp4v -#codecs/mod_opus +codecs/mod_opus #codecs/mod_sangoma_codec #codecs/mod_silk #codecs/mod_siren diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index e2dce594fa..4cd8f8e1ce 100644 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -90,7 +90,7 @@ - + diff --git a/conf/vanilla/vars.xml b/conf/vanilla/vars.xml index 92c57a2a60..20016cd85f 100644 --- a/conf/vanilla/vars.xml +++ b/conf/vanilla/vars.xml @@ -243,7 +243,7 @@ 127 - BV32 --> - + + + + + + + + + + + + + + diff --git a/src/mod/loggers/mod_graylog2/mod_graylog2.c b/src/mod/loggers/mod_graylog2/mod_graylog2.c new file mode 100644 index 0000000000..44f5286ee8 --- /dev/null +++ b/src/mod/loggers/mod_graylog2/mod_graylog2.c @@ -0,0 +1,347 @@ +/* + * mod_graylog2 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2014, Grasshopper + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mod_graylog2 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is Grasshopper + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Christopher Rienzo + * + * mod_graylog2.c -- Graylog2 GELF logger + * + */ +#include + +#include +#include + +SWITCH_MODULE_LOAD_FUNCTION(mod_graylog2_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_graylog2_shutdown); +SWITCH_MODULE_DEFINITION(mod_graylog2, mod_graylog2_load, mod_graylog2_shutdown, NULL); + +static struct { + /** memory pool for this module */ + switch_memory_pool_t *pool; + /** graylog2 server address */ + const char *server_host; + /** graylog2 server port */ + switch_port_t server_port; + /** minimum log level to allow */ + switch_log_level_t log_level; + /** shutdown flag */ + int shutdown; + /** prevents context shutdown until all threads are finished */ + switch_thread_rwlock_t *shutdown_rwlock; + /** log delivery queue */ + switch_queue_t *log_queue; +} globals; + +/** + * Convert log level to graylog2 log level + */ +static int to_graylog2_level(switch_log_level_t level) +{ + switch (level) { + case SWITCH_LOG_DEBUG: return 7; + case SWITCH_LOG_INFO: return 6; + case SWITCH_LOG_NOTICE: return 5; + case SWITCH_LOG_WARNING: return 4; + case SWITCH_LOG_ERROR: return 3; + case SWITCH_LOG_CRIT: return 2; + case SWITCH_LOG_ALERT: return 1; + default: return 8; + } +} + +/** + * Encode log as GELF + */ +static char *to_gelf(const switch_log_node_t *node, switch_log_level_t log_level) +{ + char *gelf_text = NULL; + cJSON *gelf = cJSON_CreateObject(); + char *hostname; + char timestamp[32]; + char *full_message = node->content; + char short_message[151]; + char *short_message_end = NULL; + + cJSON_AddItemToObject(gelf, "version", cJSON_CreateString("1.1")); + if ((hostname = switch_core_get_variable("hostname")) && !zstr(hostname)) { + cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname)); + } else if ((hostname = switch_core_get_variable("local_ip_v4")) && !zstr(hostname)) { + cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname)); + } + switch_snprintf(timestamp, 32, "%"SWITCH_UINT64_T_FMT".%d", (uint64_t)(node->timestamp / 1000000), node->timestamp % 1000000); + cJSON_AddItemToObject(gelf, "timestamp", cJSON_CreateString(timestamp)); + cJSON_AddItemToObject(gelf, "level", cJSON_CreateNumber(to_graylog2_level(log_level))); + cJSON_AddItemToObject(gelf, "_ident", cJSON_CreateString("freeswitch")); + cJSON_AddItemToObject(gelf, "_pid", cJSON_CreateNumber((int)getpid())); + if (!zstr(node->userdata)) { + cJSON_AddItemToObject(gelf, "_uuid", cJSON_CreateString(node->userdata)); + } + if (!zstr_buf(node->file)) { + cJSON_AddItemToObject(gelf, "_file", cJSON_CreateString(node->file)); + cJSON_AddItemToObject(gelf, "_line", cJSON_CreateNumber(node->line)); + } + if (!zstr_buf(node->func)) { + cJSON_AddItemToObject(gelf, "_function", cJSON_CreateString(node->func)); + } + + /* skip initial space and new line */ + if (*full_message == ' ') { + full_message++; + } + if (*full_message == '\n') { + full_message++; + } + + cJSON_AddItemToObject(gelf, "full_message", cJSON_CreateString(full_message)); + + switch_snprintf(short_message, sizeof(short_message) - 1, "%s", full_message); + if ((short_message_end = strchr(short_message, '\n'))) { + *short_message_end = '\0'; + } + cJSON_AddItemToObject(gelf, "short_message", cJSON_CreateString(short_message)); + + gelf_text = cJSON_PrintUnformatted(gelf); + cJSON_Delete(gelf); + return gelf_text; +} + +/** + * Open connection to graylog2 server + */ +static switch_socket_t *open_graylog2_socket(const char *host, switch_port_t port, switch_memory_pool_t *pool) +{ + switch_sockaddr_t *graylog2_addr = NULL; + switch_socket_t *graylog2_sock = NULL; + + if (switch_sockaddr_info_get(&graylog2_addr, host, SWITCH_UNSPEC, port, 0, pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad address: %s:%d\n", host, port); + return NULL; + } + + if (switch_socket_create(&graylog2_sock, switch_sockaddr_get_family(graylog2_addr), SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open UDP socket\n"); + return NULL; + } + + if (switch_socket_connect(graylog2_sock, graylog2_addr) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to connect to: %s:%d\n", host, port); + switch_socket_close(graylog2_sock); + return NULL; + } + + return graylog2_sock; +} + +/** + * Thread that delivers logs to graylog2 server + * @param thread this thread + * @param obj unused + * @return NULL + */ +static void *SWITCH_THREAD_FUNC deliver_graylog2_thread(switch_thread_t *thread, void *obj) +{ + switch_socket_t *graylog2_sock = NULL; + char *log; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "graylog2 delivery thread started\n"); + + switch_thread_rwlock_rdlock(globals.shutdown_rwlock); + + graylog2_sock = open_graylog2_socket(globals.server_host, globals.server_port, globals.pool); + if (graylog2_sock) { + while (!globals.shutdown) { + if (switch_queue_pop(globals.log_queue, (void *)&log) == SWITCH_STATUS_SUCCESS) { + if (!zstr(log)) { + switch_size_t len = strlen(log); + if (len <= 8192) { + switch_socket_send_nonblock(graylog2_sock, (void *)log, &len); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Skipping log with length > 8192 bytes\n"); + } + } + switch_safe_free(log); + } + } + } + + globals.shutdown = 1; + + /* clean up remaining logs */ + while(switch_queue_trypop(globals.log_queue, (void *)&log) == SWITCH_STATUS_SUCCESS) { + switch_safe_free(log); + } + + if (graylog2_sock) { + switch_socket_close(graylog2_sock); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "graylog2 delivery thread finished\n"); + switch_thread_rwlock_unlock(globals.shutdown_rwlock); + + return NULL; +} + +/** + * Create a new graylog2 delivery thread + * @param pool to use + */ +static void start_deliver_graylog2_thread(switch_memory_pool_t *pool) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + switch_threadattr_create(&thd_attr, pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&thread, thd_attr, deliver_graylog2_thread, NULL, pool); +} + +/** + * Stop graylog2 delivery thread + */ +static void stop_deliver_graylog2_thread(void) +{ + globals.shutdown = 1; + switch_queue_interrupt_all(globals.log_queue); + switch_thread_rwlock_wrlock(globals.shutdown_rwlock); +} + +/** + * Handle log from core + * @param node the log + * @param level the log level + */ +static switch_status_t mod_graylog2_logger(const switch_log_node_t *node, switch_log_level_t level) +{ + if (!globals.shutdown && level <= globals.log_level && level != SWITCH_LOG_CONSOLE) { + if (!zstr(node->content) && !zstr(node->content + 1)) { + char *log = to_gelf(node, level); + if (switch_queue_trypush(globals.log_queue, log) != SWITCH_STATUS_SUCCESS) { + free(log); + } + } + } + return SWITCH_STATUS_SUCCESS; +} + +/** + * Configure module + */ +static switch_status_t do_config(void) +{ + switch_xml_t cfg, xml, settings; + + if (!(xml = switch_xml_open_cfg("graylog2.conf", &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of graylog2.conf failed\n"); + return SWITCH_STATUS_TERM; + } + + /* set defaults */ + globals.log_level = SWITCH_LOG_WARNING; + globals.server_host = "127.0.0.1"; + globals.server_port = 12201; + + if ((settings = switch_xml_child(cfg, "settings"))) { + switch_xml_t param; + for (param = switch_xml_child(settings, "param"); param; param = param->next) { + char *name = (char *) switch_xml_attr_soft(param, "name"); + char *value = (char *) switch_xml_attr_soft(param, "value"); + + if (zstr(name)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring empty param\n"); + continue; + } + + if (zstr(value)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring empty value for param \"%s\"\n", name); + continue; + } + + if (!strcmp(name, "server-host")) { + globals.server_host = switch_core_strdup(globals.pool, value); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); + } else if (!strcasecmp(name, "server-port")) { + int port = -1; + if (switch_is_number(value)) { + port = atoi(value); + } + if (port > 0 && port <= 65535) { + globals.server_port = port; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid port: \"%s\"\n", value); + } + } else if (!strcasecmp(name, "loglevel")) { + switch_log_level_t log_level = switch_log_str2level(value); + if (log_level == SWITCH_LOG_INVALID) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring invalid log level: \"%s\"\n", value); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\" = \"%s\"\n", name, value); + globals.log_level = log_level; + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring unknown param: \"%s\"\n", name); + } + } + } + switch_xml_free(xml); + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_graylog2_load) +{ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + memset(&globals, 0, sizeof(globals)); + globals.pool = pool; + + if (do_config() != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_TERM; + } + + switch_thread_rwlock_create(&globals.shutdown_rwlock, pool); + switch_queue_create(&globals.log_queue, 25000, pool); + + start_deliver_graylog2_thread(globals.pool); + switch_log_bind_logger(mod_graylog2_logger, SWITCH_LOG_DEBUG, SWITCH_FALSE); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_graylog2_shutdown) +{ + switch_log_unbind_logger(mod_graylog2_logger); + stop_deliver_graylog2_thread(); + + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ From 027499173233a059073046416cb8f834450e3fc5 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 07:18:48 +0000 Subject: [PATCH 09/79] Revert commit that breaks build on gcc-4.8 Revert "FS-4296 --resolve initial calling/called nums in 'show channels'" This reverts commit b08138d058299db52a96346c0125feb9ef5cde58. --- src/switch_core_sqldb.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 36be9f3699..6a49a4988c 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2269,8 +2269,8 @@ static void core_event_handler(switch_event_t *event) break; } case SWITCH_EVENT_CHANNEL_CREATE: - new_sql() = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname,initial_cid_num,initial_dest) " - "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q','%q','%q')", + new_sql() = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname) " + "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q')", switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "call-direction"), switch_event_get_header_nil(event, "event-date-local"), @@ -2279,9 +2279,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "channel-call-state"), switch_event_get_header_nil(event, "caller-dialplan"), - switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname(), - switch_event_get_header_nil(event, "caller-caller-id-number"), - switch_event_get_header_nil(event, "caller-destination-number") + switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname() ); break; case SWITCH_EVENT_CHANNEL_ANSWER: @@ -2668,16 +2666,9 @@ static char create_channels_sql[] = " callee_direction VARCHAR(5),\n" " call_uuid VARCHAR(256),\n" " sent_callee_name VARCHAR(1024),\n" - " sent_callee_num VARCHAR(256),\n" - " initial_cid_num VARCHAR(256),\n" - " initial_dest VARCHAR(256)\n" + " sent_callee_num VARCHAR(256)\n" ");\n"; -static char *alter_channels_sql[2][2] = { - { "select initial_cid_num from channels", "ALTER TABLE channels ADD COLUMN initial_cid_num VARCHAR(256);\n" }, - { "select initial_dest from channels", "ALTER TABLE channels ADD COLUMN initial_dest VARCHAR(256);\n" } -}; - static char create_calls_sql[] = "CREATE TABLE calls (\n" " call_uuid VARCHAR(255),\n" @@ -3395,9 +3386,6 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ int result = 0; switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); - for (int i=0; i Date: Sat, 24 May 2014 08:42:54 +0000 Subject: [PATCH 10/79] Show initial channel values with `show channels` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store some initial details about the channel separately so we can preserve them across e.g. transfers and display them with show channels. With this commit, we store the original caller ID (name and number) and IP address, and the call destination, dialplan, and context. FS-4296 --resolve Thanks-to: Mariusz Czułada --- src/switch_core_sqldb.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 6a49a4988c..31e835e760 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2269,8 +2269,8 @@ static void core_event_handler(switch_event_t *event) break; } case SWITCH_EVENT_CHANNEL_CREATE: - new_sql() = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname) " - "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q')", + new_sql() = switch_mprintf("insert into channels (uuid,direction,created,created_epoch, name,state,callstate,dialplan,context,hostname,initial_cid_name,initial_cid_num,initial_ip_addr,initial_dest,initial_dialplan,initial_context) " + "values('%q','%q','%q','%ld','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q')", switch_event_get_header_nil(event, "unique-id"), switch_event_get_header_nil(event, "call-direction"), switch_event_get_header_nil(event, "event-date-local"), @@ -2279,7 +2279,13 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "channel-call-state"), switch_event_get_header_nil(event, "caller-dialplan"), - switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname() + switch_event_get_header_nil(event, "caller-context"), switch_core_get_switchname(), + switch_event_get_header_nil(event, "caller-caller-id-name"), + switch_event_get_header_nil(event, "caller-caller-id-number"), + switch_event_get_header_nil(event, "caller-network-addr"), + switch_event_get_header_nil(event, "caller-destination-number"), + switch_event_get_header_nil(event, "caller-dialplan"), + switch_event_get_header_nil(event, "caller-context") ); break; case SWITCH_EVENT_CHANNEL_ANSWER: @@ -2666,7 +2672,13 @@ static char create_channels_sql[] = " callee_direction VARCHAR(5),\n" " call_uuid VARCHAR(256),\n" " sent_callee_name VARCHAR(1024),\n" - " sent_callee_num VARCHAR(256)\n" + " sent_callee_num VARCHAR(256),\n" + " initial_cid_name VARCHAR(1024),\n" + " initial_cid_num VARCHAR(256),\n" + " initial_ip_addr VARCHAR(256),\n" + " initial_dest VARCHAR(1024),\n" + " initial_dialplan VARCHAR(128),\n" + " initial_context VARCHAR(128)\n" ");\n"; static char create_calls_sql[] = @@ -3385,7 +3397,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ char *err; int result = 0; - switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name, initial_cid_name, initial_cid_num, initial_ip_addr, initial_dest, initial_dialplan, initial_context from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); From 92843d0b75cdbfb17fa66582a860439b52431b32 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 06:55:54 +0000 Subject: [PATCH 11/79] Add mod_graylog2 to debian packaging --- debian/control-modules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/debian/control-modules b/debian/control-modules index 6d634df36a..0b778cfed5 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -588,6 +588,10 @@ Module: loggers/mod_logfile Description: mod_logfile Adds mod_logfile. +Module: loggers/mod_graylog2 +Description: mod_graylog2 + Adds mod_greylog2. + Module: loggers/mod_syslog Description: mod_syslog Adds mod_syslog. From e8ba8ed5a59d0af41971cd3817d39bf33c813980 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 00:34:12 +0000 Subject: [PATCH 12/79] Avoid useless NAT log message If FS is not behind NAT, then every call generates at least three INFO-level log messages: [INFO] switch_nat.c:589 NAT port mapping disabled This is useless noise. The message is only interesting if you do have NAT enabled but mapping disabled, which might indicate a configuration issue. With this change, we just skip the entire nat_add_mapping function if the NAT system isn't initialized or we're not behind NAT. --- src/switch_nat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_nat.c b/src/switch_nat.c index 2b95f8b959..c998c60b8b 100644 --- a/src/switch_nat.c +++ b/src/switch_nat.c @@ -585,6 +585,7 @@ SWITCH_DECLARE(switch_status_t) switch_nat_add_mapping_internal(switch_port_t po switch_status_t status = SWITCH_STATUS_FALSE; switch_event_t *event = NULL; + if (!initialized || !nat_globals.nat_type) return status; if (!nat_globals.mapping) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "NAT port mapping disabled\n"); return status; From 1fe6fb6d46efa12ae59f7b573dade4e09c3cdec2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 22 May 2014 18:08:14 +0000 Subject: [PATCH 13/79] Use CPPFLAGS for mod_java includes --- src/mod/languages/mod_java/Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_java/Makefile.am b/src/mod/languages/mod_java/Makefile.am index 1c9bda9fd3..b36675300f 100644 --- a/src/mod/languages/mod_java/Makefile.am +++ b/src/mod/languages/mod_java/Makefile.am @@ -4,11 +4,14 @@ MODNAME=mod_java mod_LTLIBRARIES = mod_java.la mod_java_la_SOURCES = mod_java.cpp freeswitch_java.cpp switch_swig_wrap.cpp modjava.c mod_java_la_CFLAGS = $(AM_CFLAGS) +mod_java_la_CPPFLAGS = -I/usr/lib/jvm/java-gcj/include +mod_java_la_CPPFLAGS+= -I/usr/lib/jvm/java-gcj/include/linux +mod_java_la_CPPFLAGS+= $(AM_CPPFLAGS) mod_java_la_LIBADD = $(switch_builddir)/libfreeswitch.la mod_java_la_LDFLAGS = -avoid-version -module -no-undefined -shared # Without -fno-strict-aliasing, g++ generates invalid code for Java_org_freeswitch_freeswitchJNI_SWIGJavaSessionUpcast, which segfaults -mod_java_la_CFLAGS += $(JAVA_FLAGS) -fno-strict-aliasing -I/usr/lib/jvm/java-gcj/include -I/usr/lib/jvm/java-gcj/include/linux +mod_java_la_CFLAGS += $(JAVA_FLAGS) -fno-strict-aliasing CLASSES=src/org/freeswitch/Launcher.java \ src/org/freeswitch/HangupHook.java \ From 333aff8a05341e0e55d99ef587d6f9fa5815802e Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 19:08:27 +0000 Subject: [PATCH 14/79] Document that switch_core_alloc returns zeroed memory --- src/include/switch_core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index b4e3e09353..22780dd4ac 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -645,6 +645,7 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(_In_ switch_memory_pool_t *pool \brief Allocate memory directly from a memory pool \param _pool the memory pool to allocate from \param _mem the number of bytes to allocate + \remark the memory returned has been memset to zero \return a void pointer to the allocated memory */ #define switch_core_alloc(_pool, _mem) switch_core_perform_alloc(_pool, _mem, __FILE__, __SWITCH_FUNC__, __LINE__) From ed2351e04817e7ebbd34ef1216d4d281b076580a Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 27 May 2014 09:15:22 -0400 Subject: [PATCH 15/79] mod_rayo: http_put of received fax was broken --- src/mod/event_handlers/mod_rayo/rayo_fax_components.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c index 2032feed55..1a866d4b81 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -383,7 +383,7 @@ static void insert_fax_metadata(switch_event_t *event, const char *name, iks *re static void on_execute_complete_event(switch_event_t *event) { const char *application = switch_event_get_header(event, "Application"); - + if (!zstr(application) && (!strcmp(application, "rxfax") || !strcmp(application, "txfax"))) { int is_rxfax = !strcmp(application, "rxfax"); const char *uuid = switch_event_get_header(event, "Unique-ID"); @@ -406,14 +406,15 @@ static void on_execute_complete_event(switch_event_t *event) /* RX only: transfer HTTP document and delete local copy */ if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { + char *cmd = switch_core_sprintf(RAYO_POOL(component), "%s %s", RECEIVEFAX_COMPONENT(component)->filename, RECEIVEFAX_COMPONENT(component)->local_filename); switch_stream_handle_t stream = { 0 }; SWITCH_STANDARD_STREAM(stream); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename); - switch_api_execute("http_put", RECEIVEFAX_COMPONENT(component)->filename, NULL, &stream); + switch_api_execute("http_put", cmd, NULL, &stream); /* check if successful */ if (!zstr(stream.data) && strncmp(stream.data, "+OK", 3)) { /* PUT failed */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s PUT fax to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s PUT fax %s to %s failed: %s\n", RAYO_JID(component), RECEIVEFAX_COMPONENT(component)->local_filename, RECEIVEFAX_COMPONENT(component)->filename, (char *)stream.data); have_fax_document = 0; } switch_safe_free(stream.data) From 48483452d231cda8657945cfcdae971c8c4d7e03 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 27 May 2014 10:21:56 -0400 Subject: [PATCH 16/79] mod_rayo: remove code that is no longer needed --- .../event_handlers/mod_rayo/rayo_fax_components.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c index 1a866d4b81..f47d9c1cf7 100644 --- a/src/mod/event_handlers/mod_rayo/rayo_fax_components.c +++ b/src/mod/event_handlers/mod_rayo/rayo_fax_components.c @@ -200,9 +200,6 @@ static iks *start_sendfax_component(struct rayo_actor *call, struct rayo_message switch_channel_set_variable(channel, "fax_local_station_id", NULL); switch_channel_set_variable(channel, "fax_remote_station_id", NULL); - /* clear fax interrupt variable */ - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); - rayo_call_set_faxing(RAYO_CALL(call), 1); /* execute txfax APP */ @@ -306,9 +303,6 @@ static iks *start_receivefax_component(struct rayo_actor *call, struct rayo_mess switch_channel_set_variable(channel, "fax_local_station_id", NULL); switch_channel_set_variable(channel, "fax_remote_station_id", NULL); - /* clear fax interrupt variable */ - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); - rayo_call_set_faxing(RAYO_CALL(call), 1); /* execute rxfax APP */ @@ -394,16 +388,8 @@ static void on_execute_complete_event(switch_event_t *event) iks *complete; iks *fax; int have_fax_document = 1; - switch_core_session_t *session; switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got result for %s\n", fax_jid); - /* clean up channel */ - session = switch_core_session_locate(uuid); - if (session) { - switch_channel_set_variable(switch_core_session_get_channel(session), "rayo_read_frame_interrupt", NULL); - switch_core_session_rwunlock(session); - } - /* RX only: transfer HTTP document and delete local copy */ if (is_rxfax && RECEIVEFAX_COMPONENT(component)->http_put_after_receive && switch_file_exists(RECEIVEFAX_COMPONENT(component)->local_filename, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { char *cmd = switch_core_sprintf(RAYO_POOL(component), "%s %s", RECEIVEFAX_COMPONENT(component)->filename, RECEIVEFAX_COMPONENT(component)->local_filename); From 7c2b4381cff41d4cf284dcf4a3059c946e766ddd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 27 May 2014 20:39:53 +0500 Subject: [PATCH 17/79] FS-6446 --resolve --- src/mod/endpoints/mod_sofia/sofia.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index ea4ed5544e..454e7109fb 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5464,10 +5464,8 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status tech_pvt->mparams.last_sdp_str = NULL; if (sip->sip_payload && sip->sip_payload->pl_data) { switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE); - - if (!sofia_use_soa(tech_pvt)) { - tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); - } + + tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); } @@ -6152,7 +6150,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - if (status > 100 && status < 300 && tech_pvt && !sofia_use_soa(tech_pvt) && !r_sdp && tech_pvt->mparams.last_sdp_str) { + if (tech_pvt && (status > 100 || switch_channel_test_flag(channel, CF_ANSWERED)) && status < 300 && !r_sdp && tech_pvt->mparams.last_sdp_str) { r_sdp = tech_pvt->mparams.last_sdp_str; } @@ -8193,9 +8191,11 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session, { char *call_info = NULL; switch_channel_t *channel = NULL; + private_object_t *tech_pvt = NULL; if (session) { channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); } if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) { @@ -8236,8 +8236,10 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session, } if (channel) { + tech_pvt->mparams.last_sdp_str = NULL; if (sip->sip_payload && sip->sip_payload->pl_data) { switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data); + tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); } switch_channel_execute_on(channel, "execute_on_sip_reinvite"); } From 795d974955dad33434ae01033f3b812b168a98c4 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 27 May 2014 11:20:29 -0500 Subject: [PATCH 18/79] Add CentOS 5.x build Makefile for reference --- build/Makefile.centos5 | 92 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 build/Makefile.centos5 diff --git a/build/Makefile.centos5 b/build/Makefile.centos5 new file mode 100644 index 0000000000..0fee662b2c --- /dev/null +++ b/build/Makefile.centos5 @@ -0,0 +1,92 @@ +# +# FreeSWITCH auto-build Makefile (CentOS 5.10 Wingardium Leviosa Edition) +# http://www.freeswitch.org +# put this file anywhere and type make to +# create a fully-built freeswitch.git from scratch +# in that same directory. +# +# Brian West +# +FSPREFIX=/usr/local/freeswitch +PREFIX=/opt/fs-libs +JPEG=v8d +OPENSSL=1.0.1g +SQLITE=autoconf-3080403 +PCRE=8.35 +CURL=7.36.0 +SPEEX=1.2rc1 +LIBEDIT=20140213-3.1 +LDNS=1.6.17 + +freeswitch: deps has-git freeswitch.git/Makefile + cd freeswitch.git && make + +freeswitch.git/Makefile: freeswitch.git/configure + cd freeswitch.git && PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig ./configure LDFLAGS='-L$(PREFIX)/lib -Wl,-rpath=$(PREFIX)/lib' CFLAGS='-I$(PREFIX)/include' --prefix=$(FSPREFIX) + +freeswitch.git/configure: freeswitch.git/bootstrap.sh + cd freeswitch.git && sh bootstrap.sh + +freeswitch.git/bootstrap.sh: has-git + test -d freeswitch.git || git clone git://git.freeswitch.org/freeswitch.git freeswitch.git + +install: freeswitch + cd freeswitch.git && make install + +install-git: + rpm -i http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm + yum update -y + yum install -y git gcc-c++ wget ncurses-devel zlib-devel e2fsprogs-devel libtool automake autoconf + +has-git: + @git --version || (echo "please install git by running 'make install-git'" && false) + +libjpeg: jpeg-8d/Makefile + +jpeg-8d/Makefile: + (test -d jpeg-8d) || (wget -4 -O jpegsrc.$(JPEG).tar.gz http://www.ijg.org/files/jpegsrc.$(JPEG).tar.gz && tar zxfv jpegsrc.$(JPEG).tar.gz) + (cd jpeg-8d && ./configure --prefix=$(PREFIX) && make && sudo make install) + +openssl: openssl-$(OPENSSL) + +openssl-$(OPENSSL): + (test -d $@) || (wget -4 -O $@.tar.gz http://www.openssl.org/source/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./Configure --prefix=$(PREFIX) linux-x86_64 shared && make && sudo make install) + +sqlite: sqlite-$(SQLITE) + +sqlite-$(SQLITE): + (test -d $@) || (wget -4 -O $@.tar.gz http://www.sqlite.org/2014/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +pcre: pcre-$(PCRE) + +pcre-$(PCRE): + (test -d $@) || (wget -4 -O $@.tar.gz http://downloads.sourceforge.net/project/pcre/pcre/$(PCRE)/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +curl: curl-$(CURL) + +curl-$(CURL): + (test -d $@) || (wget -4 -O $@.tar.gz http://curl.haxx.se/download/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +speex: speex-$(SPEEX) + +speex-$(SPEEX): + (test -d $@) || (wget -4 -O $@.tar.gz http://downloads.xiph.org/releases/speex/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +libedit: libedit-$(LIBEDIT) + +libedit-$(LIBEDIT): + (test -d $@) || (wget -4 -O $@.tar.gz http://thrysoee.dk/editline/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +ldns: ldns-$(LDNS) + +ldns-$(LDNS): openssl + (test -d $@) || (wget -4 -O $@.tar.gz http://www.nlnetlabs.nl/downloads/ldns/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && make && sudo make install) + +deps: libjpeg openssl sqlite pcre curl speex libedit ldns From 83f69a41e8320273e2e44dc7711002b62b36c240 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 22:29:06 +0000 Subject: [PATCH 19/79] Add in-code documentation for mod_fifo The goal here is to describe theory. We want to illuminate what the code is trying to do and what the core concepts are. --- src/mod/applications/mod_fifo/mod_fifo.c | 64 ++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 3e70790315..b77b2adc14 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -24,6 +24,7 @@ * Contributor(s): * * Anthony Minessale II + * Travis Cross * * mod_fifo.c -- FIFO * @@ -35,6 +36,69 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown); SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load); SWITCH_MODULE_DEFINITION(mod_fifo, mod_fifo_load, mod_fifo_shutdown, NULL); +/*!\file + * # Theory of operation + * + * ## Kinds of things + * + * The fifo systems deals in various kinds of things: /fifos nodes/, + * /queues/, /(inbound) callers/, /outbound callers/, /consumers/, and + * /(outbound) members/. + * + * /fifo nodes/ accept callers and work to deliver those callers to + * consumers and members. The nodes contain an array of /queues/ + * indexed by a priority value. + * + * /queues/ contain an array of callers treated as a list. + * + * /callers/ are the channels placed into a fifo node's queue for + * eventual delivery to consumers and members. + * + * /outbound callers/ are persons waiting to be called back via a + * dial string. + * + * /consumers/ are channels for agents who have dialed in to one or + * more fifos and will have callers connected to them. + * + * /members/ are agents who we'll place calls to via a dial string to + * attempt to deliver callers. + * + * An /agent/ may refer to either a /consumer/ or an /member/. + * + * ## Outbound Strategies + * + * An outbound strategy defines the way in which we attempt to deliver + * callers to members. + * + * The default strategy, /ringall/, preserves the caller ID of the + * caller being delivered. Because this means we must choose a caller + * before we place the call to the member, this impacts the order in + * which calls are delivered and the rate at which we can deliver + * those calls. + * + * The /enterprise/ outbound strategy does not preserve the caller ID + * of the caller thereby allowing deliver of callers to agents at the + * fastest possible rate. + * + * ## Manual calls + * + * The fifo system provides a way to prevent members on non-fifo calls + * from receiving a call from the fifo system. We do this by tracking + * non-fifo calls in a special fifo named `manual_calls`. When + * creating a channel for an agent we set the channel variable + * `fifo_outbound_uuid` to an arbitrary unique value for that agent, + * then call `fifo_track_call`. For the corresponding member we must + * also set `{fifo_outbound_uuid=}` to the same value. + * + * ## Importance + * + * Importance is a value 0-9 that can be associated with a fifo. The + * default value is 0. If the fifo is being dynamically created the + * importance of the fifo can be set when calling the `fifo` + * application. If the fifo already exists the importance value + * passed to the fifo application will be ignored. + */ + #define MANUAL_QUEUE_NAME "manual_calls" #define FIFO_EVENT "fifo::info" From 8ccd13bd9aa631bc51dddee2754a74719ff004dd Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 16:10:34 +0000 Subject: [PATCH 20/79] mod_fifo: Document load_config() --- src/mod/applications/mod_fifo/mod_fifo.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index b77b2adc14..c557b3ab97 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4338,6 +4338,20 @@ static void extract_fifo_outbound_uuid(char *string, char *uuid, switch_size_t l switch_event_destroy(&ovars); } +/*! + * Load or reload the configuration + * + * On the initial load, non-static members are preserved unless the + * parameter `delete-all-outbound-members-on-startup` is set. The + * parameter `del_all` is ignored in this case. + * + * On reload, non-static members are preserved unless `del_all` is + * set. + * + * \param reload true if we're reloading the config + * \param del_all delete all outbound members when reloading; + * not used unless reload is true + */ static switch_status_t load_config(int reload, int del_all) { char *cf = "fifo.conf"; From 84d6b2e35144673b5042b44ca933f1b144208a2f Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 23:03:07 +0000 Subject: [PATCH 21/79] mod_fifo: Consolidate code --- src/mod/applications/mod_fifo/mod_fifo.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index c557b3ab97..70a49dedb7 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4373,11 +4373,8 @@ static switch_status_t load_config(int reload, int del_all) if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { - char *var = NULL; - char *val = NULL; - - var = (char *) switch_xml_attr_soft(param, "name"); - val = (char *) switch_xml_attr_soft(param, "value"); + char *var = (char*)switch_xml_attr_soft(param, "name"); + char *val = (char*)switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "outbound-strategy") && !zstr(val)) { default_strategy = parse_strat(val); From 20f35e4591ad62c36c1cde259d8c7f9c0aa48ebc Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 23:04:36 +0000 Subject: [PATCH 22/79] mod_fifo: Improve function names --- src/mod/applications/mod_fifo/mod_fifo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 70a49dedb7..47a1845f78 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -395,7 +395,7 @@ struct callback { }; typedef struct callback callback_t; -static const char *strat_parse(outbound_strategy_t s) +static const char *print_strategy(outbound_strategy_t s) { switch (s) { case NODE_STRATEGY_RINGALL: @@ -409,7 +409,7 @@ static const char *strat_parse(outbound_strategy_t s) return "invalid"; } -static outbound_strategy_t parse_strat(const char *name) +static outbound_strategy_t parse_strategy(const char *name) { if (!strcasecmp(name, "ringall")) { return NODE_STRATEGY_RINGALL; @@ -4045,7 +4045,7 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve switch_snprintf(tmp, sizeof(buffer), "%u", node->outbound_priority); switch_xml_set_attr_d(x_fifo, "outbound_priority", tmp); - switch_xml_set_attr_d(x_fifo, "outbound_strategy", strat_parse(node->outbound_strategy)); + switch_xml_set_attr_d(x_fifo, "outbound_strategy", print_strategy(node->outbound_strategy)); cc_off = xml_outbound(x_fifo, node, "outbound", "member", cc_off, verbose); cc_off = xml_caller(x_fifo, node, "callers", "caller", cc_off, verbose); @@ -4091,7 +4091,7 @@ void node_dump(switch_stream_handle_t *stream) " waiting: %d\n" , node->name, node->outbound_name, node->outbound_per_cycle, - node->outbound_priority, strat_parse(node->outbound_strategy), + node->outbound_priority, print_strategy(node->outbound_strategy), node->has_outbound, node->outbound_priority, node->busy, @@ -4377,7 +4377,7 @@ static switch_status_t load_config(int reload, int del_all) char *val = (char*)switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "outbound-strategy") && !zstr(val)) { - default_strategy = parse_strat(val); + default_strategy = parse_strategy(val); } if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { @@ -4566,7 +4566,7 @@ static switch_status_t load_config(int reload, int del_all) node->default_lag = default_lag; if (outbound_strategy) { - node->outbound_strategy = parse_strat(outbound_strategy); + node->outbound_strategy = parse_strategy(outbound_strategy); node->has_outbound = 1; } From a15058406e89698f1270ef55a5b764c4a4cb2ff3 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 23:08:55 +0000 Subject: [PATCH 23/79] mod_fifo: Cleanup config parsing --- src/mod/applications/mod_fifo/mod_fifo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 47a1845f78..71b5c29395 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4378,9 +4378,7 @@ static switch_status_t load_config(int reload, int del_all) if (!strcasecmp(var, "outbound-strategy") && !zstr(val)) { default_strategy = parse_strategy(val); - } - - if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { + } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { if (switch_odbc_available() || switch_pgsql_available()) { switch_set_string(globals.odbc_dsn, val); } else { From f80e869fe096aa0bb843ada039488300056572b1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 23:24:07 +0000 Subject: [PATCH 24/79] mod_fifo: Cleanup whitespace in load_config() --- src/mod/applications/mod_fifo/mod_fifo.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 71b5c29395..fd7576d31a 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4402,7 +4402,6 @@ static switch_status_t load_config(int reload, int del_all) } } - if (!(dbh = fifo_get_db_handle())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n"); goto done; @@ -4418,11 +4417,8 @@ static switch_status_t load_config(int reload, int del_all) globals.post_trans_execute, globals.inner_pre_trans_execute, globals.inner_post_trans_execute); - switch_sql_queue_manager_start(globals.qm); - - switch_cache_db_test_reactive(dbh, "delete from fifo_outbound where static = 1 or taking_calls < 0 or stop_time < 0", "drop table fifo_outbound", outbound_sql); switch_cache_db_test_reactive(dbh, "delete from fifo_bridge", "drop table fifo_bridge", bridge_sql); @@ -4465,7 +4461,6 @@ static switch_status_t load_config(int reload, int del_all) node->is_static = 0; } - if ((fifos = switch_xml_child(cfg, "fifos"))) { for (fifo = switch_xml_child(fifos, "fifo"); fifo; fifo = fifo->next) { const char *name, *outbound_strategy; @@ -4506,14 +4501,11 @@ static switch_status_t load_config(int reload, int del_all) } switch_mutex_unlock(globals.mutex); - switch_assert(node); - switch_mutex_lock(node->mutex); outbound_strategy = switch_xml_attr(fifo, "outbound_strategy"); - if ((val = switch_xml_attr(fifo, "outbound_per_cycle"))) { if ((outbound_per_cycle = atoi(val)) < 0) { outbound_per_cycle = 1; @@ -4523,17 +4515,14 @@ static switch_status_t load_config(int reload, int del_all) if ((val = switch_xml_attr(fifo, "retry_delay"))) { int tmp; - if ((tmp = atoi(val)) < 0) { tmp = 0; } - node->retry_delay = tmp; } if ((val = switch_xml_attr(fifo, "outbound_priority"))) { outbound_priority = atoi(val); - if (outbound_priority < 1 || outbound_priority > 10) { outbound_priority = 5; } @@ -4610,7 +4599,6 @@ static switch_status_t load_config(int reload, int del_all) *p = '\0'; } - sql = switch_mprintf("insert into fifo_outbound " "(uuid, fifo_name, originate_string, simo_count, use_count, timeout, lag, " "next_avail, expires, static, outbound_call_count, outbound_fail_count, hostname, taking_calls, " @@ -4618,7 +4606,6 @@ static switch_status_t load_config(int reload, int del_all) "values ('%q','%q','%q',%d,%d,%d,%d,0,0,1,0,0,'%q',%d,%ld,0)", digest, node->name, member->txt, simo_i, 0, timeout_i, lag_i, globals.hostname, taking_calls_i, (long) switch_epoch_time_now(NULL)); - switch_assert(sql); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); free(name_dup); @@ -4630,7 +4617,6 @@ static switch_status_t load_config(int reload, int del_all) switch_mutex_unlock(node->mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s configured\n", node->name); - } } switch_xml_free(xml); @@ -4639,7 +4625,6 @@ static switch_status_t load_config(int reload, int del_all) if (reload) { fifo_node_t *node; - switch_mutex_lock(globals.mutex); for (node = globals.nodes; node; node = node->next) { if (node->ready == -1) { @@ -4651,8 +4636,6 @@ static switch_status_t load_config(int reload, int del_all) switch_mutex_unlock(globals.mutex); } - - return status; } From 31ae5b46556310da84ce2e2aa91c0670a0621bb2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sat, 24 May 2014 23:47:31 +0000 Subject: [PATCH 25/79] mod_fifo: Cleanup whitespace --- src/mod/applications/mod_fifo/mod_fifo.c | 114 +++++++++++------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index fd7576d31a..443bd5736e 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1,4 +1,4 @@ -/* +/* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005-2014, Anthony Minessale II * @@ -22,7 +22,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * + * * Anthony Minessale II * Travis Cross * @@ -594,14 +594,14 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session args.buflen = sizeof(buf); args.read_frame_callback = chime_read_frame_callback; args.user_data = user_data; - + status = switch_ivr_play_file(session, NULL, cd->list[cd->index], &args); - + if (match_key(cd->exit_key, *buf)) { cd->abort = 1; return SWITCH_STATUS_BREAK; } - + if (status != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_BREAK; } @@ -664,7 +664,7 @@ static struct { char *pre_trans_execute; char *post_trans_execute; char *inner_pre_trans_execute; - char *inner_post_trans_execute; + char *inner_post_trans_execute; switch_sql_queue_manager_t *qm; int allow_transcoding; } globals; @@ -683,11 +683,11 @@ static int fifo_dec_use_count(const char *outbound_id) } } switch_mutex_unlock(globals.use_mutex); - + return r; } -static int fifo_get_use_count(const char *outbound_id) +static int fifo_get_use_count(const char *outbound_id) { int r = 0, *count; @@ -696,12 +696,12 @@ static int fifo_get_use_count(const char *outbound_id) r = *count; } switch_mutex_unlock(globals.use_mutex); - + return r; } -static int fifo_inc_use_count(const char *outbound_id) +static int fifo_inc_use_count(const char *outbound_id) { int r = 0, *count; @@ -714,11 +714,11 @@ static int fifo_inc_use_count(const char *outbound_id) r = ++(*count); switch_mutex_unlock(globals.use_mutex); - + return r; } -static void fifo_init_use_count(void) +static void fifo_init_use_count(void) { switch_mutex_lock(globals.use_mutex); if (globals.use_hash) { @@ -861,7 +861,7 @@ switch_cache_db_handle_t *fifo_get_db_handle(void) switch_cache_db_handle_t *dbh = NULL; char *dsn; - + if (!zstr(globals.odbc_dsn)) { dsn = globals.odbc_dsn; } else { @@ -871,7 +871,7 @@ switch_cache_db_handle_t *fifo_get_db_handle(void) if (switch_cache_db_get_db_handle_dsn(&dbh, dsn) != SWITCH_STATUS_SUCCESS) { dbh = NULL; } - + return dbh; } @@ -881,7 +881,7 @@ static switch_status_t fifo_execute_sql_queued(char **sqlp, switch_bool_t sql_al char *sql; switch_assert(sqlp && *sqlp); - sql = *sqlp; + sql = *sqlp; if (switch_stristr("insert", sql)) { @@ -976,7 +976,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu callback_t cbt = { 0 }; char *sql = NULL; char *domain_name = NULL; - + if (!globals.running) { return NULL; } @@ -1007,12 +1007,12 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu cbt.len = sizeof(outbound_count); sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", name); fifo_execute_sql_callback(mutex, sql, sql2str_callback, &cbt); - node->member_count = atoi(outbound_count); + node->member_count = atoi(outbound_count); if (node->member_count > 0) { node->has_outbound = 1; } else { - node->has_outbound = 0; - } + node->has_outbound = 0; + } switch_safe_free(sql); node->importance = importance; @@ -1097,7 +1097,7 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses if ((outbound_id = switch_channel_get_variable(consumer_channel, "fifo_outbound_uuid"))) { use_count = fifo_get_use_count(outbound_id); } - + ts = switch_micro_time_now(); switch_time_exp_lt(&tm, ts); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); @@ -1462,7 +1462,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void if (use_ent) { stream.write_function(&stream, "{ignore_early_media=true,outbound_redirect_fatal=true,leg_timeout=%d,fifo_outbound_uuid=%s,fifo_name=%s}%s%s", - h->timeout, h->uuid, node->name, + h->timeout, h->uuid, node->name, parsed ? parsed : expanded_originate_string, (i == cbh->rowcount - 1) ? "" : SWITCH_ENT_ORIGINATE_DELIM); } else { stream.write_function(&stream, "[leg_timeout=%d,fifo_outbound_uuid=%s,fifo_name=%s]%s,", @@ -1591,7 +1591,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void if (!total) goto end; - if (!globals.allow_transcoding && !switch_true(switch_event_get_header(pop, "variable_fifo_allow_transcoding")) && + if (!globals.allow_transcoding && !switch_true(switch_event_get_header(pop, "variable_fifo_allow_transcoding")) && (codec = switch_event_get_header(pop, "variable_rtp_use_codec_name"))) { const char *rate = switch_event_get_header(pop, "variable_rtp_use_codec_rate"); const char *ptime = switch_event_get_header(pop, "variable_rtp_use_codec_ptime"); @@ -2099,7 +2099,7 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o } } } - + if (++cur_priority > 10) { cur_priority = 1; @@ -2514,7 +2514,7 @@ SWITCH_STANDARD_APP(fifo_function) const char *arg_fifo_name = NULL; const char *arg_inout = NULL; const char *serviced_uuid = NULL; - + if (!globals.running) { return; } @@ -3183,18 +3183,18 @@ SWITCH_STANDARD_APP(fifo_function) if (!(switch_channel_ready(channel))) { const char *app = switch_channel_get_variable(other_channel, "current_application"); const char *arg = switch_channel_get_variable(other_channel, "current_application_data"); - switch_caller_extension_t *extension = NULL; + switch_caller_extension_t *extension = NULL; - switch_channel_set_variable_printf(channel, "last_sent_callee_id_name", "%s (AGENT FAIL)", + switch_channel_set_variable_printf(channel, "last_sent_callee_id_name", "%s (AGENT FAIL)", switch_channel_get_variable(other_channel, "caller_id_name")); switch_channel_set_variable(channel, "last_sent_callee_id_number", switch_channel_get_variable(other_channel, "caller_id_number")); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Customer %s %s [%s] appears to be abandoned by agent %s [%s] " "but is still on the line, redirecting them back to the queue with VIP status.\n", - switch_channel_get_name(other_channel), - switch_channel_get_variable(other_channel, "caller_id_name"), + switch_channel_get_name(other_channel), + switch_channel_get_variable(other_channel, "caller_id_name"), switch_channel_get_variable(other_channel, "caller_id_number"), switch_channel_get_variable(channel, "caller_id_name"), switch_channel_get_variable(channel, "caller_id_number")); @@ -3203,7 +3203,7 @@ SWITCH_STANDARD_APP(fifo_function) send_presence(node); check_cancel(node); - + if (app) { extension = switch_caller_extension_new(other_session, app, arg); switch_caller_extension_add_application(other_session, extension, app, arg); @@ -3232,18 +3232,18 @@ SWITCH_STANDARD_APP(fifo_function) originator_cp = switch_channel_get_caller_profile(channel); originatee_cp = switch_channel_get_caller_profile(other_channel); - + switch_channel_set_originator_caller_profile(other_channel, switch_caller_profile_clone(other_session, originator_cp)); switch_channel_set_originatee_caller_profile(channel, switch_caller_profile_clone(session, originatee_cp)); - - + + originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name); originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number); originatee_cp->callee_id_name = switch_core_strdup(originatee_cp->pool, originatee_cp->caller_id_name); originatee_cp->callee_id_number = switch_core_strdup(originatee_cp->pool, originatee_cp->caller_id_number); - + originatee_cp->caller_id_name = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_name); originatee_cp->caller_id_number = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_number); @@ -3327,7 +3327,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_fire(&event); } - + add_bridge_call(switch_core_session_get_uuid(other_session)); add_bridge_call(switch_core_session_get_uuid(session)); @@ -3361,7 +3361,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_variable(switch_core_session_get_channel(other_session), "fifo_initiated_bridge", NULL); switch_channel_set_variable(switch_core_session_get_channel(other_session), "fifo_bridge_role", NULL); } - + if (switch_channel_test_flag(channel, CF_TRANSFER) && switch_channel_up(channel)) { switch_channel_set_variable(switch_core_session_get_channel(other_session), "fifo_initiated_bridge", NULL); switch_channel_set_variable(switch_core_session_get_channel(other_session), "fifo_bridge_role", NULL); @@ -3404,7 +3404,7 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-us", "%"SWITCH_TIME_T_FMT, hold_usec); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-ms", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Hold-Time-s", "%"SWITCH_TIME_T_FMT, (uint64_t)(hold_usec / 1000000)); - + switch_event_fire(&event); } @@ -3419,7 +3419,7 @@ SWITCH_STANDARD_APP(fifo_function) if (outbound_id) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Outbound-ID", outbound_id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Consumer-Use-Count", "%d", fifo_get_use_count(outbound_id)); - } + } switch_event_fire(&event); } if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { @@ -3599,7 +3599,7 @@ SWITCH_STANDARD_APP(fifo_function) continue; } switch_thread_rwlock_unlock(node->rwlock); - + if (node->ready == 1 && do_destroy && node_caller_count(node) == 0 && node->consumer_count == 0) { switch_core_hash_delete(globals.fifo_hash, node->name); node->ready = 0; @@ -4370,7 +4370,7 @@ static switch_status_t load_config(int reload, int del_all) } globals.dbname = "fifo"; - + if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char*)switch_xml_attr_soft(param, "name"); @@ -4644,8 +4644,8 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co { char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 }; char *sql, *name_dup, *p; - char outbound_count[80] = ""; - callback_t cbt = { 0 }; + char outbound_count[80] = ""; + callback_t cbt = { 0 }; fifo_node_t *node = NULL; if (!fifo_name) return; @@ -4683,17 +4683,17 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); free(name_dup); - cbt.buf = outbound_count; - cbt.len = sizeof(outbound_count); - sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", fifo_name); - fifo_execute_sql_callback(globals.sql_mutex, sql, sql2str_callback, &cbt); - node->member_count = atoi(outbound_count); - if (node->member_count > 0) { - node->has_outbound = 1; - } else { - node->has_outbound = 0; - } - switch_safe_free(sql); + cbt.buf = outbound_count; + cbt.len = sizeof(outbound_count); + sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", fifo_name); + fifo_execute_sql_callback(globals.sql_mutex, sql, sql2str_callback, &cbt); + node->member_count = atoi(outbound_count); + if (node->member_count > 0) { + node->has_outbound = 1; + } else { + node->has_outbound = 0; + } + switch_safe_free(sql); } static void fifo_member_del(char *fifo_name, char *originate_string) @@ -4728,11 +4728,11 @@ static void fifo_member_del(char *fifo_name, char *originate_string) cbt.len = sizeof(outbound_count); sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", node->name); fifo_execute_sql_callback(globals.sql_mutex, sql, sql2str_callback, &cbt); - node->member_count = atoi(outbound_count); + node->member_count = atoi(outbound_count); if (node->member_count > 0) { - node->has_outbound = 1; + node->has_outbound = 1; } else { - node->has_outbound = 0; + node->has_outbound = 0; } switch_safe_free(sql); } @@ -4920,7 +4920,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) this_node = node; node = node->next; - + switch_mutex_lock(this_node->update_mutex); switch_mutex_lock(this_node->mutex); for (x = 0; x < MAX_PRI; x++) { From 06d94d2c173b5fc534bfcc9463eecadf82c3179a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 13:54:25 +0000 Subject: [PATCH 26/79] mod_fifo: Move straggling vars to global struct --- src/mod/applications/mod_fifo/mod_fifo.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 443bd5736e..1b8c0c8fde 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -111,8 +111,6 @@ typedef enum { NODE_STRATEGY_ENTERPRISE } outbound_strategy_t; -static outbound_strategy_t default_strategy = NODE_STRATEGY_RINGALL; - static int marker = 1; typedef struct { @@ -667,6 +665,8 @@ static struct { char *inner_post_trans_execute; switch_sql_queue_manager_t *qm; int allow_transcoding; + switch_bool_t delete_all_members_on_startup; + outbound_strategy_t default_strategy; } globals; @@ -986,7 +986,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu node = switch_core_alloc(pool, sizeof(*node)); node->pool = pool; - node->outbound_strategy = default_strategy; + node->outbound_strategy = globals.default_strategy; node->name = switch_core_strdup(node->pool, name); if (!strchr(name, '@')) { @@ -4358,7 +4358,6 @@ static switch_status_t load_config(int reload, int del_all) switch_xml_t cfg, xml, fifo, fifos, member, settings, param; switch_status_t status = SWITCH_STATUS_SUCCESS; char *sql; - switch_bool_t delete_all_outbound_member_on_startup = SWITCH_FALSE; switch_cache_db_handle_t *dbh = NULL; fifo_node_t *node; @@ -4370,14 +4369,15 @@ static switch_status_t load_config(int reload, int del_all) } globals.dbname = "fifo"; - + globals.default_strategy = NODE_STRATEGY_RINGALL; + globals.delete_all_members_on_startup = SWITCH_FALSE; if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char*)switch_xml_attr_soft(param, "name"); char *val = (char*)switch_xml_attr_soft(param, "value"); if (!strcasecmp(var, "outbound-strategy") && !zstr(val)) { - default_strategy = parse_strategy(val); + globals.default_strategy = parse_strategy(val); } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { if (switch_odbc_available() || switch_pgsql_available()) { switch_set_string(globals.odbc_dsn, val); @@ -4397,7 +4397,7 @@ static switch_status_t load_config(int reload, int del_all) } else if (!strcasecmp(var, "db-inner-post-trans-execute") && !zstr(val)) { globals.inner_post_trans_execute = switch_core_strdup(globals.pool, val); } else if (!strcasecmp(var, "delete-all-outbound-member-on-startup")) { - delete_all_outbound_member_on_startup = switch_true(val); + globals.delete_all_members_on_startup = switch_true(val); } } } @@ -4447,7 +4447,7 @@ static switch_status_t load_config(int reload, int del_all) switch_mutex_unlock(globals.mutex); } - if ((reload && del_all) || (!reload && delete_all_outbound_member_on_startup)) { + if ((reload && del_all) || (!reload && globals.delete_all_members_on_startup)) { sql = switch_mprintf("delete from fifo_outbound where hostname='%q'", globals.hostname); } else { sql = switch_mprintf("delete from fifo_outbound where static=1 and hostname='%q'", globals.hostname); From a3a62d2481c2fc06c9c91a8051c2a260f8e52e19 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 14:27:01 +0000 Subject: [PATCH 27/79] mod_fifo: Convert macro to fn and improve name --- src/mod/applications/mod_fifo/mod_fifo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 1b8c0c8fde..251f596180 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -508,7 +508,9 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, return SWITCH_STATUS_SUCCESS; } -#define check_string(s) if (!zstr(s) && !strcasecmp(s, "undef")) { s = NULL; } +static inline void cleanup_fifo_arg(const char **s) { + if (!zstr(*s) && !strcasecmp(*s, "undef")) *s = NULL; +} static int node_caller_count(fifo_node_t *node) { @@ -2607,8 +2609,8 @@ SWITCH_STANDARD_APP(fifo_function) moh = NULL; } - check_string(announce); - check_string(moh); + cleanup_fifo_arg(&announce); + cleanup_fifo_arg(&moh); switch_assert(node); switch_core_media_bug_pause(session); From c6e90e01112e2b7d5c1ae5ac6ae383ad93488aa0 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 14:46:19 +0000 Subject: [PATCH 28/79] mod_fifo: Refactor out config file reading --- src/mod/applications/mod_fifo/mod_fifo.c | 67 +++++++++++++----------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 251f596180..8a87e2d473 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4340,40 +4340,16 @@ static void extract_fifo_outbound_uuid(char *string, char *uuid, switch_size_t l switch_event_destroy(&ovars); } -/*! - * Load or reload the configuration - * - * On the initial load, non-static members are preserved unless the - * parameter `delete-all-outbound-members-on-startup` is set. The - * parameter `del_all` is ignored in this case. - * - * On reload, non-static members are preserved unless `del_all` is - * set. - * - * \param reload true if we're reloading the config - * \param del_all delete all outbound members when reloading; - * not used unless reload is true - */ -static switch_status_t load_config(int reload, int del_all) -{ - char *cf = "fifo.conf"; - switch_xml_t cfg, xml, fifo, fifos, member, settings, param; - switch_status_t status = SWITCH_STATUS_SUCCESS; - char *sql; - switch_cache_db_handle_t *dbh = NULL; - fifo_node_t *node; +static switch_status_t read_config_file(switch_xml_t *xml, switch_xml_t *cfg) { + const char *cf = "fifo.conf"; + switch_xml_t settings; - strncpy(globals.hostname, switch_core_get_switchname(), sizeof(globals.hostname) - 1); - - if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { + if (!(*xml = switch_xml_open_cfg(cf, cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf); return SWITCH_STATUS_TERM; } - - globals.dbname = "fifo"; - globals.default_strategy = NODE_STRATEGY_RINGALL; - globals.delete_all_members_on_startup = SWITCH_FALSE; - if ((settings = switch_xml_child(cfg, "settings"))) { + if ((settings = switch_xml_child(*cfg, "settings"))) { + switch_xml_t param; for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *var = (char*)switch_xml_attr_soft(param, "name"); char *val = (char*)switch_xml_attr_soft(param, "value"); @@ -4403,6 +4379,37 @@ static switch_status_t load_config(int reload, int del_all) } } } + return SWITCH_STATUS_SUCCESS; +} + +/*! + * Load or reload the configuration + * + * On the initial load, non-static members are preserved unless the + * parameter `delete-all-outbound-members-on-startup` is set. The + * parameter `del_all` is ignored in this case. + * + * On reload, non-static members are preserved unless `del_all` is + * set. + * + * \param reload true if we're reloading the config + * \param del_all delete all outbound members when reloading; + * not used unless reload is true + */ +static switch_status_t load_config(int reload, int del_all) +{ + switch_xml_t xml, cfg, fifo, fifos, member; + switch_status_t status = SWITCH_STATUS_SUCCESS; + char *sql; + switch_cache_db_handle_t *dbh = NULL; + fifo_node_t *node; + + strncpy(globals.hostname, switch_core_get_switchname(), sizeof(globals.hostname) - 1); + globals.dbname = "fifo"; + globals.default_strategy = NODE_STRATEGY_RINGALL; + globals.delete_all_members_on_startup = SWITCH_FALSE; + + if ((status = read_config_file(&xml, &cfg)) != SWITCH_STATUS_SUCCESS) return status; if (!(dbh = fifo_get_db_handle())) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot open DB!\n"); From 2068b284ccd9d6312e75a571d85aefc3305788d6 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 14:48:47 +0000 Subject: [PATCH 29/79] mod_fifo: Fix memory leak of xml structure If getting the DB handle failed during the load or reload of the configuration, we would leak the XML structure we just allocated for the configuration. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 8a87e2d473..de82ff0575 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4628,10 +4628,10 @@ static switch_status_t load_config(int reload, int del_all) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s configured\n", node->name); } } - switch_xml_free(xml); done: + switch_xml_free(xml); if (reload) { fifo_node_t *node; switch_mutex_lock(globals.mutex); From 0526e00457a06644b8298b43281cc34c28d247b9 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 15:48:17 +0000 Subject: [PATCH 30/79] mod_fifo: Replace global var with local static This marker value is only used in one place. --- src/mod/applications/mod_fifo/mod_fifo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index de82ff0575..a8fcd88c41 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -111,8 +111,6 @@ typedef enum { NODE_STRATEGY_ENTERPRISE } outbound_strategy_t; -static int marker = 1; - typedef struct { int nelm; int idx; @@ -796,6 +794,7 @@ static int check_bridge_call(const char *key) static void add_bridge_call(const char *key) { + static int marker = 1; if (!key) return; switch_mutex_lock(globals.bridge_mutex); From 1f7589d6fa7a152442a24e119190350b93943196 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 15:57:39 +0000 Subject: [PATCH 31/79] mod_fifo: Refactor --- src/mod/applications/mod_fifo/mod_fifo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index a8fcd88c41..6d9f8da59d 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4481,9 +4481,7 @@ static switch_status_t load_config(int reload, int del_all) int ring_timeout = 60; int default_lag = 30; - name = switch_xml_attr(fifo, "name"); - - if (!name) { + if (!(name = switch_xml_attr(fifo, "name"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fifo has no name!\n"); continue; } From 17070e9dac68d2a0912e7cb7112c723db2c986fd Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 16:07:35 +0000 Subject: [PATCH 32/79] mod_fifo: Improve strategy thread function names --- src/mod/applications/mod_fifo/mod_fifo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 6d9f8da59d..a5e24c6388 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1342,7 +1342,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ } -static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void *obj) +static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thread, void *obj) { struct callback_helper *cbh = (struct callback_helper *) obj; char *node_name; @@ -1744,7 +1744,7 @@ static void *SWITCH_THREAD_FUNC ringall_thread_run(switch_thread_t *thread, void return NULL; } -static void *SWITCH_THREAD_FUNC o_thread_run(switch_thread_t *thread, void *obj) +static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t *thread, void *obj) { struct call_helper *h = (struct call_helper *) obj; @@ -1946,7 +1946,7 @@ static int place_call_enterprise_callback(void *pArg, int argc, char **argv, cha switch_threadattr_create(&thd_attr, h->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, o_thread_run, h, h->pool); + switch_thread_create(&thread, thd_attr, outbound_enterprise_thread_run, h, h->pool); (*need)--; @@ -2003,7 +2003,7 @@ static void find_consumers(fifo_node_t *node) switch_threadattr_create(&thd_attr, cbh->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&thread, thd_attr, ringall_thread_run, cbh, cbh->pool); + switch_thread_create(&thread, thd_attr, outbound_ringall_thread_run, cbh, cbh->pool); } else { switch_core_destroy_memory_pool(&pool); } From 353c3b19fae384797d04ae0f793df4034d2b8112 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Sun, 25 May 2014 16:46:44 +0000 Subject: [PATCH 33/79] mod_fifo: Document fifo_node::outbound_name --- src/mod/applications/mod_fifo/mod_fifo.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index a5e24c6388..949717d93c 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -348,6 +348,19 @@ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid) +/*! + * \struct fifo_node + * + * \var fifo_node::outbound_name + * \brief Name of fifo in caller ID + * + * For the ringall strategy, this value is a prefix for the + * caller ID shown to agents. If the value starts with '=' then the + * actual caller ID is replaced completely. + * + * For the enterprise strategy, this value is used instead of the + * queue name in the caller ID. + */ struct fifo_node { char *name; switch_mutex_t *mutex; From 6105e9783c98499c939c47c39ff596cda768bf8b Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 05:17:19 +0000 Subject: [PATCH 34/79] mod_fifo: Refactor load_config() Reduce number of local variables where possible; consolidate lines. --- src/mod/applications/mod_fifo/mod_fifo.c | 95 +++++++++--------------- 1 file changed, 36 insertions(+), 59 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 949717d93c..2bc691eb0e 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4484,15 +4484,9 @@ static switch_status_t load_config(int reload, int del_all) if ((fifos = switch_xml_child(cfg, "fifos"))) { for (fifo = switch_xml_child(fifos, "fifo"); fifo; fifo = fifo->next) { - const char *name, *outbound_strategy; + const char *name, *sp; const char *val; - int imp = 0, outbound_per_cycle = 1, outbound_priority = 5; - int simo_i = 1; - int taking_calls_i = 1; - int timeout_i = 60; - int lag_i = 10; - int ring_timeout = 60; - int default_lag = 30; + int i, importance = 0; if (!(name = switch_xml_attr(fifo, "name"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "fifo has no name!\n"); @@ -4504,15 +4498,13 @@ static switch_status_t load_config(int reload, int del_all) continue; } - if ((val = switch_xml_attr(fifo, "importance"))) { - if ((imp = atoi(val)) < 0) { - imp = 0; - } + if ((val = switch_xml_attr(fifo, "importance")) && !(i = atoi(val)) < 0) { + importance = i; } switch_mutex_lock(globals.mutex); if (!(node = switch_core_hash_find(globals.fifo_hash, name))) { - node = create_node(name, imp, globals.sql_mutex); + node = create_node(name, importance, globals.sql_mutex); } if ((val = switch_xml_attr(fifo, "outbound_name"))) { @@ -4523,64 +4515,54 @@ static switch_status_t load_config(int reload, int del_all) switch_assert(node); switch_mutex_lock(node->mutex); - outbound_strategy = switch_xml_attr(fifo, "outbound_strategy"); + if ((sp = switch_xml_attr(fifo, "outbound_strategy"))) { + node->outbound_strategy = parse_strategy(sp); + node->has_outbound = 1; + } + node->outbound_per_cycle = 1; if ((val = switch_xml_attr(fifo, "outbound_per_cycle"))) { - if ((outbound_per_cycle = atoi(val)) < 0) { - outbound_per_cycle = 1; + if (!(i = atoi(val)) < 0) { + node->outbound_per_cycle = i; } node->has_outbound = 1; } if ((val = switch_xml_attr(fifo, "retry_delay"))) { - int tmp; - if ((tmp = atoi(val)) < 0) { - tmp = 0; - } - node->retry_delay = tmp; + if ((i = atoi(val)) < 0) i = 0; + node->retry_delay = i; } + node->outbound_priority = 5; if ((val = switch_xml_attr(fifo, "outbound_priority"))) { - outbound_priority = atoi(val); - if (outbound_priority < 1 || outbound_priority > 10) { - outbound_priority = 5; + i = atoi(val); + if (!(i < 1 || i > 10)) { + node->outbound_priority = i; } node->has_outbound = 1; } + node->ring_timeout = 60; if ((val = switch_xml_attr(fifo, "outbound_ring_timeout"))) { - int tmp = atoi(val); - if (tmp > 10) { - ring_timeout = tmp; + if ((i = atoi(val)) > 10) { + node->ring_timeout = i; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid ring_timeout: must be > 10 for queue %s\n", node->name); } } + node->default_lag = 30; if ((val = switch_xml_attr(fifo, "outbound_default_lag"))) { - int tmp = atoi(val); - if (tmp > 10) { - default_lag = tmp; + if ((i = atoi(val)) > 10) { + node->default_lag = i; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Invalid default_lag: must be > 10 for queue %s\n", node->name); } } - node->ring_timeout = ring_timeout; - node->outbound_per_cycle = outbound_per_cycle; - node->outbound_priority = outbound_priority; - node->default_lag = default_lag; - - if (outbound_strategy) { - node->outbound_strategy = parse_strategy(outbound_strategy); - node->has_outbound = 1; - } - for (member = switch_xml_child(fifo, "member"); member; member = member->next) { - const char *simo = switch_xml_attr_soft(member, "simo"); - const char *lag = switch_xml_attr_soft(member, "lag"); - const char *timeout = switch_xml_attr_soft(member, "timeout"); - const char *taking_calls = switch_xml_attr_soft(member, "taking_calls"); + const char *simo, *taking_calls, *timeout, *lag; + int simo_i = 1, taking_calls_i = 1, timeout_i = 60, lag_i = 10; char *name_dup, *p; char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 }; @@ -4590,27 +4572,23 @@ static switch_status_t load_config(int reload, int del_all) switch_md5_string(digest, (void *) member->txt, strlen(member->txt)); } - if (simo) { + if ((simo = switch_xml_attr_soft(member, "simo"))) { simo_i = atoi(simo); } - if (taking_calls) { - if ((taking_calls_i = atoi(taking_calls)) < 1) { - taking_calls_i = 1; - } + if ((taking_calls = switch_xml_attr_soft(member, "taking_calls")) + && (taking_calls_i = atoi(taking_calls)) < 1) { + taking_calls_i = 1; } - if (timeout) { - if ((timeout_i = atoi(timeout)) < 10) { - timeout_i = ring_timeout; - } - + if ((timeout = switch_xml_attr_soft(member, "timeout")) + && (timeout_i = atoi(timeout)) < 10) { + timeout_i = node->ring_timeout; } - if (lag) { - if ((lag_i = atoi(lag)) < 0) { - lag_i = default_lag; - } + if ((lag = switch_xml_attr_soft(member, "lag")) + && (lag_i = atoi(lag)) < 0) { + lag_i = node->default_lag; } name_dup = strdup(node->name); @@ -4634,7 +4612,6 @@ static switch_status_t load_config(int reload, int del_all) node->ready = 1; node->is_static = 1; switch_mutex_unlock(node->mutex); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s configured\n", node->name); } } From 628b6c19ab7a9d4c2b91bc49ba0be53b08261263 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 05:24:14 +0000 Subject: [PATCH 35/79] mod_fifo: Remove dead code We were making a copy of the fifo name and stripping any domain name, but then not using the value. --- src/mod/applications/mod_fifo/mod_fifo.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 2bc691eb0e..d2b8a4a520 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4563,7 +4563,6 @@ static switch_status_t load_config(int reload, int del_all) for (member = switch_xml_child(fifo, "member"); member; member = member->next) { const char *simo, *taking_calls, *timeout, *lag; int simo_i = 1, taking_calls_i = 1, timeout_i = 60, lag_i = 10; - char *name_dup, *p; char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 }; if (switch_stristr("fifo_outbound_uuid=", member->txt)) { @@ -4591,11 +4590,6 @@ static switch_status_t load_config(int reload, int del_all) lag_i = node->default_lag; } - name_dup = strdup(node->name); - if ((p = strchr(name_dup, '@'))) { - *p = '\0'; - } - sql = switch_mprintf("insert into fifo_outbound " "(uuid, fifo_name, originate_string, simo_count, use_count, timeout, lag, " "next_avail, expires, static, outbound_call_count, outbound_fail_count, hostname, taking_calls, " @@ -4605,7 +4599,6 @@ static switch_status_t load_config(int reload, int del_all) (long) switch_epoch_time_now(NULL)); switch_assert(sql); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); - free(name_dup); node->has_outbound = 1; node->member_count++; } From e677da587044dfdea2cddf2b3edcb7f0d18cc247 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 05:33:02 +0000 Subject: [PATCH 36/79] mod_fifo: Refactor in create_node() --- src/mod/applications/mod_fifo/mod_fifo.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index d2b8a4a520..d684773b19 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -995,7 +995,6 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu return NULL; } - switch_core_new_memory_pool(&pool); node = switch_core_alloc(pool, sizeof(*node)); @@ -1022,11 +1021,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu sql = switch_mprintf("select count(*) from fifo_outbound where fifo_name = '%q'", name); fifo_execute_sql_callback(mutex, sql, sql2str_callback, &cbt); node->member_count = atoi(outbound_count); - if (node->member_count > 0) { - node->has_outbound = 1; - } else { - node->has_outbound = 0; - } + node->has_outbound = (node->member_count > 0) ? 1 : 0; switch_safe_free(sql); node->importance = importance; From e241477860fabc7424d3a4c3a2c60c4573ea193a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 14:42:06 +0000 Subject: [PATCH 37/79] mod_fifo: Tighten up some whitespace --- src/mod/applications/mod_fifo/mod_fifo.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index d684773b19..d60cc71e26 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -166,37 +166,26 @@ static void change_pos(switch_event_t *event, int pos) char tmp[30] = ""; if (zstr(uuid)) return; - if (!(session = switch_core_session_locate(uuid))) { return; } - channel = switch_core_session_get_channel(session); - switch_snprintf(tmp, sizeof(tmp), "%d", pos); switch_channel_set_variable(channel, "fifo_position", tmp); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fifo_position", tmp); - switch_core_session_rwunlock(session); - - } static switch_status_t fifo_queue_push(fifo_queue_t *queue, switch_event_t *ptr) { switch_mutex_lock(queue->mutex); - if (queue->idx == queue->nelm) { switch_mutex_unlock(queue->mutex); return SWITCH_STATUS_FALSE; } - queue->data[queue->idx++] = ptr; - switch_mutex_unlock(queue->mutex); - return SWITCH_STATUS_SUCCESS; - } static int fifo_queue_size(fifo_queue_t *queue) @@ -205,7 +194,6 @@ static int fifo_queue_size(fifo_queue_t *queue) switch_mutex_lock(queue->mutex); s = queue->idx; switch_mutex_unlock(queue->mutex); - return s; } @@ -248,9 +236,7 @@ static switch_status_t fifo_queue_pop(fifo_queue_t *queue, switch_event_t **pop, } switch_mutex_unlock(queue->mutex); - return SWITCH_STATUS_SUCCESS; - } From 1eaf4b50caae97ebc4d8aa25e3ad9e6363f70f93 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 14:42:20 +0000 Subject: [PATCH 38/79] mod_fifo: Document remove parameter of fifo_queue_pop() --- src/mod/applications/mod_fifo/mod_fifo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index d60cc71e26..1cf1d0cf9e 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -197,6 +197,12 @@ static int fifo_queue_size(fifo_queue_t *queue) return s; } +/*! + * \param remove Whether to remove the popped event from the queue + * If remove is 0, do not remove the popped event. If it is 1, remove + * it if it is not an event for an outbound caller. If it is 2, + * always remove it. + */ static switch_status_t fifo_queue_pop(fifo_queue_t *queue, switch_event_t **pop, int remove) { int i, j; From b914c2374dbff745c814559f78e9cab85dd1d93d Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 14:52:04 +0000 Subject: [PATCH 39/79] mod_fifo: Document fifo_queue_pop_nameval() --- src/mod/applications/mod_fifo/mod_fifo.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 1cf1d0cf9e..ba05976f2e 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -245,7 +245,16 @@ static switch_status_t fifo_queue_pop(fifo_queue_t *queue, switch_event_t **pop, return SWITCH_STATUS_SUCCESS; } - +/*! \brief Remove matching event from queue + * + * Each event in the queue will be checked to see whether it has a + * header equal to name whose value is equal to val. If it does, that + * event will be returned unless the event is for an outbound caller. + * If name starts with '+' or remove == 2 then forcing is enabled and + * the event will be returned in any case. If remove > 0 then the + * returned event will be removed from the queue and the remaining + * elements shifted to make them contiguous. + */ static switch_status_t fifo_queue_pop_nameval(fifo_queue_t *queue, const char *name, const char *val, switch_event_t **pop, int remove) { int i, j, force = 0; From 077579b131d7d8c0fcc3540a39f003943b999f09 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 15:01:06 +0000 Subject: [PATCH 40/79] mod_fifo: Document fifo_queue_popfly() --- src/mod/applications/mod_fifo/mod_fifo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index ba05976f2e..4621f29be1 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -309,6 +309,12 @@ static switch_status_t fifo_queue_pop_nameval(fifo_queue_t *queue, const char *n return SWITCH_STATUS_SUCCESS; } +/*! \brief Destroy event with given uuid and remove it from queue + * + * Elements of the queue are searched until a matching uuid is found. + * That uuid is then destroyed and removed from the queue. The + * remaining elements are shifted to make them contiguous. + */ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid) { int i, j; From c34ad2c0eceeb44253cc87067dbc8d8d3563cec3 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 15:09:20 +0000 Subject: [PATCH 41/79] mod_fifo: Avoid getting a var when we won't use it --- src/mod/applications/mod_fifo/mod_fifo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 4621f29be1..fdd68441d3 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -468,9 +468,8 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit switch_channel_t *bchan = switch_core_session_get_channel(bleg); switch_channel_t *channel = switch_core_session_get_channel(session); - const char *consumer_exit_key = switch_channel_get_variable(channel, "fifo_consumer_exit_key"); - if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_BRIDGE_ORIGINATOR)) { + const char *consumer_exit_key = switch_channel_get_variable(channel, "fifo_consumer_exit_key"); if (consumer_exit_key && dtmf->digit == *consumer_exit_key) { switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING); return SWITCH_STATUS_BREAK; From 7920630c8f5b3ad55bf867093ffb53cc6ec41cb6 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 15:20:38 +0000 Subject: [PATCH 42/79] mod_fifo: Refactor DTMF exit key matching --- src/mod/applications/mod_fifo/mod_fifo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index fdd68441d3..8f78c85711 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -470,10 +470,8 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_BRIDGE_ORIGINATOR)) { const char *consumer_exit_key = switch_channel_get_variable(channel, "fifo_consumer_exit_key"); - if (consumer_exit_key && dtmf->digit == *consumer_exit_key) { - switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING); - return SWITCH_STATUS_BREAK; - } else if (!consumer_exit_key && dtmf->digit == '*') { + if (!consumer_exit_key) consumer_exit_key = "*"; + if (dtmf->digit == *consumer_exit_key) { switch_channel_hangup(bchan, SWITCH_CAUSE_NORMAL_CLEARING); return SWITCH_STATUS_BREAK; } else if (dtmf->digit == '0') { From 27b3ddcc9f3dc7c92ef26f754d9aa630d61e97fb Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 16:02:17 +0000 Subject: [PATCH 43/79] mod_fifo: Document the consumer DTMF callback --- src/mod/applications/mod_fifo/mod_fifo.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 8f78c85711..31bcbec9bc 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -457,6 +457,19 @@ static switch_bool_t match_key(const char *caller_exit_key, char key) return SWITCH_FALSE; } +/*! \brief Handler for consumer DTMF + * + * When `fifo_consumer_exit_key` is pressed by the consumer we hangup + * on the caller (unless we've put the caller on hold). The default + * exit key is '*'. + * + * When the consumer presses '0' we put both legs on hold and play + * hold music as follows. To the caller we play `fifo_music` or the + * default hold music for the channel. To the consumer we play + * `fifo_hold_music`, or `fifo_music`, or the default hold music for + * the channel. The consumer can press '0' again to pick up the + * caller from hold. + */ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { switch_core_session_t *bleg = (switch_core_session_t *) buf; From 3e6199eace5903a952ae993b3797fe612d1db6c1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 16:19:34 +0000 Subject: [PATCH 44/79] mod_fifo: Remove reimplementation of strchr() --- src/mod/applications/mod_fifo/mod_fifo.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 31bcbec9bc..d6a2159897 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -447,16 +447,6 @@ static int sql2str_callback(void *pArg, int argc, char **argv, char **columnName return 0; } -static switch_bool_t match_key(const char *caller_exit_key, char key) -{ - while (caller_exit_key && *caller_exit_key) { - if (*caller_exit_key++ == key) { - return SWITCH_TRUE; - } - } - return SWITCH_FALSE; -} - /*! \brief Handler for consumer DTMF * * When `fifo_consumer_exit_key` is pressed by the consumer we hangup @@ -522,7 +512,7 @@ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_channel_t *channel = switch_core_session_get_channel(session); const char *caller_exit_key = switch_channel_get_variable(channel, "fifo_caller_exit_key"); - if (match_key(caller_exit_key, dtmf->digit)) { + if (caller_exit_key && dtmf->digit && strchr(caller_exit_key, dtmf->digit)) { char *bp = buf; *bp = dtmf->digit; return SWITCH_STATUS_BREAK; @@ -625,7 +615,7 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session status = switch_ivr_play_file(session, NULL, cd->list[cd->index], &args); - if (match_key(cd->exit_key, *buf)) { + if (cd->exit_key && *buf && strchr(cd->exit_key, *buf)) { cd->abort = 1; return SWITCH_STATUS_BREAK; } @@ -2781,7 +2771,7 @@ SWITCH_STANDARD_APP(fifo_function) goto abort; } - if (match_key(caller_exit_key, *buf)) { + if (caller_exit_key && *buf && strchr(caller_exit_key, *buf)) { switch_channel_set_variable(channel, "fifo_caller_exit_key", (char *)buf); aborted = 1; goto abort; From 2c7c15261d672b46b5526dd7a30ec7511689d9bd Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 17:34:22 +0000 Subject: [PATCH 45/79] mod_fifo: Document caller DTMF handler --- src/mod/applications/mod_fifo/mod_fifo.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index d6a2159897..8db7a5c545 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -503,6 +503,13 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit return SWITCH_STATUS_SUCCESS; } +/*! \brief Handler for caller DTMF + * + * The channel variable `fifo_caller_exit_key` can be set to one or + * more digits that when pressed will cause the caller to exit from + * the fifo. We'll return via a single character in `buf` the digit + * that was pressed (not null-terminated). + */ static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { switch (itype) { From 5f4ed9c123593263f4f6d3de033e156d319289f1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 17:50:43 +0000 Subject: [PATCH 46/79] mod_fifo: Document fifo_chime_data::list --- src/mod/applications/mod_fifo/mod_fifo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 8db7a5c545..911cd1fa4d 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -565,6 +565,12 @@ static void node_remove_uuid(fifo_node_t *node, const char *uuid) return; } +/*!\struct fifo_chime_data + * + * \var fifo_chime_data::list + * A list of strings representing things to play back to the caller + * while they are waiting to be connected with an agent. + */ #define MAX_CHIME 25 struct fifo_chime_data { char *list[MAX_CHIME]; From 42ebfbfc5980baa35fbf9c1e4704201ec8dfcb8f Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 18:00:02 +0000 Subject: [PATCH 47/79] mod_fifo: Document the fifo_queue_t structure --- src/mod/applications/mod_fifo/mod_fifo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 911cd1fa4d..42f030d3c5 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -111,6 +111,16 @@ typedef enum { NODE_STRATEGY_ENTERPRISE } outbound_strategy_t; +/*!\struct fifo_queue_t + * \brief Queue of callers + * + * Callers are placed into a queue as events in `data` which is an + * array of such events. The array size is hard-coded as 1000 + * elements. + * + * Fifo nodes are composed of an array of these queues representing + * each priority level of the fifo. + */ typedef struct { int nelm; int idx; From edecd151a51ad292ffa0f9d3b2f34593d3d4afc3 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 18:21:45 +0000 Subject: [PATCH 48/79] mod_fifo: Document the read_frame_callbacks --- src/mod/applications/mod_fifo/mod_fifo.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 42f030d3c5..09da73cd21 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -599,6 +599,11 @@ struct fifo_chime_data { typedef struct fifo_chime_data fifo_chime_data_t; +/*! \brief Enforce the `fifo_orbit_timeout` + * + * If the caller has been waiting longer than the `fifo_orbit_timeout` + * we break out so the orbit can do something else with the call. + */ static switch_status_t chime_read_frame_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data) { fifo_chime_data_t *cd = (fifo_chime_data_t *) user_data; @@ -611,7 +616,11 @@ static switch_status_t chime_read_frame_callback(switch_core_session_t *session, return SWITCH_STATUS_SUCCESS; } - +/*! \brief Handle chimes and timeouts for callers + * + * Play back the chimes in order spaced out by the given `freq` while + * ensuring that we don't exceed the `orbit_timeout`. + */ static switch_status_t caller_read_frame_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data) { fifo_chime_data_t *cd = (fifo_chime_data_t *) user_data; @@ -655,6 +664,13 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session return chime_read_frame_callback(session, frame, user_data); } +/*! \brief Handler for waiting consumers + * + * In `user_data` we'll be passed an array of fifo_nodes representing + * the fifos for which this consumer will accept calls. If any of + * those fifos have a caller in them, we break out so we can accept + * the call. + */ static switch_status_t consumer_read_frame_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data) { fifo_node_t *node, **node_list = (fifo_node_t **) user_data; From 597a5c1208991c072a949c644d58dcf819da6315 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 18:34:50 +0000 Subject: [PATCH 49/79] mod_fifo: Remove empty declaration --- src/mod/applications/mod_fifo/mod_fifo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 09da73cd21..935431c20d 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -692,8 +692,6 @@ static switch_status_t consumer_read_frame_callback(switch_core_session_t *sessi return SWITCH_STATUS_SUCCESS; } -struct fifo_node; - static struct { switch_hash_t *caller_orig_hash; switch_hash_t *consumer_orig_hash; From a5f982fd1c9019db11853d18736fc343245fb3f2 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 18:43:23 +0000 Subject: [PATCH 50/79] mod_fifo: Replace duplicate code with node_caller_count() --- src/mod/applications/mod_fifo/mod_fifo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 935431c20d..c1a8b27f74 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -674,15 +674,13 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session static switch_status_t consumer_read_frame_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data) { fifo_node_t *node, **node_list = (fifo_node_t **) user_data; - int x = 0, total = 0, i = 0; + int total = 0, i = 0; for (i = 0;; i++) { if (!(node = node_list[i])) { break; } - for (x = 0; x < MAX_PRI; x++) { - total += fifo_queue_size(node->fifo_list[x]); - } + total += node_caller_count(node); } if (total) { From 011882c8dda2d840862753d5133208f4dd59cc39 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 19:20:20 +0000 Subject: [PATCH 51/79] mod_fifo: Cleanup line spacing --- src/mod/applications/mod_fifo/mod_fifo.c | 149 ----------------------- 1 file changed, 149 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index c1a8b27f74..eb4c8c6d05 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -135,8 +135,6 @@ typedef enum { FIFO_APP_DID_HOOK = (1 << 2) } fifo_app_flag_t; - - static int check_caller_outbound_call(const char *key); static void add_caller_outbound_call(const char *key, switch_call_cause_t *cancel_cause); static void del_caller_outbound_call(const char *key); @@ -146,12 +144,10 @@ static void add_consumer_outbound_call(const char *key, switch_call_cause_t *can static void del_consumer_outbound_call(const char *key); static void cancel_consumer_outbound_call(const char *key, switch_call_cause_t cause); - static int check_bridge_call(const char *key); static void add_bridge_call(const char *key); static void del_bridge_call(const char *key); - switch_status_t fifo_queue_create(fifo_queue_t **queue, int size, switch_memory_pool_t *pool) { fifo_queue_t *q; @@ -167,7 +163,6 @@ switch_status_t fifo_queue_create(fifo_queue_t **queue, int size, switch_memory_ return SWITCH_STATUS_SUCCESS; } - static void change_pos(switch_event_t *event, int pos) { const char *uuid = switch_event_get_header(event, "unique-id"); @@ -289,7 +284,6 @@ static switch_status_t fifo_queue_pop_nameval(fifo_queue_t *queue, const char *n const char *j_val = switch_event_get_header(queue->data[j], name); const char *uuid = switch_event_get_header(queue->data[j], "unique-id"); if (j_val && val && !strcmp(j_val, val) && (force || !check_caller_outbound_call(uuid))) { - if (remove) { *pop = queue->data[j]; } else { @@ -360,11 +354,8 @@ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid) switch_mutex_unlock(queue->mutex); return SWITCH_STATUS_SUCCESS; - } - - /*! * \struct fifo_node * @@ -412,8 +403,6 @@ typedef struct fifo_node fifo_node_t; static void fifo_caller_add(fifo_node_t *node, switch_core_session_t *session); static void fifo_caller_del(const char *uuid); - - struct callback { char *buf; size_t len; @@ -724,13 +713,10 @@ static struct { outbound_strategy_t default_strategy; } globals; - - static int fifo_dec_use_count(const char *outbound_id) { int r = 0, *count; - switch_mutex_lock(globals.use_mutex); if ((count = (int *) switch_core_hash_find(globals.use_hash, outbound_id))) { if (*count > 0) { @@ -755,7 +741,6 @@ static int fifo_get_use_count(const char *outbound_id) return r; } - static int fifo_inc_use_count(const char *outbound_id) { int r = 0, *count; @@ -783,9 +768,6 @@ static void fifo_init_use_count(void) switch_mutex_unlock(globals.use_mutex); } - - - static int check_caller_outbound_call(const char *key) { int x = 0; @@ -796,10 +778,8 @@ static int check_caller_outbound_call(const char *key) x = !!switch_core_hash_find(globals.caller_orig_hash, key); switch_mutex_unlock(globals.caller_orig_mutex); return x; - } - static void add_caller_outbound_call(const char *key, switch_call_cause_t *cancel_cause) { if (!key) return; @@ -831,8 +811,6 @@ static void cancel_caller_outbound_call(const char *key, switch_call_cause_t cau switch_mutex_unlock(globals.caller_orig_mutex); } - - static int check_bridge_call(const char *key) { int x = 0; @@ -843,10 +821,8 @@ static int check_bridge_call(const char *key) x = !!switch_core_hash_find(globals.bridge_hash, key); switch_mutex_unlock(globals.bridge_mutex); return x; - } - static void add_bridge_call(const char *key) { static int marker = 1; @@ -864,7 +840,6 @@ static void del_bridge_call(const char *key) switch_mutex_unlock(globals.bridge_mutex); } - static int check_consumer_outbound_call(const char *key) { int x = 0; @@ -875,7 +850,6 @@ static int check_consumer_outbound_call(const char *key) x = !!switch_core_hash_find(globals.consumer_orig_hash, key); switch_mutex_unlock(globals.consumer_orig_mutex); return x; - } static void add_consumer_outbound_call(const char *key, switch_call_cause_t *cancel_cause) @@ -907,14 +881,10 @@ static void cancel_consumer_outbound_call(const char *key, switch_call_cause_t c *cancel_cause = cause; } switch_mutex_unlock(globals.consumer_orig_mutex); - } - - switch_cache_db_handle_t *fifo_get_db_handle(void) { - switch_cache_db_handle_t *dbh = NULL; char *dsn; @@ -939,7 +909,6 @@ static switch_status_t fifo_execute_sql_queued(char **sqlp, switch_bool_t sql_al switch_assert(sqlp && *sqlp); sql = *sqlp; - if (switch_stristr("insert", sql)) { index = 0; } @@ -955,7 +924,6 @@ static switch_status_t fifo_execute_sql_queued(char **sqlp, switch_bool_t sql_al } return SWITCH_STATUS_SUCCESS; - } #if 0 static switch_status_t fifo_execute_sql(char *sql, switch_mutex_t *mutex) @@ -1101,7 +1069,6 @@ static int node_idle_consumers(fifo_node_t *node) switch_mutex_unlock(node->mutex); return total; - } struct call_helper { @@ -1156,7 +1123,6 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(consumer_session)); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); - switch_channel_set_variable(consumer_channel, "fifo_status", "WAITING"); switch_channel_set_variable(consumer_channel, "fifo_timestamp", date); @@ -1208,7 +1174,6 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses } } - static switch_status_t messagehook (switch_core_session_t *session, switch_core_session_message_t *msg) { switch_event_t *event; @@ -1250,11 +1215,9 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ goto end; } - switch (msg->message_id) { case SWITCH_MESSAGE_INDICATE_BRIDGE: { - long epoch_start = 0; char date[80] = ""; switch_time_t ts; @@ -1349,7 +1312,6 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); - epoch_start = (long)switch_epoch_time_now(NULL); ts = switch_micro_time_now(); @@ -1391,7 +1353,6 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ return SWITCH_STATUS_SUCCESS; } - static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thread, void *obj) { struct callback_helper *cbh = (struct callback_helper *) obj; @@ -1475,7 +1436,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr goto end; } - if (node) { switch_mutex_lock(node->update_mutex); node->busy = 0; @@ -1491,14 +1451,12 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS); switch_assert(ovars); - for (i = 0; i < cbh->rowcount; i++) { struct call_helper *h = cbh->rows[i]; char *parsed = NULL; int use_ent = 0; char *expanded_originate_string = switch_event_expand_headers(ovars, h->originate_string); - if (strstr(expanded_originate_string, "user/")) { switch_event_create_brackets(expanded_originate_string, '<', '>', ',', &ovars, &parsed, SWITCH_TRUE); use_ent = 1; @@ -1526,7 +1484,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr if (expanded_originate_string && expanded_originate_string != h->originate_string) { switch_safe_free(expanded_originate_string); } - } originate_string = (char *) stream.data; @@ -1589,7 +1546,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr switch_event_add_header_string(ovars, SWITCH_STACK_BOTTOM, "fifo_originate_uuid", uuid_str); - if ((export = switch_event_get_header(pop, "variable_fifo_export"))) { int argc; char *argv[100] = { 0 }; @@ -1611,7 +1567,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr switch_safe_free(mydata); } - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_core_session_t *session; if (id && (session = switch_core_session_locate(id))) { @@ -1637,7 +1592,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr char *sql = switch_mprintf("update fifo_outbound set ring_count=ring_count+1 where uuid='%s'", h->uuid); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); - } if (!total) goto end; @@ -1665,7 +1619,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr del_caller_outbound_call(id); - if (status != SWITCH_STATUS_SUCCESS || cause != SWITCH_CAUSE_SUCCESS) { const char *acceptable = "false"; @@ -1681,7 +1634,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr "where uuid='%q' and ring_count > 0", h->uuid); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } - } break; default: @@ -1694,7 +1646,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr "next_avail=%ld + lag + 1 where uuid='%q' and ring_count > 0", (long) switch_epoch_time_now(NULL) + node->retry_delay, h->uuid); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); - } } } @@ -1730,7 +1681,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr switch_event_fire(&event); } - switch_channel_set_variable(channel, "fifo_pop_order", NULL); app_name = "fifo"; @@ -1744,9 +1694,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr switch_core_session_rwunlock(session); - - - for (i = 0; i < cbh->rowcount; i++) { struct call_helper *h = cbh->rows[i]; char *sql = switch_mprintf("update fifo_outbound set ring_count=ring_count-1 where uuid='%q' and ring_count > 0", h->uuid); @@ -1765,7 +1712,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr switch_thread_rwlock_unlock(node->rwlock); } - for (i = 0; i < cbh->rowcount; i++) { struct call_helper *h = cbh->rows[i]; del_consumer_outbound_call(h->uuid); @@ -1817,7 +1763,6 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * globals.threads++; switch_mutex_unlock(globals.mutex); - switch_mutex_lock(globals.mutex); node = switch_core_hash_find(globals.fifo_hash, h->node_name); switch_thread_rwlock_rdlock(node->rwlock); @@ -1849,7 +1794,6 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * "origination_caller_id_name=Queue,origination_caller_id_number='Queue: %q'}%s", node->name, node->name, node->name, expanded_originate_string); } - } if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { @@ -1861,14 +1805,12 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * switch_event_fire(&event); } - sql = switch_mprintf("update fifo_outbound set ring_count=ring_count+1 where uuid='%s'", h->uuid); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); status = switch_ivr_originate(NULL, &session, &cause, originate_string, h->timeout, NULL, NULL, NULL, NULL, ovars, SOF_NONE, NULL); if (status != SWITCH_STATUS_SUCCESS) { - sql = switch_mprintf("update fifo_outbound set ring_count=ring_count-1, " "outbound_fail_count=outbound_fail_count+1, next_avail=%ld + lag + 1 where uuid='%q'", (long) switch_epoch_time_now(NULL) + (node ? node->retry_delay : 0), h->uuid); @@ -1901,7 +1843,6 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * switch_event_fire(&event); } - if ((member_wait = switch_channel_get_variable(channel, "fifo_member_wait")) || (member_wait = switch_channel_get_variable(channel, "member_wait"))) { if (strcasecmp(member_wait, "wait") && strcasecmp(member_wait, "nowait")) { member_wait = NULL; @@ -1971,12 +1912,10 @@ static int place_call_ringall_callback(void *pArg, int argc, char **argv, char * } return 0; - } static int place_call_enterprise_callback(void *pArg, int argc, char **argv, char **columnNames) { - int *need = (int *) pArg; switch_thread_t *thread; @@ -1992,7 +1931,6 @@ static int place_call_enterprise_callback(void *pArg, int argc, char **argv, cha h->originate_string = switch_core_strdup(h->pool, argv[2]); h->timeout = atoi(argv[5]); - switch_threadattr_create(&thd_attr, h->pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); @@ -2007,7 +1945,6 @@ static void find_consumers(fifo_node_t *node) { char *sql; - sql = switch_mprintf("select uuid, fifo_name, originate_string, simo_count, use_count, timeout, lag, " "next_avail, expires, static, outbound_call_count, outbound_fail_count, hostname " "from fifo_outbound " @@ -2016,8 +1953,6 @@ static void find_consumers(fifo_node_t *node) node->name, (long) switch_epoch_time_now(NULL) ); - - switch(node->outbound_strategy) { case NODE_STRATEGY_ENTERPRISE: { @@ -2028,7 +1963,6 @@ static void find_consumers(fifo_node_t *node) } fifo_execute_sql_callback(globals.sql_mutex, sql, place_call_enterprise_callback, &need); - } break; case NODE_STRATEGY_RINGALL: @@ -2057,14 +1991,12 @@ static void find_consumers(fifo_node_t *node) } else { switch_core_destroy_memory_pool(&pool); } - } break; default: break; } - switch_safe_free(sql); } @@ -2100,10 +2032,8 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o switch_event_destroy(&pop); } } - } - if (this_node->ready == 0 && switch_thread_rwlock_trywrlock(this_node->rwlock) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s removed.\n", this_node->name); @@ -2142,7 +2072,6 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o this_node->name, ppl_waiting, consumer_total, idle_consumers, this_node->ring_consumer_count, this_node->outbound_priority); } - if ((ppl_waiting - this_node->ring_consumer_count > 0) && (!consumer_total || !idle_consumers)) { found++; find_consumers(this_node); @@ -2151,7 +2080,6 @@ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *o } } - if (++cur_priority > 10) { cur_priority = 1; } @@ -2202,7 +2130,6 @@ static void check_cancel(fifo_node_t *node) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound call count (%d) exceeds required value for queue %s (%d), " "Ending extraneous calls\n", node->ring_consumer_count, node->name, ppl_waiting); - switch_core_session_hupall_matching_var("fifo_hangup_check", node->name, SWITCH_CAUSE_ORIGINATOR_CANCEL); } } @@ -2271,7 +2198,6 @@ static void pres_event_handler(switch_event_t *event) dup_node_name = switch_mprintf("%q@%q", node_name, domain_name); - switch_mutex_lock(globals.mutex); if (!(node = switch_core_hash_find(globals.fifo_hash, node_name)) && !(node = switch_core_hash_find(globals.fifo_hash, dup_node_name))) { node = create_node(node_name, 0, globals.sql_mutex); @@ -2322,7 +2248,6 @@ static uint32_t fifo_add_outbound(const char *node_name, const char *url, uint32 switch_thread_rwlock_unlock(node->rwlock); return i; - } SWITCH_STANDARD_API(fifo_check_bridge_function) @@ -2357,17 +2282,14 @@ SWITCH_STANDARD_API(fifo_add_outbound_function) stream->write_function(stream, "%d", fifo_add_outbound(argv[0], argv[1], priority)); - free(data); return SWITCH_STATUS_SUCCESS; - fail: free(data); stream->write_function(stream, "0"); return SWITCH_STATUS_SUCCESS; - } static void dec_use_count(switch_core_session_t *session, const char *type) @@ -2381,7 +2303,6 @@ static void dec_use_count(switch_core_session_t *session, const char *type) if ((outbound_id = switch_channel_get_variable(channel, "fifo_outbound_uuid"))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s untracking call on uuid %s!\n", switch_channel_get_name(channel), outbound_id); - sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session)); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); @@ -2468,7 +2389,6 @@ SWITCH_STANDARD_APP(fifo_track_call_function) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s tracking call on uuid %s!\n", switch_channel_get_name(channel), data); - if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { col1 = "manual_calls_in_count"; col2 = "manual_calls_in_total_count"; @@ -2503,7 +2423,6 @@ SWITCH_STANDARD_APP(fifo_track_call_function) } } - static void fifo_caller_add(fifo_node_t *node, switch_core_session_t *session) { char *sql; @@ -2531,11 +2450,8 @@ static void fifo_caller_del(const char *uuid) } fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); - } - - typedef enum { STRAT_MORE_PPL, STRAT_WAITING_LONGER, @@ -2621,7 +2537,6 @@ SWITCH_STANDARD_APP(fifo_function) } } - if (!(node = switch_core_hash_find(globals.fifo_hash, nlist[i]))) { node = create_node(nlist[i], importance, globals.sql_mutex); node->ready = 1; @@ -2735,7 +2650,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_create(&call_event, SWITCH_EVENT_CHANNEL_DATA); switch_channel_event_set_data(channel, call_event); - fifo_queue_push(node->fifo_list[p], call_event); fifo_caller_add(node, session); in_table = 1; @@ -2811,7 +2725,6 @@ SWITCH_STANDARD_APP(fifo_function) aborted = 1; goto abort; } - } if (!serviced_uuid && switch_channel_ready(channel)) { @@ -2862,7 +2775,6 @@ SWITCH_STANDARD_APP(fifo_function) send_presence(node); check_cancel(node); switch_mutex_unlock(globals.mutex); - } if ((switch_true(switch_channel_get_variable(channel, "fifo_caller_exit_to_orbit")) || cd.do_orbit) && cd.orbit_exten) { @@ -2878,7 +2790,6 @@ SWITCH_STANDARD_APP(fifo_function) cancel_caller_outbound_call(switch_core_session_get_uuid(session), SWITCH_CAUSE_ORIGINATOR_CANCEL); goto done; - } else { /* consumer */ switch_event_t *pop = NULL; switch_frame_t *read_frame; @@ -3026,7 +2937,6 @@ SWITCH_STANDARD_APP(fifo_function) } if ((waiting = node_caller_count(node))) { - if (!importance || node->importance > importance) { if (strat == STRAT_WAITING_LONGER) { if (node->start_waiting < longest) { @@ -3164,7 +3074,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Outbound-URL", url); switch_event_fire(&event); } - } else { if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); @@ -3177,7 +3086,6 @@ SWITCH_STANDARD_APP(fifo_function) url = NULL; caller_uuid = switch_core_session_strdup(session, switch_core_session_get_uuid(other_session)); } - } else { if ((other_session = switch_core_session_locate(caller_uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); @@ -3218,7 +3126,6 @@ SWITCH_STANDARD_APP(fifo_function) } } - switch_channel_set_variable(other_channel, "fifo_serviced_by", my_id); switch_channel_set_variable(other_channel, "fifo_serviced_uuid", switch_core_session_get_uuid(session)); switch_channel_set_flag(other_channel, CF_BREAK); @@ -3236,7 +3143,6 @@ SWITCH_STANDARD_APP(fifo_function) const char *arg = switch_channel_get_variable(other_channel, "current_application_data"); switch_caller_extension_t *extension = NULL; - switch_channel_set_variable_printf(channel, "last_sent_callee_id_name", "%s (AGENT FAIL)", switch_channel_get_variable(other_channel, "caller_id_name")); switch_channel_set_variable(channel, "last_sent_callee_id_number", switch_channel_get_variable(other_channel, "caller_id_number")); @@ -3277,7 +3183,6 @@ SWITCH_STANDARD_APP(fifo_function) } } - switch_channel_step_caller_profile(channel); switch_channel_step_caller_profile(other_channel); @@ -3287,20 +3192,15 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_set_originator_caller_profile(other_channel, switch_caller_profile_clone(other_session, originator_cp)); switch_channel_set_originatee_caller_profile(channel, switch_caller_profile_clone(session, originatee_cp)); - originator_cp->callee_id_name = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_name); originator_cp->callee_id_number = switch_core_strdup(originator_cp->pool, originatee_cp->callee_id_number); - originatee_cp->callee_id_name = switch_core_strdup(originatee_cp->pool, originatee_cp->caller_id_name); originatee_cp->callee_id_number = switch_core_strdup(originatee_cp->pool, originatee_cp->caller_id_number); originatee_cp->caller_id_name = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_name); originatee_cp->caller_id_number = switch_core_strdup(originatee_cp->pool, originator_cp->caller_id_number); - - - ts = switch_micro_time_now(); switch_time_exp_lt(&tm, ts); epoch_start = (long)switch_epoch_time_now(NULL); @@ -3330,7 +3230,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_process_import(session, other_channel, "fifo_caller_consumer_import", switch_channel_get_variable(channel, "fifo_import_prefix")); switch_process_import(other_session, channel, "fifo_consumer_caller_import", switch_channel_get_variable(other_channel, "fifo_import_prefix")); - if (outbound_id) { cancel_consumer_outbound_call(outbound_id, SWITCH_CAUSE_ORIGINATOR_CANCEL); add_bridge_call(outbound_id); @@ -3338,10 +3237,8 @@ SWITCH_STANDARD_APP(fifo_function) sql = switch_mprintf("update fifo_outbound set stop_time=0,start_time=%ld,use_count=use_count+1,outbound_fail_count=0 where uuid='%s'", switch_epoch_time_now(NULL), outbound_id); - fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); fifo_inc_use_count(outbound_id); - } if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { @@ -3358,8 +3255,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_fire(&event); } - - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]); @@ -3378,7 +3273,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_event_fire(&event); } - add_bridge_call(switch_core_session_get_uuid(other_session)); add_bridge_call(switch_core_session_get_uuid(session)); @@ -3394,10 +3288,8 @@ SWITCH_STANDARD_APP(fifo_function) (long) switch_epoch_time_now(NULL) ); - fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); - switch_channel_set_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(other_session)); switch_channel_set_variable(other_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session)); @@ -3430,10 +3322,8 @@ SWITCH_STANDARD_APP(fifo_function) del_bridge_call(outbound_id); fifo_dec_use_count(outbound_id); - } - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { uint64_t hold_usec = 0, tt_usec = 0; switch_channel_event_set_data(channel, event); @@ -3462,7 +3352,6 @@ SWITCH_STANDARD_APP(fifo_function) del_bridge_call(switch_core_session_get_uuid(session)); del_bridge_call(switch_core_session_get_uuid(other_session)); - if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "FIFO-Name", argv[0]); @@ -3500,7 +3389,6 @@ SWITCH_STANDARD_APP(fifo_function) sql = switch_mprintf("delete from fifo_bridge where consumer_uuid='%q'", switch_core_session_get_uuid(session)); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_FALSE); - if (switch_channel_ready(channel)) { switch_core_media_bug_pause(session); } @@ -3526,7 +3414,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_core_session_rwunlock(other_session); - if (!do_wait || !switch_channel_ready(channel)) { break; } @@ -3584,7 +3471,6 @@ SWITCH_STANDARD_APP(fifo_function) if ((terminator == *fifo_consumer_wrapup_key) || !(switch_channel_ready(channel))) { break; } - } } else if (fifo_consumer_wrapup_time && (zstr(fifo_consumer_wrapup_key) || !strcmp(buf, fifo_consumer_wrapup_key))) { while (switch_channel_ready(channel)) { @@ -3631,7 +3517,6 @@ SWITCH_STANDARD_APP(fifo_function) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s is still alive, tracking call.\n", switch_channel_get_name(channel)); fifo_track_call_function(session, outbound_id); } - } done: @@ -3704,14 +3589,12 @@ static int xml_callback(void *pArg, int argc, char **argv, char **columnNames) } } - if (atoi(argv[13])) { arg = 17; } else { arg = 18; } - if ((etime = atol(argv[arg]))) { switch_size_t retsize; switch_time_exp_lt(&tm, switch_time_from_sec(etime)); @@ -3720,7 +3603,6 @@ static int xml_callback(void *pArg, int argc, char **argv, char **columnNames) switch_set_string(atime, "now"); } - x_out = switch_xml_add_child_d(h->xml, h->tag, c_off++); switch_xml_set_attr_d(x_out, "simo", argv[3]); switch_xml_set_attr_d(x_out, "use_count", argv[4]); @@ -3769,7 +3651,6 @@ static int xml_callback(void *pArg, int argc, char **argv, char **columnNames) switch_xml_set_attr_d(x_out, "stop-time", tb); } - switch_xml_set_attr_d(x_out, "next-available", expires); switch_xml_set_txt_d(x_out, argv[2]); @@ -3783,7 +3664,6 @@ static int xml_outbound(switch_xml_t xml, fifo_node_t *node, char *container, ch char *sql; if (!strcmp(node->name, MANUAL_QUEUE_NAME)) { - sql = switch_mprintf("select uuid, '%s', originate_string, simo_count, use_count, timeout," "lag, next_avail, expires, static, outbound_call_count, outbound_fail_count," "hostname, taking_calls, status, outbound_call_total_count, outbound_fail_total_count, active_time, inactive_time," @@ -3794,8 +3674,6 @@ static int xml_outbound(switch_xml_t xml, fifo_node_t *node, char *container, ch "hostname, taking_calls, status, outbound_call_total_count, outbound_fail_total_count, active_time, inactive_time," "manual_calls_out_count, manual_calls_in_count, manual_calls_out_total_count, manual_calls_in_total_count", MANUAL_QUEUE_NAME); - - } else { sql = switch_mprintf("select uuid, fifo_name, originate_string, simo_count, use_count, timeout, " "lag, next_avail, expires, static, outbound_call_count, outbound_fail_count, " @@ -3822,7 +3700,6 @@ static int xml_outbound(switch_xml_t xml, fifo_node_t *node, char *container, ch return h.cc_off; } - static int xml_bridge_callback(void *pArg, int argc, char **argv, char **columnNames) { struct xml_helper *h = (struct xml_helper *) pArg; @@ -3844,7 +3721,6 @@ static int xml_bridge_callback(void *pArg, int argc, char **argv, char **columnN switch_set_string(exp_buf, "now"); } - x_bridge = switch_xml_add_child_d(h->xml, h->tag, h->row_off++); switch_xml_set_attr_d(x_bridge, "fifo_name", argv[0]); @@ -3861,8 +3737,6 @@ static int xml_bridge_callback(void *pArg, int argc, char **argv, char **columnN encoded = switch_url_encode(argv[3], url_buf, sizeof(url_buf)); switch_xml_set_attr_d(x_caller, "caller_id_number", encoded); - - if (h->verbose) { if ((session = switch_core_session_locate(argv[1]))) { x_cdr = switch_xml_add_child_d(x_caller, "cdr", 0); @@ -3976,7 +3850,6 @@ static int xml_hash(switch_xml_t xml, switch_hash_t *hash, char *container, char return cc_off; } - static int xml_caller(switch_xml_t xml, fifo_node_t *node, char *container, char *tag, int cc_off, int verbose) { switch_xml_t x_tmp, x_caller, x_cp; @@ -3993,7 +3866,6 @@ static int xml_caller(switch_xml_t xml, fifo_node_t *node, char *container, char switch_mutex_lock(q->mutex); for (i = 0; i < q->idx; i++) { - int c_off = 0, d_off = 0; const char *status; const char *ts; @@ -4045,7 +3917,6 @@ static int xml_caller(switch_xml_t xml, fifo_node_t *node, char *container, char switch_snprintf(sl, sizeof(sl), "%d", x); switch_xml_set_attr_d_buf(x_caller, "slot", sl); - if (verbose) { if (!(x_cp = switch_xml_add_child_d(x_caller, "cdr", d_off++))) { abort(); @@ -4104,7 +3975,6 @@ static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int ve cc_off = xml_bridges(x_fifo, node, "bridges", "bridge", cc_off, verbose); } - void dump_hash(switch_hash_t *hash, switch_stream_handle_t *stream) { switch_hash_index_t *hi; @@ -4121,8 +3991,6 @@ void dump_hash(switch_hash_t *hash, switch_stream_handle_t *stream) void node_dump(switch_stream_handle_t *stream) { - - switch_hash_index_t *hi; fifo_node_t *node; void *val; @@ -4161,12 +4029,8 @@ void node_dump(switch_stream_handle_t *stream) dump_hash(globals.bridge_hash, stream); switch_mutex_unlock(globals.mutex); - - } - - #define FIFO_API_SYNTAX "list|list_verbose|count|debug|status|importance []|reparse [del_all]" SWITCH_STANDARD_API(fifo_api_function) { @@ -4188,7 +4052,6 @@ SWITCH_STANDARD_API(fifo_api_function) switch_assert(data); } - switch_mutex_lock(globals.mutex); if (zstr(cmd) || (argc = switch_separate_string(data, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 1 || !argv[0]) { @@ -4245,7 +4108,6 @@ SWITCH_STANDARD_API(fifo_api_function) stream->write_function(stream, "%s\n", xml_text); switch_xml_free(x_report); switch_safe_free(xml_text); - } else if (!strcasecmp(argv[0], "importance")) { if (argv[1] && (node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { int importance = 0; @@ -4314,7 +4176,6 @@ SWITCH_STANDARD_API(fifo_api_function) return SWITCH_STATUS_SUCCESS; } - const char outbound_sql[] = "create table fifo_outbound (\n" " uuid varchar(255),\n" @@ -4345,7 +4206,6 @@ const char outbound_sql[] = " stop_time integer not null default 0\n" ");\n"; - const char bridge_sql[] = "create table fifo_bridge (\n" " fifo_name varchar(1024) not null,\n" @@ -4369,8 +4229,6 @@ const char callers_sql[] = ");\n" ; - - static void extract_fifo_outbound_uuid(char *string, char *uuid, switch_size_t len) { switch_event_t *ovars; @@ -4378,7 +4236,6 @@ static void extract_fifo_outbound_uuid(char *string, char *uuid, switch_size_t l const char *fifo_outbound_uuid; switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS); - switch_event_create_brackets(string, '{', '}', ',', &ovars, &parsed, SWITCH_TRUE); if ((fifo_outbound_uuid = switch_event_get_header(ovars, "fifo_outbound_uuid"))) { @@ -4665,7 +4522,6 @@ static switch_status_t load_config(int reload, int del_all) return status; } - static void fifo_member_add(char *fifo_name, char *originate_string, int simo_count, int timeout, int lag, time_t expires, int taking_calls) { char digest[SWITCH_MD5_DIGEST_STRING_SIZE] = { 0 }; @@ -4686,7 +4542,6 @@ static void fifo_member_add(char *fifo_name, char *originate_string, int simo_co switch_assert(sql); fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); - switch_mutex_lock(globals.mutex); if (!(node = switch_core_hash_find(globals.fifo_hash, fifo_name))) { node = create_node(fifo_name, 0, globals.sql_mutex); @@ -4732,7 +4587,6 @@ static void fifo_member_del(char *fifo_name, char *originate_string) if (!fifo_name) return; - if (switch_stristr("fifo_outbound_uuid=", originate_string)) { extract_fifo_outbound_uuid(originate_string, digest, sizeof(digest)); } else { @@ -4844,7 +4698,6 @@ SWITCH_STANDARD_API(fifo_member_api_function) free(mydata); return SWITCH_STATUS_SUCCESS; - } SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load) @@ -4890,7 +4743,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load) return status; } - /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_APP(app_interface, "fifo", "Park with FIFO", FIFO_DESC, fifo_function, FIFO_USAGE, SAF_NONE); @@ -4946,7 +4798,6 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) this_node = node; node = node->next; - switch_mutex_lock(this_node->update_mutex); switch_mutex_lock(this_node->mutex); for (x = 0; x < MAX_PRI; x++) { From 64144d73a371452d0119fe341b8b80410dfef939 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 19:46:55 +0000 Subject: [PATCH 52/79] mod_fifo: Refactor to avoid a memory allocation --- src/mod/applications/mod_fifo/mod_fifo.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index eb4c8c6d05..f1a1474882 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -999,8 +999,6 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu char outbound_count[80] = ""; callback_t cbt = { 0 }; char *sql = NULL; - char *domain_name = NULL; - if (!globals.running) { return NULL; } @@ -1013,8 +1011,7 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu node->name = switch_core_strdup(node->pool, name); if (!strchr(name, '@')) { - domain_name = switch_core_get_domain(SWITCH_TRUE); - node->domain_name = switch_core_strdup(node->pool, domain_name); + node->domain_name = switch_core_strdup(node->pool, switch_core_get_domain(SWITCH_FALSE)); } for (x = 0; x < MAX_PRI; x++) { @@ -1043,8 +1040,6 @@ static fifo_node_t *create_node(const char *name, uint32_t importance, switch_mu globals.nodes = node; switch_mutex_unlock(globals.mutex); - switch_safe_free(domain_name); - return node; } From a24b0b739f9536e5e07894c688a6ca40534a68b1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 19:58:26 +0000 Subject: [PATCH 53/79] mod_fifo: Avoid getting time twice We were simply discarding unused the first time we retrieved here. --- src/mod/applications/mod_fifo/mod_fifo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index f1a1474882..11d5e4a987 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1111,7 +1111,6 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses use_count = fifo_get_use_count(outbound_id); } - ts = switch_micro_time_now(); switch_time_exp_lt(&tm, ts); switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); From 48acd9fe66604778bdc295ef617d9579f0ba09ff Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 20:30:39 +0000 Subject: [PATCH 54/79] mod_fifo: Note source of unexplained constant --- src/mod/applications/mod_fifo/mod_fifo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 11d5e4a987..3d8fecc442 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1186,6 +1186,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ case SWITCH_MESSAGE_INDICATE_BRIDGE: case SWITCH_MESSAGE_INDICATE_UNBRIDGE: if (msg->numeric_arg == 42) { + /* See audio_bridge_thread() for source of 42 constant. */ goto end; } if ((caller_session = switch_core_session_locate(msg->string_arg))) { From 343aee2dd819cf893bc3787ec7010f1ee3d64f70 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 20:46:59 +0000 Subject: [PATCH 55/79] mod_fifo: Comment manual call tracking session handler --- src/mod/applications/mod_fifo/mod_fifo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 3d8fecc442..c52f328587 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1083,6 +1083,8 @@ struct callback_helper { int ready; }; +/*!\brief Handle unbridging of manually tracked calls + */ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_session_t *caller_session) { switch_channel_t *consumer_channel = switch_core_session_get_channel(consumer_session); @@ -1168,6 +1170,8 @@ static void do_unbridge(switch_core_session_t *consumer_session, switch_core_ses } } +/*!\brief Handle session messages for manually tracked calls + */ static switch_status_t messagehook (switch_core_session_t *session, switch_core_session_message_t *msg) { switch_event_t *event; From 80ccaf3450f2dc24695b5f3abbc082c532df6a2a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 21:19:56 +0000 Subject: [PATCH 56/79] mod_fifo: Remove duplicate check in ringall strategy We already checked the number of usable rows, and nothing has changed. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index c52f328587..f8496a74f1 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1593,8 +1593,6 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); } - if (!total) goto end; - if (!globals.allow_transcoding && !switch_true(switch_event_get_header(pop, "variable_fifo_allow_transcoding")) && (codec = switch_event_get_header(pop, "variable_rtp_use_codec_name"))) { const char *rate = switch_event_get_header(pop, "variable_rtp_use_codec_rate"); From 0c25c3deb923351ed33c86c2354da9957126df34 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 26 May 2014 22:57:12 +0000 Subject: [PATCH 57/79] mod_fifo: Document node_thread_run() --- src/mod/applications/mod_fifo/mod_fifo.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index f8496a74f1..f1902eb636 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1997,6 +1997,20 @@ static void find_consumers(fifo_node_t *node) switch_safe_free(sql); } +/*\brief Continuously attempt to deliver calls to outbound members + * + * For each outbound priority level 1-10, find fifo nodes with a + * matching priority. For each of those nodes with outbound members, + * run `find_consumers()` if the fifo node has calls needing to be + * delivered and not enough ready and waiting inbound consumers. + * + * In the event of nothing needing to be done, each cycle starts at + * priority 1 and ends at priority 10, yielding for one second + * afterward. We also yield after initiating outbound calls, starting + * again where we left off on the next node. + * + * We also take care of cleaning up after nodes queued for deletion. + */ static void *SWITCH_THREAD_FUNC node_thread_run(switch_thread_t *thread, void *obj) { fifo_node_t *node, *last, *this_node; From 1b5a1c1e1d9398db32962fd70f62ca047073dc94 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 03:34:18 +0000 Subject: [PATCH 58/79] mod_fifo: Document find_consumers() --- src/mod/applications/mod_fifo/mod_fifo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index f1902eb636..61152afb0a 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1938,6 +1938,18 @@ static int place_call_enterprise_callback(void *pArg, int argc, char **argv, cha return *need ? 0 : -1; } +/*!\brief Find outbound members to call for a given fifo node + * + * We're given a fifo node that has callers to be delivered to agents. + * Our job is to find available outbound members and pass them to the + * appropriate outbound strategy handler. + * + * The ringall strategy handler needs the full list of members to do + * its job, so we first let `place_call_ringall_callback` accumulate + * the results. The enterprise strategy handler can simply take each + * member one at a time, so the `place_call_enterprise_callback` takes + * care of invoking the handler. + */ static void find_consumers(fifo_node_t *node) { char *sql; From e2596b3f30271a416a6125d5e4c8035cf54e7d1d Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 03:32:54 +0000 Subject: [PATCH 59/79] mod_fifo: Document the ringall strategy --- src/mod/applications/mod_fifo/mod_fifo.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 61152afb0a..e078deeb16 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1352,6 +1352,20 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ return SWITCH_STATUS_SUCCESS; } +/*!\brief Create calls to outbound members with ringall strategy + * + * A fifo node has been selected for us and we've been given a list of + * outbound members to ring. We're going to pick a single caller by + * searching through the fifo node queues in order of priority + * (`fifo_priority`) from lowest to highest. We'll look first for + * callers with fifo_vip=true. Finding none, we'll consider the + * plebs. + * + * Once we have a caller to service, we'll set fifo_bridge_uuid for + * that caller to let the fifo application in on our decision. Our + * job being done, we'll let the fifo application deal with the + * remaining details. + */ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thread, void *obj) { struct callback_helper *cbh = (struct callback_helper *) obj; @@ -1887,6 +1901,9 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * return NULL; } +/*!\brief Extract the outbound member results and accumulate them for + * the ringall strategy handler + */ static int place_call_ringall_callback(void *pArg, int argc, char **argv, char **columnNames) { struct callback_helper *cbh = (struct callback_helper *) pArg; @@ -2991,6 +3008,7 @@ SWITCH_STANDARD_APP(fifo_function) check = switch_channel_get_variable(channel, "fifo_bridge_uuid_required"); + /* Handle predestined calls, including calls from the ringall strategy */ if ((varval = switch_channel_get_variable(channel, "fifo_bridge_uuid"))) { if (check_bridge_call(varval) && switch_true(check)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Call has already been answered\n", From 96012ffb3a2b26b3b53d592dfc45c69f61bcb8a1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 03:33:55 +0000 Subject: [PATCH 60/79] mod_fifo: Document the enterprise strategy --- src/mod/applications/mod_fifo/mod_fifo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index e078deeb16..5671ad5754 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1751,6 +1751,15 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr return NULL; } +/*!\brief Send a call to an outbound member with the enterprise strategy + * + * A fifo and an outbound member have been picked out for us and our + * job is to create a channel to the member and deliver that channel + * into the `fifo out` application. + * + * We haven't picked a caller yet, and we won't do so here. We'll let + * the fifo application take care of that work. + */ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t *thread, void *obj) { struct call_helper *h = (struct call_helper *) obj; @@ -1928,6 +1937,9 @@ static int place_call_ringall_callback(void *pArg, int argc, char **argv, char * return 0; } +/*!\brief Extract the outbound member results and invoke the + * enterprise strategy handler + */ static int place_call_enterprise_callback(void *pArg, int argc, char **argv, char **columnNames) { int *need = (int *) pArg; From 431d7d97c7c4bf35af2fb135d545e48649e21d78 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 04:15:44 +0000 Subject: [PATCH 61/79] mod_fifo: Document effect of fifo strategy and importance --- src/mod/applications/mod_fifo/mod_fifo.c | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 5671ad5754..7d0151f428 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -2983,6 +2983,33 @@ SWITCH_STANDARD_APP(fifo_function) } } + /* Before we can pick a caller we have to decide on a fifo + node to service if the consumer can service more than + one. + + If all fifos have an importance of zero, we'll find the + first node that wins based on the chosen strategy. + + The `waiting_longer` strategy will choose the node that + hasn't been empty for the longest time. + + The `more_ppl` strategy will choose the node that has + the most people waiting. + + If a node has an importance value set, it will cause us + to ignore later nodes with equivalent or lower + importance values. This means that a node with the + same importance that would otherwise win based on the + strategy will not be considered at all if it comes + later in the list. Note also that the high importance + node may still lose if a considered fifo earlier in the + list beats it per the strategy. + + Note that when the consumer has been delivered by an + outbound strategy there will only be one fifo node + passed to us, so neither the importance nor the + strategy here will have any effect. + */ for (i = 0; i < node_count; i++) { if (!(node = node_list[i])) { continue; From 06805452d833c6e3cd374b1f3dc8376487a43ca6 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 06:55:38 +0000 Subject: [PATCH 62/79] mod_fifo: Cleanup documentation formatting --- src/mod/applications/mod_fifo/mod_fifo.c | 26 +++++++++++------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 7d0151f428..d1a1872cf3 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -204,9 +204,9 @@ static int fifo_queue_size(fifo_queue_t *queue) /*! * \param remove Whether to remove the popped event from the queue - * If remove is 0, do not remove the popped event. If it is 1, remove - * it if it is not an event for an outbound caller. If it is 2, - * always remove it. + * If remove is 0, do not remove the popped event. If it is 1, + * remove it if it is not an event for an outbound caller. If it is + * 2, always remove it. */ static switch_status_t fifo_queue_pop(fifo_queue_t *queue, switch_event_t **pop, int remove) { @@ -250,7 +250,7 @@ static switch_status_t fifo_queue_pop(fifo_queue_t *queue, switch_event_t **pop, return SWITCH_STATUS_SUCCESS; } -/*! \brief Remove matching event from queue +/*!\brief Remove matching event from queue * * Each event in the queue will be checked to see whether it has a * header equal to name whose value is equal to val. If it does, that @@ -313,7 +313,7 @@ static switch_status_t fifo_queue_pop_nameval(fifo_queue_t *queue, const char *n return SWITCH_STATUS_SUCCESS; } -/*! \brief Destroy event with given uuid and remove it from queue +/*!\brief Destroy event with given uuid and remove it from queue * * Elements of the queue are searched until a matching uuid is found. * That uuid is then destroyed and removed from the queue. The @@ -356,8 +356,7 @@ static switch_status_t fifo_queue_popfly(fifo_queue_t *queue, const char *uuid) return SWITCH_STATUS_SUCCESS; } -/*! - * \struct fifo_node +/*!\struct fifo_node * * \var fifo_node::outbound_name * \brief Name of fifo in caller ID @@ -446,7 +445,7 @@ static int sql2str_callback(void *pArg, int argc, char **argv, char **columnName return 0; } -/*! \brief Handler for consumer DTMF +/*!\brief Handler for consumer DTMF * * When `fifo_consumer_exit_key` is pressed by the consumer we hangup * on the caller (unless we've put the caller on hold). The default @@ -502,7 +501,7 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit return SWITCH_STATUS_SUCCESS; } -/*! \brief Handler for caller DTMF +/*!\brief Handler for caller DTMF * * The channel variable `fifo_caller_exit_key` can be set to one or * more digits that when pressed will cause the caller to exit from @@ -588,7 +587,7 @@ struct fifo_chime_data { typedef struct fifo_chime_data fifo_chime_data_t; -/*! \brief Enforce the `fifo_orbit_timeout` +/*!\brief Enforce the `fifo_orbit_timeout` * * If the caller has been waiting longer than the `fifo_orbit_timeout` * we break out so the orbit can do something else with the call. @@ -605,7 +604,7 @@ static switch_status_t chime_read_frame_callback(switch_core_session_t *session, return SWITCH_STATUS_SUCCESS; } -/*! \brief Handle chimes and timeouts for callers +/*!\brief Handle chimes and timeouts for callers * * Play back the chimes in order spaced out by the given `freq` while * ensuring that we don't exceed the `orbit_timeout`. @@ -653,7 +652,7 @@ static switch_status_t caller_read_frame_callback(switch_core_session_t *session return chime_read_frame_callback(session, frame, user_data); } -/*! \brief Handler for waiting consumers +/*!\brief Handler for waiting consumers * * In `user_data` we'll be passed an array of fifo_nodes representing * the fifos for which this consumer will accept calls. If any of @@ -4368,8 +4367,7 @@ static switch_status_t read_config_file(switch_xml_t *xml, switch_xml_t *cfg) { return SWITCH_STATUS_SUCCESS; } -/*! - * Load or reload the configuration +/*!\brief Load or reload the configuration * * On the initial load, non-static members are preserved unless the * parameter `delete-all-outbound-members-on-startup` is set. The From 42e9615900fa5459f5c2beaeac0c5436cdf2af17 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 08:09:25 +0000 Subject: [PATCH 63/79] mod_fifo: Add missing tab completions --- src/mod/applications/mod_fifo/mod_fifo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index d1a1872cf3..2250c805b1 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4833,6 +4833,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load) switch_console_set_complete("add fifo list"); switch_console_set_complete("add fifo list_verbose"); switch_console_set_complete("add fifo count"); + switch_console_set_complete("add fifo debug"); + switch_console_set_complete("add fifo status"); switch_console_set_complete("add fifo has_outbound"); switch_console_set_complete("add fifo importance"); switch_console_set_complete("add fifo reparse"); From 144fea57b213d3a45b6f6938de000740c34788d1 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 08:10:51 +0000 Subject: [PATCH 64/79] mod_fifo: Add missing has_outbound to docstring --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 2250c805b1..fd25b3248f 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4110,7 +4110,7 @@ void node_dump(switch_stream_handle_t *stream) switch_mutex_unlock(globals.mutex); } -#define FIFO_API_SYNTAX "list|list_verbose|count|debug|status|importance []|reparse [del_all]" +#define FIFO_API_SYNTAX "list|list_verbose|count|debug|status|has_outbound|importance []|reparse [del_all]" SWITCH_STANDARD_API(fifo_api_function) { fifo_node_t *node; From 00b25baa421d7104ba9aee39ce8351f38b78d3d0 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 27 May 2014 17:33:05 -0500 Subject: [PATCH 65/79] mod_fifo: Explain session message unbridge constant --- src/mod/applications/mod_fifo/mod_fifo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index fd25b3248f..48b02422aa 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1190,6 +1190,14 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_ case SWITCH_MESSAGE_INDICATE_UNBRIDGE: if (msg->numeric_arg == 42) { /* See audio_bridge_thread() for source of 42 constant. */ + /* When a session is interrupted to execute an application + (e.g. by uuid_execute) we need to tell everything in FS + to unbridge the channel (e.g. to turn on the + jitterbuffer) but we need mod_fifo not to see the + unbridge because we don't want fifo to stop tracking + the call. So this magic number is a complete hack to + make this happen. So we ignore it here and simply fall + through. */ goto end; } if ((caller_session = switch_core_session_locate(msg->string_arg))) { From 5138f4d5a71b6f5937941049663874ca98e020bf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 28 May 2014 07:31:24 +0500 Subject: [PATCH 66/79] add new stub module mod_rtc dummy signaling-free media engine endpoint --- build/modules.conf.in | 1 + configure.ac | 1 + src/mod/endpoints/mod_rtc/Makefile.am | 8 + src/mod/endpoints/mod_rtc/mod_rtc.c | 463 ++++++++++++++++++++++++++ 4 files changed, 473 insertions(+) create mode 100644 src/mod/endpoints/mod_rtc/Makefile.am create mode 100644 src/mod/endpoints/mod_rtc/mod_rtc.c diff --git a/build/modules.conf.in b/build/modules.conf.in index 348e3521aa..34e16be048 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -82,6 +82,7 @@ dialplans/mod_dialplan_xml #endpoints/mod_gsmopen #endpoints/mod_h323 #endpoints/mod_khomp +endpoints/mod_rtc endpoints/mod_loopback #endpoints/mod_opal #endpoints/mod_portaudio diff --git a/configure.ac b/configure.ac index 02fb30629a..4da80f2105 100644 --- a/configure.ac +++ b/configure.ac @@ -1499,6 +1499,7 @@ AC_CONFIG_FILES([Makefile src/mod/endpoints/mod_skypopen/Makefile src/mod/endpoints/mod_sofia/Makefile src/mod/endpoints/mod_unicall/Makefile + src/mod/endpoints/mod_rtc/Makefile src/mod/event_handlers/mod_cdr_csv/Makefile src/mod/event_handlers/mod_cdr_mongodb/Makefile src/mod/event_handlers/mod_cdr_pg_csv/Makefile diff --git a/src/mod/endpoints/mod_rtc/Makefile.am b/src/mod/endpoints/mod_rtc/Makefile.am new file mode 100644 index 0000000000..bc09a9c357 --- /dev/null +++ b/src/mod/endpoints/mod_rtc/Makefile.am @@ -0,0 +1,8 @@ +include $(top_srcdir)/build/modmake.rulesam +MODNAME=mod_rtc + +mod_LTLIBRARIES = mod_rtc.la +mod_rtc_la_SOURCES = mod_rtc.c +mod_rtc_la_CFLAGS = $(AM_CFLAGS) +mod_rtc_la_LIBADD = $(switch_builddir)/libfreeswitch.la +mod_rtc_la_LDFLAGS = -avoid-version -module -no-undefined -shared diff --git a/src/mod/endpoints/mod_rtc/mod_rtc.c b/src/mod/endpoints/mod_rtc/mod_rtc.c new file mode 100644 index 0000000000..06b2815052 --- /dev/null +++ b/src/mod/endpoints/mod_rtc/mod_rtc.c @@ -0,0 +1,463 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2014, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * mod_rtc.c -- RTC Endpoint + * + */ + +/* Best viewed in a 160 x 60 VT100 Terminal or so the line below at least fits across your screen*/ +/*************************************************************************************************************************************************************/ +#include + +SWITCH_MODULE_LOAD_FUNCTION(mod_rtc_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rtc_shutdown); +SWITCH_MODULE_DEFINITION(mod_rtc, mod_rtc_load, mod_rtc_shutdown, NULL); + + +switch_endpoint_interface_t *rtc_endpoint_interface; + +#define STRLEN 15 + +static switch_status_t rtc_on_init(switch_core_session_t *session); + +static switch_status_t rtc_on_exchange_media(switch_core_session_t *session); +static switch_status_t rtc_on_soft_execute(switch_core_session_t *session); +static switch_call_cause_t rtc_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, + switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, + switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause); +static switch_status_t rtc_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); +static switch_status_t rtc_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); +static switch_status_t rtc_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id); +static switch_status_t rtc_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id); +static switch_status_t rtc_kill_channel(switch_core_session_t *session, int sig); + +typedef struct { + switch_channel_t *channel; + switch_core_session_t *session; + switch_caller_profile_t *caller_profile; + switch_media_handle_t *media_handle; + switch_core_media_params_t mparams; +} private_object_t; + +static struct { + switch_memory_pool_t *pool; + switch_mutex_t *mutex; + int running; +} mod_rtc_globals; + + +/* BODY OF THE MODULE */ +/*************************************************************************************************************************************************************/ + +/* + State methods they get called when the state changes to the specific state + returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next + so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. +*/ +static switch_status_t rtc_on_init(switch_core_session_t *session) +{ + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t rtc_on_routing(switch_core_session_t *session) +{ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RTC ROUTING\n", + switch_channel_get_name(switch_core_session_get_channel(session))); + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t rtc_on_reset(switch_core_session_t *session) +{ + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RTC RESET\n", + switch_channel_get_name(switch_core_session_get_channel(session))); + + + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t rtc_on_hibernate(switch_core_session_t *session) +{ + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RTC HIBERNATE\n", + switch_channel_get_name(switch_core_session_get_channel(session))); + + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t rtc_on_execute(switch_core_session_t *session) +{ + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RTC EXECUTE\n", + switch_channel_get_name(switch_core_session_get_channel(session))); + + return SWITCH_STATUS_SUCCESS; +} + + +switch_status_t rtc_on_destroy(switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RTC DESTROY\n", switch_channel_get_name(channel)); + switch_media_handle_destroy(session); + + return SWITCH_STATUS_SUCCESS; + +} + +switch_status_t rtc_on_hangup(switch_core_session_t *session) +{ + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t rtc_on_exchange_media(switch_core_session_t *session) +{ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RTC EXCHANGE_MEDIA\n"); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t rtc_on_soft_execute(switch_core_session_t *session) +{ + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "RTC SOFT_EXECUTE\n"); + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t rtc_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) +{ + return switch_core_media_read_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_VIDEO); +} + +static switch_status_t rtc_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) +{ + private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); + switch_assert(tech_pvt != NULL); + + + if (SWITCH_STATUS_SUCCESS == switch_core_media_write_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_VIDEO)) { + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +static switch_status_t rtc_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + status = switch_core_media_read_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_AUDIO); + + return status; +} + +static switch_status_t rtc_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + status = switch_core_media_write_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_AUDIO); + + return status; +} + +static switch_status_t rtc_kill_channel(switch_core_session_t *session, int sig) +{ + private_object_t *tech_pvt = switch_core_session_get_private(session); + + if (!tech_pvt) { + return SWITCH_STATUS_FALSE; + } + + switch (sig) { + case SWITCH_SIG_BREAK: + if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { + switch_core_media_break(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); + } + if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO)) { + switch_core_media_break(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO); + } + break; + case SWITCH_SIG_KILL: + default: + + if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { + switch_core_media_kill_socket(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO); + } + if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO)) { + switch_core_media_kill_socket(tech_pvt->session, SWITCH_MEDIA_TYPE_VIDEO); + } + break; + } + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t rtc_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) +{ + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t rtc_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + private_object_t *tech_pvt = switch_core_session_get_private(session); + switch_status_t status = SWITCH_STATUS_SUCCESS; + const char *var; + + if (switch_channel_down(channel) || !tech_pvt) { + status = SWITCH_STATUS_FALSE; + return SWITCH_STATUS_FALSE; + } + + /* ones that do not need to lock rtp mutex */ + switch (msg->message_id) { + + case SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS: + break; + case SWITCH_MESSAGE_INDICATE_ANSWER: + case SWITCH_MESSAGE_INDICATE_PROGRESS: + { + + if (((var = switch_channel_get_variable(channel, "rtp_secure_media"))) && + (switch_true(var) || switch_core_media_crypto_str2type(var) != CRYPTO_INVALID)) { + switch_channel_set_flag(tech_pvt->channel, CF_SECURE); + } + } + break; + + default: + break; + } + + + return status; + +} + +static switch_status_t rtc_receive_event(switch_core_session_t *session, switch_event_t *event) +{ + return SWITCH_STATUS_SUCCESS; +} + +switch_io_routines_t rtc_io_routines = { + /*.outgoing_channel */ rtc_outgoing_channel, + /*.read_frame */ rtc_read_frame, + /*.write_frame */ rtc_write_frame, + /*.kill_channel */ rtc_kill_channel, + /*.send_dtmf */ rtc_send_dtmf, + /*.receive_message */ rtc_receive_message, + /*.receive_event */ rtc_receive_event, + /*.state_change */ NULL, + /*.read_video_frame */ rtc_read_video_frame, + /*.write_video_frame */ rtc_write_video_frame, + /*.state_run*/ NULL, + /*.get_jb*/ NULL +}; + +switch_state_handler_table_t rtc_event_handlers = { + /*.on_init */ rtc_on_init, + /*.on_routing */ rtc_on_routing, + /*.on_execute */ rtc_on_execute, + /*.on_hangup */ rtc_on_hangup, + /*.on_exchange_media */ rtc_on_exchange_media, + /*.on_soft_execute */ rtc_on_soft_execute, + /*.on_consume_media */ NULL, + /*.on_hibernate */ rtc_on_hibernate, + /*.on_reset */ rtc_on_reset, + /*.on_park */ NULL, + /*.on_reporting */ NULL, + /*.on_destroy */ rtc_on_destroy +}; + + +void rtc_set_name(private_object_t *tech_pvt, const char *channame) +{ + char name[256]; + + switch_snprintf(name, sizeof(name), "rtc/%s", channame); + switch_channel_set_name(tech_pvt->channel, name); +} + + + +void rtc_attach_private(switch_core_session_t *session, private_object_t *tech_pvt, const char *channame) +{ + + switch_assert(session != NULL); + switch_assert(tech_pvt != NULL); + + switch_core_session_add_stream(session, NULL); + + tech_pvt->session = session; + tech_pvt->channel = switch_core_session_get_channel(session); + switch_core_media_check_dtmf_type(session); + switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER); + switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP); + switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams); + switch_core_session_set_private(session, tech_pvt); + + if (channame) { + rtc_set_name(tech_pvt, channame); + } +} + + +private_object_t *rtc_new_pvt(switch_core_session_t *session) +{ + private_object_t *tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)); + return tech_pvt; +} + +static switch_call_cause_t rtc_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, + switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, + switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) +{ + switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; + switch_core_session_t *nsession = NULL; + switch_caller_profile_t *caller_profile = NULL; + private_object_t *tech_pvt = NULL; + switch_channel_t *nchannel; + const char *hval = NULL; + + *new_session = NULL; + + + if (!(nsession = switch_core_session_request_uuid(rtc_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, + flags, pool, switch_event_get_header(var_event, "origination_uuid")))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); + goto error; + } + + tech_pvt = rtc_new_pvt(nsession); + + nchannel = switch_core_session_get_channel(nsession); + + if (outbound_profile) { + caller_profile = switch_caller_profile_clone(nsession, outbound_profile); + switch_channel_set_caller_profile(nchannel, caller_profile); + } + + if ((hval = switch_event_get_header(var_event, "media_webrtc")) && switch_true(hval)) { + switch_channel_set_variable(nchannel, "rtc_secure_media", SWITCH_RTP_CRYPTO_KEY_80); + } + + if ((hval = switch_event_get_header(var_event, "rtc_secure_media"))) { + switch_channel_set_variable(nchannel, "rtc_secure_media", hval); + } + + rtc_attach_private(nsession, tech_pvt, NULL); + + + if (switch_channel_get_state(nchannel) == CS_NEW) { + switch_channel_set_state(nchannel, CS_INIT); + } + + tech_pvt->caller_profile = caller_profile; + *new_session = nsession; + cause = SWITCH_CAUSE_SUCCESS; + + + if (session) { + switch_ivr_transfer_variable(session, nsession, "rtc_video_fmtp"); + } + + goto done; + + error: + + if (nsession) { + switch_core_session_destroy(&nsession); + } + + if (pool) { + *pool = NULL; + } + + done: + + return cause; +} + +static int rtc_recover_callback(switch_core_session_t *session) +{ + private_object_t *tech_pvt = rtc_new_pvt(session); + rtc_attach_private(session, tech_pvt, NULL); + + return 1; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_rtc_load) +{ + memset(&mod_rtc_globals, 0, sizeof(mod_rtc_globals)); + mod_rtc_globals.pool = pool; + switch_mutex_init(&mod_rtc_globals.mutex, SWITCH_MUTEX_NESTED, mod_rtc_globals.pool); + + switch_mutex_lock(mod_rtc_globals.mutex); + mod_rtc_globals.running = 1; + switch_mutex_unlock(mod_rtc_globals.mutex); + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + rtc_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); + rtc_endpoint_interface->interface_name = "rtc"; + rtc_endpoint_interface->io_routines = &rtc_io_routines; + rtc_endpoint_interface->state_handler = &rtc_event_handlers; + rtc_endpoint_interface->recover_callback = rtc_recover_callback; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rtc_shutdown) +{ + switch_mutex_lock(mod_rtc_globals.mutex); + if (mod_rtc_globals.running == 1) { + mod_rtc_globals.running = 0; + } + switch_mutex_unlock(mod_rtc_globals.mutex); + + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ + From 8b893130451824296738976794f600fe327b1736 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Wed, 28 May 2014 11:49:22 -0400 Subject: [PATCH 67/79] rayo config: increase mod_shout outscale to mpg123 default of 32768 --- conf/rayo/autoload_configs/shout.conf.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/rayo/autoload_configs/shout.conf.xml b/conf/rayo/autoload_configs/shout.conf.xml index 3f381e6278..c3d1334b68 100644 --- a/conf/rayo/autoload_configs/shout.conf.xml +++ b/conf/rayo/autoload_configs/shout.conf.xml @@ -3,6 +3,7 @@ - + + From a976badec7257a904bb77353af085cedc8c78fbe Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Wed, 28 May 2014 17:03:46 +0000 Subject: [PATCH 68/79] Document the length limit of fifo_outbound_uuid Ask me sometime how I was "reminded" of this. --- src/mod/applications/mod_fifo/mod_fifo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 48b02422aa..b8ae5433cd 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -86,9 +86,12 @@ SWITCH_MODULE_DEFINITION(mod_fifo, mod_fifo_load, mod_fifo_shutdown, NULL); * from receiving a call from the fifo system. We do this by tracking * non-fifo calls in a special fifo named `manual_calls`. When * creating a channel for an agent we set the channel variable - * `fifo_outbound_uuid` to an arbitrary unique value for that agent, - * then call `fifo_track_call`. For the corresponding member we must - * also set `{fifo_outbound_uuid=}` to the same value. + * `fifo_outbound_uuid` to an arbitrary unique value <= 32 characters + * for that agent, then call `fifo_track_call`. For the corresponding + * member we must also set `{fifo_outbound_uuid=}` to the same value. + * We expect the value of `fifo_outbound_uuid` to be the MD5 hash of + * the unique ID. Values longer than 32 characters will cause the + * mechanism to fail to work as expected. * * ## Importance * From 93561c6720368debc0d37b7c67e1f40dcbdd24b1 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 28 May 2014 12:29:39 -0500 Subject: [PATCH 69/79] Nike edition of makefile for quickly building debian7 or centos 6.5 freeswitch takes care of all deps. --- build/Makefile.centos6 | 92 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 build/Makefile.centos6 diff --git a/build/Makefile.centos6 b/build/Makefile.centos6 new file mode 100644 index 0000000000..0fee662b2c --- /dev/null +++ b/build/Makefile.centos6 @@ -0,0 +1,92 @@ +# +# FreeSWITCH auto-build Makefile (CentOS 5.10 Wingardium Leviosa Edition) +# http://www.freeswitch.org +# put this file anywhere and type make to +# create a fully-built freeswitch.git from scratch +# in that same directory. +# +# Brian West +# +FSPREFIX=/usr/local/freeswitch +PREFIX=/opt/fs-libs +JPEG=v8d +OPENSSL=1.0.1g +SQLITE=autoconf-3080403 +PCRE=8.35 +CURL=7.36.0 +SPEEX=1.2rc1 +LIBEDIT=20140213-3.1 +LDNS=1.6.17 + +freeswitch: deps has-git freeswitch.git/Makefile + cd freeswitch.git && make + +freeswitch.git/Makefile: freeswitch.git/configure + cd freeswitch.git && PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig ./configure LDFLAGS='-L$(PREFIX)/lib -Wl,-rpath=$(PREFIX)/lib' CFLAGS='-I$(PREFIX)/include' --prefix=$(FSPREFIX) + +freeswitch.git/configure: freeswitch.git/bootstrap.sh + cd freeswitch.git && sh bootstrap.sh + +freeswitch.git/bootstrap.sh: has-git + test -d freeswitch.git || git clone git://git.freeswitch.org/freeswitch.git freeswitch.git + +install: freeswitch + cd freeswitch.git && make install + +install-git: + rpm -i http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm + yum update -y + yum install -y git gcc-c++ wget ncurses-devel zlib-devel e2fsprogs-devel libtool automake autoconf + +has-git: + @git --version || (echo "please install git by running 'make install-git'" && false) + +libjpeg: jpeg-8d/Makefile + +jpeg-8d/Makefile: + (test -d jpeg-8d) || (wget -4 -O jpegsrc.$(JPEG).tar.gz http://www.ijg.org/files/jpegsrc.$(JPEG).tar.gz && tar zxfv jpegsrc.$(JPEG).tar.gz) + (cd jpeg-8d && ./configure --prefix=$(PREFIX) && make && sudo make install) + +openssl: openssl-$(OPENSSL) + +openssl-$(OPENSSL): + (test -d $@) || (wget -4 -O $@.tar.gz http://www.openssl.org/source/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./Configure --prefix=$(PREFIX) linux-x86_64 shared && make && sudo make install) + +sqlite: sqlite-$(SQLITE) + +sqlite-$(SQLITE): + (test -d $@) || (wget -4 -O $@.tar.gz http://www.sqlite.org/2014/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +pcre: pcre-$(PCRE) + +pcre-$(PCRE): + (test -d $@) || (wget -4 -O $@.tar.gz http://downloads.sourceforge.net/project/pcre/pcre/$(PCRE)/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +curl: curl-$(CURL) + +curl-$(CURL): + (test -d $@) || (wget -4 -O $@.tar.gz http://curl.haxx.se/download/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +speex: speex-$(SPEEX) + +speex-$(SPEEX): + (test -d $@) || (wget -4 -O $@.tar.gz http://downloads.xiph.org/releases/speex/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +libedit: libedit-$(LIBEDIT) + +libedit-$(LIBEDIT): + (test -d $@) || (wget -4 -O $@.tar.gz http://thrysoee.dk/editline/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) + +ldns: ldns-$(LDNS) + +ldns-$(LDNS): openssl + (test -d $@) || (wget -4 -O $@.tar.gz http://www.nlnetlabs.nl/downloads/ldns/$@.tar.gz && tar zxfv $@.tar.gz) + (cd $@ && ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && make && sudo make install) + +deps: libjpeg openssl sqlite pcre curl speex libedit ldns From eb923bbd2d9f58f4fadff58ffc68a80ad518e622 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 28 May 2014 12:32:28 -0500 Subject: [PATCH 70/79] Copy snafu here is the correct file --- build/Makefile.centos6 | 82 +++++++----------------------------------- 1 file changed, 12 insertions(+), 70 deletions(-) diff --git a/build/Makefile.centos6 b/build/Makefile.centos6 index 0fee662b2c..9c27f2e7ad 100644 --- a/build/Makefile.centos6 +++ b/build/Makefile.centos6 @@ -1,28 +1,19 @@ # -# FreeSWITCH auto-build Makefile (CentOS 5.10 Wingardium Leviosa Edition) +# FreeSWITCH auto-build Makefile (CentOS 6.5/Debian 7 Nike Edition, JUST DO IT!) # http://www.freeswitch.org # put this file anywhere and type make to # create a fully-built freeswitch.git from scratch # in that same directory. # -# Brian West # -FSPREFIX=/usr/local/freeswitch -PREFIX=/opt/fs-libs -JPEG=v8d -OPENSSL=1.0.1g -SQLITE=autoconf-3080403 -PCRE=8.35 -CURL=7.36.0 -SPEEX=1.2rc1 -LIBEDIT=20140213-3.1 -LDNS=1.6.17 +RPMS=git gcc-c++ autoconf automake libtool wget python ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel +DEBS=git build-essential automake autoconf libtool wget python zlib1g-dev libjpeg-dev libncurses5-dev libssl-dev libpcre3-dev libcurl4-openssl-dev libldns-dev libedit-dev libspeexdsp-dev libspeexdsp-dev libsqlite3-dev freeswitch: deps has-git freeswitch.git/Makefile cd freeswitch.git && make freeswitch.git/Makefile: freeswitch.git/configure - cd freeswitch.git && PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig ./configure LDFLAGS='-L$(PREFIX)/lib -Wl,-rpath=$(PREFIX)/lib' CFLAGS='-I$(PREFIX)/include' --prefix=$(FSPREFIX) + cd freeswitch.git && ./configure freeswitch.git/configure: freeswitch.git/bootstrap.sh cd freeswitch.git && sh bootstrap.sh @@ -30,63 +21,14 @@ freeswitch.git/configure: freeswitch.git/bootstrap.sh freeswitch.git/bootstrap.sh: has-git test -d freeswitch.git || git clone git://git.freeswitch.org/freeswitch.git freeswitch.git -install: freeswitch +rpmforge: + (which rpm && rpm -i http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm) || true + +install: cd freeswitch.git && make install -install-git: - rpm -i http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm - yum update -y - yum install -y git gcc-c++ wget ncurses-devel zlib-devel e2fsprogs-devel libtool automake autoconf +has-git: + @git --version || (echo "please install git" && false) -has-git: - @git --version || (echo "please install git by running 'make install-git'" && false) - -libjpeg: jpeg-8d/Makefile - -jpeg-8d/Makefile: - (test -d jpeg-8d) || (wget -4 -O jpegsrc.$(JPEG).tar.gz http://www.ijg.org/files/jpegsrc.$(JPEG).tar.gz && tar zxfv jpegsrc.$(JPEG).tar.gz) - (cd jpeg-8d && ./configure --prefix=$(PREFIX) && make && sudo make install) - -openssl: openssl-$(OPENSSL) - -openssl-$(OPENSSL): - (test -d $@) || (wget -4 -O $@.tar.gz http://www.openssl.org/source/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./Configure --prefix=$(PREFIX) linux-x86_64 shared && make && sudo make install) - -sqlite: sqlite-$(SQLITE) - -sqlite-$(SQLITE): - (test -d $@) || (wget -4 -O $@.tar.gz http://www.sqlite.org/2014/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) - -pcre: pcre-$(PCRE) - -pcre-$(PCRE): - (test -d $@) || (wget -4 -O $@.tar.gz http://downloads.sourceforge.net/project/pcre/pcre/$(PCRE)/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) - -curl: curl-$(CURL) - -curl-$(CURL): - (test -d $@) || (wget -4 -O $@.tar.gz http://curl.haxx.se/download/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) - -speex: speex-$(SPEEX) - -speex-$(SPEEX): - (test -d $@) || (wget -4 -O $@.tar.gz http://downloads.xiph.org/releases/speex/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) - -libedit: libedit-$(LIBEDIT) - -libedit-$(LIBEDIT): - (test -d $@) || (wget -4 -O $@.tar.gz http://thrysoee.dk/editline/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./configure --prefix=$(PREFIX) && make && sudo make install) - -ldns: ldns-$(LDNS) - -ldns-$(LDNS): openssl - (test -d $@) || (wget -4 -O $@.tar.gz http://www.nlnetlabs.nl/downloads/ldns/$@.tar.gz && tar zxfv $@.tar.gz) - (cd $@ && ./configure --with-ssl=$(PREFIX) --prefix=$(PREFIX) && make && sudo make install) - -deps: libjpeg openssl sqlite pcre curl speex libedit ldns +deps: rpmforge + ((which yum && yum -y install $(RPMS)) || (which apt-get && apt-get -y install $(DEBS))) || true From 50dfce2845637f6c7ba00507ba8367fd1edf76dc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 29 May 2014 01:14:28 +0500 Subject: [PATCH 71/79] FS-6513 --resolve This function was assuming the app was being run with execute_on_media so it did not properly check for established media. Now it will use the scheduler method automatically when this state is detected. --- src/switch_core_session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 15f18c5ab0..61c8ac54e2 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1547,11 +1547,11 @@ SWITCH_DECLARE(void) switch_core_session_enable_heartbeat(switch_core_session_t session->track_duration = seconds; - if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || + if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || !switch_channel_media_ready(session->channel) || switch_true(switch_channel_get_variable_dup(session->channel, "heartbeat_use_scheduler", SWITCH_FALSE, -1)) || switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media", SWITCH_FALSE, -1)) || switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_bridge", SWITCH_FALSE, -1))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s using scheduler due to bypass_media mode\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s using scheduler due to bypass media or media is not established.\n", switch_channel_get_name(session->channel)); switch_core_session_sched_heartbeat(session, seconds); return; From bf59d57dabc9e22e1e1f9f10ed8c3218e7678a3d Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 13:06:35 +0000 Subject: [PATCH 72/79] Add missing parenthesis pair This would have briefly caused the importance value in the fifo config file to be ignored. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index b8ae5433cd..2a0f82d369 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4481,7 +4481,7 @@ static switch_status_t load_config(int reload, int del_all) continue; } - if ((val = switch_xml_attr(fifo, "importance")) && !(i = atoi(val)) < 0) { + if ((val = switch_xml_attr(fifo, "importance")) && !((i = atoi(val)) < 0)) { importance = i; } From 84fe7b07941e5c40bf16b45df2c7fb520b7d3d4a Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 13:15:44 +0000 Subject: [PATCH 73/79] Remove tautological condition check We already decided to goto end if node is null, so it cannot be null here. --- src/mod/applications/mod_fifo/mod_fifo.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 2a0f82d369..768ed67847 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1459,14 +1459,10 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr goto end; } - if (node) { - switch_mutex_lock(node->update_mutex); - node->busy = 0; - node->ring_consumer_count = 1; - switch_mutex_unlock(node->update_mutex); - } else { - goto end; - } + switch_mutex_lock(node->update_mutex); + node->busy = 0; + node->ring_consumer_count = 1; + switch_mutex_unlock(node->update_mutex); SWITCH_STANDARD_STREAM(stream); SWITCH_STANDARD_STREAM(stream2); From 17137d089de0e4fb6a81f1137fbc3799a328c493 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 13:21:22 +0000 Subject: [PATCH 74/79] Add missing parenthesis pair This would have briefly prevented setting outbound_per_cycle from the mod_fifo config file. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 768ed67847..1d48e6f0a3 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4501,7 +4501,7 @@ static switch_status_t load_config(int reload, int del_all) node->outbound_per_cycle = 1; if ((val = switch_xml_attr(fifo, "outbound_per_cycle"))) { - if (!(i = atoi(val)) < 0) { + if (!((i = atoi(val)) < 0)) { node->outbound_per_cycle = i; } node->has_outbound = 1; From e66d24622ace62fec5fef2a4b22c74ed92baeaa4 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 14:10:44 +0000 Subject: [PATCH 75/79] Fix potential dereference of null pointer The node could conceivably disappear before we grab the globals mutex and we'd get back a null pointer. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 1d48e6f0a3..ce980ae2c0 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1791,7 +1791,7 @@ static void *SWITCH_THREAD_FUNC outbound_enterprise_thread_run(switch_thread_t * switch_mutex_lock(globals.mutex); node = switch_core_hash_find(globals.fifo_hash, h->node_name); - switch_thread_rwlock_rdlock(node->rwlock); + if (node) switch_thread_rwlock_rdlock(node->rwlock); switch_mutex_unlock(globals.mutex); if (node) { From 6663692ff7a1f3aeb8abaed80486b930203dc01f Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 14:24:48 +0000 Subject: [PATCH 76/79] Assert on implied failure to malloc switch_event_expand_headers should only return null on a malloc failure, so we might as well just assert here. --- src/mod/applications/mod_fifo/mod_fifo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index ce980ae2c0..95402638cc 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1476,6 +1476,7 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr int use_ent = 0; char *expanded_originate_string = switch_event_expand_headers(ovars, h->originate_string); + switch_assert(expanded_originate_string); if (strstr(expanded_originate_string, "user/")) { switch_event_create_brackets(expanded_originate_string, '<', '>', ',', &ovars, &parsed, SWITCH_TRUE); use_ent = 1; From 609982cf2fd51213c4c30236a0b68c680f90c738 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 14:25:49 +0000 Subject: [PATCH 77/79] Remove redundant check for null We're asserting now, and we would have already blown up from dereferencing earlier. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 95402638cc..1c6cef66c1 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -1501,7 +1501,7 @@ static void *SWITCH_THREAD_FUNC outbound_ringall_thread_run(switch_thread_t *thr stream2.write_function(&stream2, "%s,", h->uuid); switch_safe_free(parsed); - if (expanded_originate_string && expanded_originate_string != h->originate_string) { + if (expanded_originate_string != h->originate_string) { switch_safe_free(expanded_originate_string); } } From 2b0c9a14829d0263952dc3449ee7c9fe2a98e96d Mon Sep 17 00:00:00 2001 From: William King Date: Thu, 29 May 2014 08:37:21 -0700 Subject: [PATCH 78/79] FS-6560 --resolve --- src/mod/xml_int/mod_xml_radius/mod_xml_radius.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c index 1ad31a58f4..95b437722c 100644 --- a/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c +++ b/src/mod/xml_int/mod_xml_radius/mod_xml_radius.c @@ -479,7 +479,7 @@ switch_status_t mod_xml_radius_add_params(switch_core_session_t *session, switch if ( GLOBAL_TIME_FORMAT == 1 ) { av_value = switch_mprintf("%02u:%02u:%02u.%03u %s %s %s %02u %04u", tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000, - GLOBAL_TIME_FORMAT, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], + GLOBAL_TIME_ZONE, radattrdays[tm.tm_wday], radattrmonths[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900); } else { av_value = switch_mprintf("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+03d%02d", From b53a6c2b2e2830976a54567834bb1ebd84bb9f6e Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Thu, 29 May 2014 15:59:49 +0000 Subject: [PATCH 79/79] Remove unused assignment If we don't find it, we create a new one, and if we do find it, we don't use it. --- src/mod/applications/mod_fifo/mod_fifo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 1c6cef66c1..ff00fec256 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -4456,7 +4456,7 @@ static switch_status_t load_config(int reload, int del_all) fifo_execute_sql_queued(&sql, SWITCH_TRUE, SWITCH_TRUE); - if (!(node = switch_core_hash_find(globals.fifo_hash, MANUAL_QUEUE_NAME))) { + if (!switch_core_hash_find(globals.fifo_hash, MANUAL_QUEUE_NAME)) { node = create_node(MANUAL_QUEUE_NAME, 0, globals.sql_mutex); node->ready = 2; node->is_static = 0;