From db0dfe94d079e8b82c5ca93092faa2fe204b0d06 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Wed, 27 Apr 2016 11:34:58 -0700 Subject: [PATCH 01/72] FS-9113 [sofia-sip] Clear out ssl error queue Sofia will unpredictably close a tls transport during call setup. This occurs when the epoll event loop wakes up the socket reader and SSL_read returns an error because there is no packet on the socket. Normally sofia will read the last error using SSL_get_error and return SSL_ERROR_WANT_READ. Sofia gracefully handles this error and the transport stays open. Sometimes, however, the worker thread will call SSL_shutdown for a different transport, which can write an error to the internal openssl error queue. If that error is not read off the queue, the next time that SSL_get_error is called, it will read that unrelated error. The documentation for SSL_shutdown explains that there are three possible results -1, 0 and 1 with, oddly, 1 indicating success. The -1 result code occurs when there is no handshake callback registered on the connection. It can return 0 when there is still work to be done. The documentation suggest that it is insufficient to call it just once. This is why I added the do {} while () construct. Although just the fix to SSL_shutdown was enough to resolve my issue, I a also audited other calls to SSL_* functions and found a few other cases where an error may be generated, but was not handled. --- .../libsofia-sip-ua/tport/tport_tls.c | 27 ++++++++++++++----- .../libsofia-sip-ua/tport/tport_tls.h | 1 + .../libsofia-sip-ua/tport/tport_type_ws.c | 27 ++++++++++++++----- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c index 976a88dede..c872336b0b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c @@ -137,7 +137,6 @@ enum { tls_buffer_size = 16384 }; * Log the TLS error specified by the error code @a e and all the errors in * the queue. The error code @a e implies no error, and it is not logged. */ -static void tls_log_errors(unsigned level, char const *s, unsigned long e) { if (e == 0) @@ -449,12 +448,22 @@ int tls_init_context(tls_t *tls, tls_issues_t const *ti) void tls_free(tls_t *tls) { + int ret; if (!tls) return; if (tls->con != NULL) { - SSL_shutdown(tls->con); - SSL_free(tls->con), tls->con = NULL; + do { + ret = SSL_shutdown(tls->con); + if (ret == -1) { + /* The return value -1 means that the connection wasn't actually established */ + /* so it should be safe to not call shutdown again. We need to clear the eror */ + /* queue for other connections though. */ + tls_log_errors(3, "tls_free", 0); + ret = 1; + } + } while (ret != 1); + SSL_free(tls->con), tls->con = NULL; } if (tls->ctx != NULL && tls->type != tls_slave) { @@ -498,13 +507,18 @@ tls_t *tls_init_master(tls_issues_t *ti) RAND_pseudo_bytes(sessionId, sizeof(sessionId)); - SSL_CTX_set_session_id_context(tls->ctx, + if (!SSL_CTX_set_session_id_context(tls->ctx, (void*) sessionId, - sizeof(sessionId)); + sizeof(sessionId))) { + tls_log_errors(3, "tls_init_master", 0); + } - if (ti->CAfile != NULL) + if (ti->CAfile != NULL) { SSL_CTX_set_client_CA_list(tls->ctx, SSL_load_client_CA_file(ti->CAfile)); + if (tls->ctx->client_CA == NULL) + tls_log_errors(3, "tls_init_master", 0); + } #if 0 if (sock != -1) { @@ -576,6 +590,7 @@ int tls_post_connection_check(tport_t *self, tls_t *tls) if (!tls) return -1; if (!(cipher = SSL_get_current_cipher(tls->con))) { + tls_log_errors(3, "tls_post_connection_check", 0); SU_DEBUG_7(("%s(%p): %s\n", __func__, (void*)self, "OpenSSL failed to return an SSL_CIPHER object to us.")); return SSL_ERROR_SSL; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h index 74a8db6a15..e8d04a14b7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h @@ -83,6 +83,7 @@ tls_t *tls_init_master(tls_issues_t *tls_issues); tls_t *tls_init_secondary(tls_t *tls_master, int sock, int accept); void tls_free(tls_t *tls); int tls_get_socket(tls_t *tls); +void tls_log_errors(unsigned level, char const *s, unsigned long e); ssize_t tls_read(tls_t *tls); void *tls_read_buffer(tls_t *tls, size_t N); int tls_want_read(tls_t *tls, int events); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c index 8857515cb3..050b2f8364 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c @@ -385,22 +385,37 @@ static int tport_ws_init_primary_secure(tport_primary_t *pri, SSL_CTX_sess_set_remove_cb(wspri->ssl_ctx, NULL); wspri->ws_secure = 1; - if ( !wspri->ssl_ctx ) goto done; + if ( !wspri->ssl_ctx ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } if (chain) { - SSL_CTX_use_certificate_chain_file(wspri->ssl_ctx, chain); + if ( !SSL_CTX_use_certificate_chain_file(wspri->ssl_ctx, chain) ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + } } /* set the local certificate from CertFile */ - SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM); + if ( !SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM) ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } /* set the private key from KeyFile */ - SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM); + if ( !SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM) ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } /* verify private key */ if ( !SSL_CTX_check_private_key(wspri->ssl_ctx) ) { - goto done; + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; } - SSL_CTX_set_cipher_list(wspri->ssl_ctx, "!eNULL:!aNULL:!DSS:HIGH:@STRENGTH"); + if ( !SSL_CTX_set_cipher_list(wspri->ssl_ctx, "!eNULL:!aNULL:!DSS:HIGH:@STRENGTH") ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } ret = tport_ws_init_primary(pri, tpn, ai, tags, return_culprit); From 69d643b53f5c72a33728a73b9fbf0b0ecc41b7e6 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 6 May 2016 18:26:07 +0200 Subject: [PATCH 02/72] Properly handle NULL var_name for switch_play_and_get_digits Do not set "_invalid" in case var_name is empty or unset. While at it, clear the "foo_invalid" variable before doing anything else when a regex is passed, this ensures that the variable really reflects the current run. Fixes an issue in original FS-7783 feature. --- src/switch_ivr_play_say.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index d856131dd8..4a1d6da68c 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -2252,6 +2252,13 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t const char *transfer_on_failure) { switch_channel_t *channel = switch_core_session_get_channel(session); + char *var_name_invalid = NULL; + + if (!zstr(digits_regex) && !zstr(var_name)) { + var_name_invalid = switch_mprintf("%s_invalid", var_name); + switch_channel_set_variable(channel, var_name_invalid, NULL); + switch_safe_free(var_name_invalid); + } while (switch_channel_ready(channel) && max_tries) { switch_status_t status; @@ -2277,21 +2284,20 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t if (!(status == SWITCH_STATUS_TOO_SMALL && strlen(digit_buffer) == 0)) { if (status == SWITCH_STATUS_SUCCESS) { if (!zstr(digit_buffer)) { - char *invalid_var = NULL; if (zstr(digits_regex)) { return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "Test Regex [%s][%s]\n", digit_buffer, digits_regex); - invalid_var = switch_mprintf("%s_invalid", var_name); if (switch_regex_match(digit_buffer, digits_regex) == SWITCH_STATUS_SUCCESS) { - switch_channel_set_variable(channel, invalid_var, NULL); - switch_safe_free(invalid_var); return SWITCH_STATUS_SUCCESS; } else { switch_channel_set_variable(channel, var_name, NULL); - switch_channel_set_variable(channel, invalid_var, digit_buffer); - switch_safe_free(invalid_var); + if (!zstr(var_name)) { + var_name_invalid = switch_mprintf("%s_invalid", var_name); + switch_channel_set_variable(channel, var_name_invalid, digit_buffer); + switch_safe_free(var_name_invalid); + } } } } From b5169e770c255afd19a87ab7478239e7ec1077cd Mon Sep 17 00:00:00 2001 From: Hesaam Farhang Date: Wed, 4 May 2016 19:12:44 -0700 Subject: [PATCH 03/72] FS-9132: [mod_kazoo] Add more vars to default filter --- .../event_handlers/mod_kazoo/kazoo_utils.c | 19 +++++++++++++++++++ src/mod/event_handlers/mod_kazoo/mod_kazoo.c | 3 ++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c index 1284118daf..127f849cdc 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c @@ -477,6 +477,9 @@ switch_hash_t *create_default_filter() { switch_core_hash_insert(filter, "whistle_application_name", "1"); switch_core_hash_insert(filter, "whistle_application_response", "1"); switch_core_hash_insert(filter, "whistle_event_name", "1"); + switch_core_hash_insert(filter, "kazoo_application_name", "1"); + switch_core_hash_insert(filter, "kazoo_application_response", "1"); + switch_core_hash_insert(filter, "kazoo_event_name", "1"); switch_core_hash_insert(filter, "sip_auto_answer_notify", "1"); switch_core_hash_insert(filter, "eavesdrop_group", "1"); switch_core_hash_insert(filter, "origination_caller_id_name", "1"); @@ -489,6 +492,21 @@ switch_hash_t *create_default_filter() { switch_core_hash_insert(filter, "effective_caller_id_number", "1"); switch_core_hash_insert(filter, "effective_callee_id_name", "1"); switch_core_hash_insert(filter, "effective_callee_id_number", "1"); + switch_core_hash_insert(filter, "variable_destination_number", "1"); + switch_core_hash_insert(filter, "variable_effective_callee_id_name", "1"); + switch_core_hash_insert(filter, "variable_effective_callee_id_number", "1"); + switch_core_hash_insert(filter, "variable_record_silence_hits", "1"); + switch_core_hash_insert(filter, "variable_refer_uuid", "1"); + switch_core_hash_insert(filter, "variable_sip_call_id", "1"); + switch_core_hash_insert(filter, "variable_sip_h_Referred-By", "1"); + switch_core_hash_insert(filter, "variable_sip_h_X-AUTH-PORT", "1"); + switch_core_hash_insert(filter, "variable_sip_loopback_req_uri", "1"); + switch_core_hash_insert(filter, "variable_sip_received_port", "1"); + switch_core_hash_insert(filter, "variable_sip_refer_to", "1"); + switch_core_hash_insert(filter, "variable_sip_req_host", "1"); + switch_core_hash_insert(filter, "variable_sip_req_uri", "1"); + switch_core_hash_insert(filter, "variable_transfer_source", "1"); + switch_core_hash_insert(filter, "variable_uuid", "1"); /* Registration headers */ switch_core_hash_insert(filter, "call-id", "1"); @@ -570,6 +588,7 @@ switch_hash_t *create_default_filter() { switch_core_hash_insert(filter, "variable_fax_timezone", "1"); switch_core_hash_insert(filter, "variable_fax_doc_id", "1"); switch_core_hash_insert(filter, "variable_fax_doc_database", "1"); + switch_core_hash_insert(filter, "variable_has_t38", "1"); /* Secure headers */ switch_core_hash_insert(filter, "variable_sdp_secure_savp_only", "1"); diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c index ebf3af3f8c..4771f53c2d 100644 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c +++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c @@ -340,7 +340,8 @@ static int read_cookie_from_file(char *filename) { static switch_status_t config(void) { char *cf = "kazoo.conf"; switch_xml_t cfg, xml, child, param; - globals.send_all_headers = globals.send_all_private_headers = 0; + globals.send_all_headers = 0; + globals.send_all_private_headers = 1; globals.connection_timeout = 500; globals.receive_timeout = 200; globals.receive_msg_preallocate = 2000; From 8153b6fdeef9785dc044de7068cab38ee1ea9e5d Mon Sep 17 00:00:00 2001 From: Hesaam Farhang Date: Fri, 6 May 2016 10:44:34 -0700 Subject: [PATCH 04/72] FS-9132: [mod_kazoo] remove whitespaces --- .../event_handlers/mod_kazoo/kazoo_commands.c | 2 +- .../event_handlers/mod_kazoo/kazoo_dptools.c | 6 +- .../mod_kazoo/kazoo_event_stream.c | 30 +-- src/mod/event_handlers/mod_kazoo/kazoo_node.c | 2 +- src/mod/event_handlers/mod_kazoo/mod_kazoo.c | 216 +++++++++--------- 5 files changed, 128 insertions(+), 128 deletions(-) diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c index ab9b65386b..4de71398f4 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c @@ -148,5 +148,5 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface, swit SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi", UUID_SET_DESC, uuid_setvar_multi_function, UUID_MULTISET_SYNTAX); switch_console_set_complete("add kz_uuid_setvar_multi ::console::list_uuid"); SWITCH_ADD_API(api_interface, "kz_uuid_setvar", UUID_MULTISET_DESC, uuid_setvar_function, UUID_SET_SYNTAX); - switch_console_set_complete("add kz_uuid_setvar ::console::list_uuid"); + switch_console_set_complete("add kz_uuid_setvar ::console::list_uuid"); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c index e6453d6490..352edaae82 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c @@ -141,7 +141,7 @@ SWITCH_STANDARD_APP(multiset_function) { arg = switch_core_session_strdup(session, arg); argc = switch_split(arg, delim, array); - + for(i = 0; i < argc; i++) { base_set(session, array[i], SWITCH_STACK_BOTTOM); } @@ -178,7 +178,7 @@ SWITCH_STANDARD_APP(unset_function) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UNSET [%s]\n", (char *) data); switch_channel_set_variable(switch_core_session_get_channel(session), data, NULL); } - + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); switch_event_fire(&event); @@ -242,7 +242,7 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switc SWITCH_ADD_APP(app_interface, "kz_unset", UNSET_SHORT_DESC, UNSET_LONG_DESC, unset_function, UNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_multiunset", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiunset_function, MULTIUNSET_SYNTAX, - SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); + SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_export", EXPORT_SHORT_DESC, EXPORT_LONG_DESC, export_function, EXPORT_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c index 00eb06a126..cf43ce1f45 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c @@ -37,7 +37,7 @@ static char *my_dup(const char *s) { size_t len = strlen(s) + 1; void *new = malloc(len); switch_assert(new); - + return (char *) memcpy(new, s, len); } @@ -58,21 +58,21 @@ static int is_private_header(const char *name) { static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *event, switch_hash_t *filter) { switch_event_header_t *header; - + if (switch_event_create_subclass(clone, SWITCH_EVENT_CLONE, event->subclass_name) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; } - + (*clone)->event_id = event->event_id; (*clone)->event_user_data = event->event_user_data; (*clone)->bind_user_data = event->bind_user_data; (*clone)->flags = event->flags; - + for (header = event->headers; header; header = header->next) { if (event->subclass_name && !strcmp(header->name, "Event-Subclass")) { continue; } - + if (strncmp(header->name, globals.kazoo_var_prefix, globals.var_prefix_length) && filter && !switch_core_hash_find(filter, header->name) @@ -82,7 +82,7 @@ static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *e { continue; } - + if (header->idx) { int i; for (i = 0; i < header->idx; i++) { @@ -92,33 +92,33 @@ static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *e switch_event_add_header_string(*clone, SWITCH_STACK_BOTTOM, header->name, header->value); } } - + if (event->body) { (*clone)->body = DUP(event->body); } - + (*clone)->key = event->key; - + return SWITCH_STATUS_SUCCESS; } static void event_handler(switch_event_t *event) { switch_event_t *clone = NULL; ei_event_stream_t *event_stream = (ei_event_stream_t *) event->bind_user_data; - + /* if mod_kazoo or the event stream isn't running dont push a new event */ if (!switch_test_flag(event_stream, LFLAG_RUNNING) || !switch_test_flag(&globals, LFLAG_RUNNING)) { return; } - + if (event->event_id == SWITCH_EVENT_CUSTOM) { ei_event_binding_t *event_binding = event_stream->bindings; unsigned short int found = 0; - + if (!event->subclass_name) { return; } - + while(event_binding != NULL) { if (event_binding->type == SWITCH_EVENT_CUSTOM) { if(event_binding->subclass_name @@ -238,9 +238,9 @@ static void *SWITCH_THREAD_FUNC event_stream_loop(switch_thread_t *thread, void } else { ei_x_new_with_version(&ebuf); } - + ei_encode_switch_event(&ebuf, event); - + if (globals.event_stream_preallocate > 0 && ebuf.buffsz > globals.event_stream_preallocate) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "increased event stream buffer size to %d\n", ebuf.buffsz); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c index 0ffd3ffdf0..1efe7e3e82 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_node.c @@ -1092,7 +1092,7 @@ static void *SWITCH_THREAD_FUNC handle_node(switch_thread_t *thread, void *obj) ei_x_new(&received_msg->buf); } } - + while (switch_queue_trypop(ei_node->send_msgs, &pop) == SWITCH_STATUS_SUCCESS && ++send_msg_count <= globals.send_msg_batch) { ei_send_msg_t *send_msg = (ei_send_msg_t *) pop; diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c index 4771f53c2d..dd305fe911 100644 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c +++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c @@ -53,16 +53,16 @@ static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { char ipbuf[25]; const char *ip_addr; ei_node_t *ei_node; - + switch_socket_addr_get(&sa, SWITCH_FALSE, globals.acceptor); - + port = switch_sockaddr_get_port(sa); ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - + stream->write_function(stream, "Running %s\n", VERSION); stream->write_function(stream, "Listening for new Erlang connections on %s:%u with cookie %s\n", ip_addr, port, globals.ei_cookie); stream->write_function(stream, "Registered as Erlang node %s, visible as %s\n", globals.ei_cnode.thisnodename, globals.ei_cnode.thisalivename); - + if (globals.ei_compat_rel) { stream->write_function(stream, "Using Erlang compatibility mode: %d\n", globals.ei_compat_rel); } @@ -75,7 +75,7 @@ static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { stream->write_function(stream, "Connected to:\n"); while(ei_node != NULL) { unsigned int year, day, hour, min, sec, delta; - + delta = (switch_micro_time_now() - ei_node->created_time) / 1000000; sec = delta % 60; min = delta / 60 % 60; @@ -88,14 +88,14 @@ static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { } } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) { switch_hash_index_t *hi = NULL; int column = 0; - + for (hi = (switch_hash_index_t *)switch_core_hash_first_iter(globals.event_filter, hi); hi; hi = switch_core_hash_next(&hi)) { const void *key; void *val; @@ -106,20 +106,20 @@ static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) { column = 0; } } - + if (++column > 2) { stream->write_function(stream, "\n"); column = 0; } - + stream->write_function(stream, "%-50s", globals.kazoo_var_prefix); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_nodes_list(switch_stream_handle_t *stream) { ei_node_t *ei_node; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { @@ -127,14 +127,14 @@ static switch_status_t api_erlang_nodes_list(switch_stream_handle_t *stream) { ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_nodes_count(switch_stream_handle_t *stream) { ei_node_t *ei_node; int count = 0; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { @@ -142,9 +142,9 @@ static switch_status_t api_erlang_nodes_count(switch_stream_handle_t *stream) { ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + stream->write_function(stream, "%d\n", count); - + return SWITCH_STATUS_SUCCESS; } @@ -152,7 +152,7 @@ static switch_status_t api_complete_erlang_node(const char *line, const char *cu switch_console_callback_match_t *my_matches = NULL; switch_status_t status = SWITCH_STATUS_FALSE; ei_node_t *ei_node; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { @@ -160,34 +160,34 @@ static switch_status_t api_complete_erlang_node(const char *line, const char *cu ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + if (my_matches) { *matches = my_matches; status = SWITCH_STATUS_SUCCESS; } - + return status; } static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_stream, switch_stream_handle_t *stream) { ei_event_binding_t *binding; int column = 0; - + switch_mutex_lock(event_stream->socket_mutex); if (event_stream->connected == SWITCH_FALSE) { switch_sockaddr_t *sa; uint16_t port; char ipbuf[25] = {0}; const char *ip_addr; - + switch_socket_addr_get(&sa, SWITCH_TRUE, event_stream->acceptor); port = switch_sockaddr_get_port(sa); ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - + if (zstr(ip_addr)) { ip_addr = globals.ip; } - + stream->write_function(stream, "%s:%d -> disconnected\n" ,ip_addr, port); } else { @@ -195,7 +195,7 @@ static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_str ,event_stream->local_ip, event_stream->local_port ,event_stream->remote_ip, event_stream->remote_port); } - + binding = event_stream->bindings; while(binding != NULL) { if (binding->type == SWITCH_EVENT_CUSTOM) { @@ -203,22 +203,22 @@ static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_str } else { stream->write_function(stream, "%-50s", switch_event_name(binding->type)); } - + if (++column > 2) { stream->write_function(stream, "\n"); column = 0; } - + binding = binding->next; } switch_mutex_unlock(event_stream->socket_mutex); - + if (!column) { stream->write_function(stream, "\n"); } else { stream->write_function(stream, "\n\n"); } - + return SWITCH_STATUS_SUCCESS; } @@ -232,13 +232,13 @@ static switch_status_t handle_node_api_event_streams(ei_node_t *ei_node, switch_ event_stream = event_stream->next; } switch_mutex_unlock(ei_node->event_streams_mutex); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command) { unsigned int year, day, hour, min, sec, delta; - + switch (command) { case API_COMMAND_DISCONNECT: stream->write_function(stream, "Disconnecting erlang node %s at managers request\n", ei_node->peer_nodename); @@ -251,7 +251,7 @@ static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream hour = delta / 3600 % 24; day = delta / 86400 % 7; year = delta / 31556926 % 12; - + stream->write_function(stream, "Uptime %d years, %d days, %d hours, %d minutes, %d seconds\n", year, day, hour, min, sec); stream->write_function(stream, "Local Address %s:%d\n", ei_node->local_ip, ei_node->local_port); stream->write_function(stream, "Remote Address %s:%d\n", ei_node->remote_ip, ei_node->remote_port); @@ -265,28 +265,28 @@ static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream default: break; } - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_node_command(switch_stream_handle_t *stream, const char *nodename, uint32_t command) { ei_node_t *ei_node; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { int length = strlen(ei_node->peer_nodename); - + if (!strncmp(ei_node->peer_nodename, nodename, length)) { handle_node_api_command(ei_node, stream, command); switch_thread_rwlock_unlock(globals.ei_nodes_lock); return SWITCH_STATUS_SUCCESS; } - + ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + return SWITCH_STATUS_NOTFOUND; } @@ -296,7 +296,7 @@ static int read_cookie_from_file(char *filename) { char *end; struct stat buf; ssize_t res; - + if (!stat(filename, &buf)) { if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename); @@ -311,24 +311,24 @@ static int read_cookie_from_file(char *filename) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno); return 2; } - + if ((res = read(fd, cookie, MAXATOMLEN)) < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno); } - + cookie[MAXATOMLEN] = '\0'; - + /* replace any end of line characters with a null */ if ((end = strchr(cookie, '\n'))) { *end = '\0'; } - + if ((end = strchr(cookie, '\r'))) { *end = '\0'; } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie from file %s: %s\n", filename, cookie); - + set_pref_ei_cookie(cookie); return 0; } else { @@ -349,7 +349,7 @@ static switch_status_t config(void) { globals.send_msg_batch = 10; globals.event_stream_framing = 2; globals.port = 0; - + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); return SWITCH_STATUS_FALSE; @@ -358,7 +358,7 @@ static switch_status_t config(void) { for (param = switch_xml_child(child, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); - + if (!strcmp(var, "listen-ip")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val); set_pref_ip(val); @@ -413,19 +413,19 @@ static switch_status_t config(void) { } } } - + if ((child = switch_xml_child(cfg, "event-filter"))) { switch_hash_t *filter; - + switch_core_hash_init(&filter); for (param = switch_xml_child(child, "header"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); switch_core_hash_insert(filter, var, "1"); } - + globals.event_filter = filter; } - + switch_xml_free(xml); } @@ -433,17 +433,17 @@ static switch_status_t config(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n"); globals.receive_msg_preallocate = 0; } - + if (globals.event_stream_preallocate < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n"); globals.event_stream_preallocate = 0; } - + if (globals.send_msg_batch < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n"); globals.send_msg_batch = 10; } - + if (!globals.event_filter) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n"); globals.event_filter = create_default_filter(); @@ -453,7 +453,7 @@ static switch_status_t config(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n"); globals.event_stream_framing = 2; } - + if (zstr(globals.kazoo_var_prefix)) { set_pref_kazoo_var_prefix("variable_ecallmgr*"); globals.var_prefix_length = 17; //ignore the * @@ -462,33 +462,33 @@ static switch_status_t config(void) { * free the pointer if it was not drawn from the XML */ char *buf; int size = switch_snprintf(NULL, 0, "variable_%s*", globals.kazoo_var_prefix) + 1; - + switch_malloc(buf, size); switch_snprintf(buf, size, "variable_%s*", globals.kazoo_var_prefix); switch_safe_free(globals.kazoo_var_prefix); globals.kazoo_var_prefix = buf; globals.var_prefix_length = size - 2; //ignore the * } - + if (!globals.num_worker_threads) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of worker threads not found in configuration, using default\n"); globals.num_worker_threads = 10; } - + if (zstr(globals.ip)) { set_pref_ip("0.0.0.0"); } - + if (zstr(globals.ei_cookie)) { int res; char *home_dir = getenv("HOME"); char path_buf[1024]; - + if (!zstr(home_dir)) { /* $HOME/.erlang.cookie */ switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf); - + res = read_cookie_from_file(path_buf); if (res) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n"); @@ -496,15 +496,15 @@ static switch_status_t config(void) { } } } - + if (!globals.ei_nodename) { set_pref_ei_nodename("freeswitch"); } - + if (!globals.nat_map) { globals.nat_map = 0; } - + return SWITCH_STATUS_SUCCESS; } @@ -513,38 +513,38 @@ static switch_status_t create_acceptor() { uint16_t port; char ipbuf[25]; const char *ip_addr; - + /* if the config has specified an erlang release compatibility then pass that along to the erlang interface */ if (globals.ei_compat_rel) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Compatability with OTP R%d requested\n", globals.ei_compat_rel); ei_set_compat_rel(globals.ei_compat_rel); } - + if (!(globals.acceptor = create_socket_with_port(globals.pool, globals.port))) { return SWITCH_STATUS_SOCKERR; } - + switch_socket_addr_get(&sa, SWITCH_FALSE, globals.acceptor); - + port = switch_sockaddr_get_port(sa); ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor listening on %s:%u\n", ip_addr, port); - + /* try to initialize the erlang interface */ if (create_ei_cnode(ip_addr, globals.ei_nodename, &globals.ei_cnode) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_SOCKERR; } - + /* tell the erlang port manager where we can be reached. this returns a file descriptor pointing to epmd or -1 */ if ((globals.epmdfd = ei_publish(&globals.ei_cnode, port)) == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to publish port to epmd. Try starting it yourself or run an erl shell with the -sname or -name option.\n"); return SWITCH_STATUS_SOCKERR; } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to epmd and published erlang cnode name %s at port %d\n", globals.ei_cnode.thisnodename, port); - + return SWITCH_STATUS_SUCCESS; } @@ -553,7 +553,7 @@ SWITCH_STANDARD_API(exec_api_cmd) char *argv[1024] = { 0 }; int unknown_command = 1, argc = 0; char *mycmd = NULL; - + const char *usage_string = "USAGE:\n" "--------------------------------------------------------------------------------------------------------------------\n" "erlang status - provides an overview of the current status\n" @@ -565,28 +565,28 @@ SWITCH_STANDARD_API(exec_api_cmd) "erlang node event_streams - lists the event streams for an Erlang node\n" "erlang node fetch_bindings - lists the XML fetch bindings for an Erlang node\n" "---------------------------------------------------------------------------------------------------------------------\n"; - + if (zstr(cmd)) { stream->write_function(stream, "%s", usage_string); return SWITCH_STATUS_SUCCESS; } - + if (!(mycmd = strdup(cmd))) { return SWITCH_STATUS_MEMERR; } - + if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { stream->write_function(stream, "%s", usage_string); switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; } - + if (zstr(argv[0])) { stream->write_function(stream, "%s", usage_string); switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; } - + if (!strncmp(argv[0], "status", 6)) { unknown_command = 0; api_erlang_status(stream); @@ -616,11 +616,11 @@ SWITCH_STANDARD_API(exec_api_cmd) api_erlang_node_command(stream, argv[1], API_COMMAND_BINDINGS); } } - + if (unknown_command) { stream->write_function(stream, "%s", usage_string); } - + switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; } @@ -628,28 +628,28 @@ SWITCH_STANDARD_API(exec_api_cmd) SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { switch_api_interface_t *api_interface = NULL; switch_application_interface_t *app_interface = NULL; - + memset(&globals, 0, sizeof(globals)); - + globals.pool = pool; globals.ei_nodes = NULL; - + if(config() != SWITCH_STATUS_SUCCESS) { // TODO: what would we need to clean up here? switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improper configuration!\n"); return SWITCH_STATUS_TERM; } - + if(create_acceptor() != SWITCH_STATUS_SUCCESS) { // TODO: what would we need to clean up here switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create erlang connection acceptor!\n"); close_socket(&globals.acceptor); return SWITCH_STATUS_TERM; } - + /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - + /* create an api for cli debug commands */ SWITCH_ADD_API(api_interface, "erlang", KAZOO_DESC, exec_api_cmd, KAZOO_SYNTAX); switch_console_set_complete("add erlang status"); @@ -661,13 +661,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { switch_console_set_complete("add erlang node ::erlang::node event_streams"); switch_console_set_complete("add erlang node ::erlang::node fetch_bindings"); switch_console_add_complete_func("::erlang::node", api_complete_erlang_node); - + switch_thread_rwlock_create(&globals.ei_nodes_lock, pool); - + switch_set_flag(&globals, LFLAG_RUNNING); - + /* create all XML fetch agents */ - bind_fetch_agents(); + bind_fetch_agents(); /* add our modified commands */ add_kz_commands(module_interface, api_interface); @@ -681,13 +681,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) { int sanity = 0; - + switch_console_set_complete("del erlang"); switch_console_del_complete_func("::erlang::node"); - + /* stop taking new requests and start shuting down the threads */ switch_clear_flag(&globals, LFLAG_RUNNING); - + /* give everyone time to cleanly shutdown */ while (switch_atomic_read(&globals.threads)) { switch_yield(100000); @@ -696,52 +696,52 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) { break; } } - + if (globals.event_filter) { switch_core_hash_destroy(&globals.event_filter); } - + switch_thread_rwlock_wrlock(globals.ei_nodes_lock); switch_thread_rwlock_unlock(globals.ei_nodes_lock); switch_thread_rwlock_destroy(globals.ei_nodes_lock); - + /* close the connection to epmd and the acceptor */ close_socketfd(&globals.epmdfd); close_socket(&globals.acceptor); - + /* remove all XML fetch agents */ unbind_fetch_agents(); - + /* Close the port we reserved for uPnP/Switch behind firewall, if necessary */ // if (globals.nat_map && switch_nat_get_type()) { // switch_nat_del_mapping(globals.port, SWITCH_NAT_TCP); // } - + /* clean up our allocated preferences */ switch_safe_free(globals.ip); switch_safe_free(globals.ei_cookie); switch_safe_free(globals.ei_nodename); switch_safe_free(globals.kazoo_var_prefix); - + return SWITCH_STATUS_SUCCESS; } SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) { switch_os_socket_t os_socket; - + switch_atomic_inc(&globals.threads); - + switch_os_sock_get(&os_socket, globals.acceptor); - + while (switch_test_flag(&globals, LFLAG_RUNNING)) { int nodefd; ErlConnect conn; - + /* zero out errno because ei_accept doesn't differentiate between a */ /* failed authentication or a socket failure, or a client version */ /* mismatch or a godzilla attack (and a godzilla attack is highly likely) */ errno = 0; - + /* wait here for an erlang node to connect, timming out to check if our module is still running every now-and-again */ if ((nodefd = ei_accept_tmo(&globals.ei_cnode, (int) os_socket, &conn, globals.connection_timeout)) == ERL_ERROR) { if (erl_errno == ETIMEDOUT) { @@ -754,19 +754,19 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) { } continue; } - + if (!switch_test_flag(&globals, LFLAG_RUNNING)) { break; } - + /* NEW ERLANG NODE CONNECTION! Hello friend! */ new_kazoo_node(nodefd, &conn); } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor shut down\n"); - + switch_atomic_dec(&globals.threads); - + return SWITCH_STATUS_TERM; } From 9dbe81b50ffb919058478d77adb47f9388238b52 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 10 May 2016 21:46:54 +0000 Subject: [PATCH 05/72] Cleanup inconsistent whitespace in debian/util.sh We use two space indentation in this file and no tabs as per the mode-line header. --- debian/util.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/debian/util.sh b/debian/util.sh index aa828e365c..bce15bd911 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -245,7 +245,7 @@ create_dsc () { } fmt_debug_hook () { - cat <<'EOF' + cat <<'EOF' #!/bin/bash export debian_chroot="cow" cd /tmp/buildd/*/debian/.. @@ -290,24 +290,24 @@ build_debs () { done shift $(($OPTIND-1)) if [ "$custom_sources_file" == "/etc/apt/sources.list" ]; then - # If you are using the system sources, then it is reasonable that you expect to use all of the supplementary repos too - cat /etc/apt/sources.list > /tmp/fs.sources.list - if [ "$(ls -A /etc/apt/sources.list.d)" ]; then - for X in /etc/apt/sources.list.d/*; do cat $X >> /tmp/fs.sources.list; done - fi - custom_sources_file="/tmp/fs.sources.list" - apt-key exportall > "/tmp/fs.asc" - custom_keyring="/tmp/fs.asc" + # If you are using the system sources, then it is reasonable that you expect to use all of the supplementary repos too + cat /etc/apt/sources.list > /tmp/fs.sources.list + if [ "$(ls -A /etc/apt/sources.list.d)" ]; then + for X in /etc/apt/sources.list.d/*; do cat $X >> /tmp/fs.sources.list; done + fi + custom_sources_file="/tmp/fs.sources.list" + apt-key exportall > "/tmp/fs.asc" + custom_keyring="/tmp/fs.asc" fi if [ "$custom_sources_file" == "" ]; then - # Caller has explicitly set the custom sources file to empty string. They must intend to not use additional mirrors. - use_custom_sources=false + # Caller has explicitly set the custom sources file to empty string. They must intend to not use additional mirrors. + use_custom_sources=false fi if [[ "$custom_source_file" == "/tmp/fs.sources.list" && ! -e "/tmp/fs.sources.list" ]]; then - echo "deb http://files.freeswitch.org/repo/deb/debian/ jessie main" >> "/tmp/fs.sources.list" + echo "deb http://files.freeswitch.org/repo/deb/debian/ jessie main" >> "/tmp/fs.sources.list" fi if [[ "$custom_keyring" == "/tmp/fs.asc" && ! -r "/tmp/fs.asc" ]]; then - cat << EOF > "/tmp/fs.asc" + cat << EOF > "/tmp/fs.asc" -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.12 (GNU/Linux) From 3fca86c81f6132426d24b05f91b01cf8456aa55e Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Tue, 10 May 2016 21:50:41 +0000 Subject: [PATCH 06/72] Remove superfluous semicolon Having this extra semicolon here confuses automatic indentation. --- debian/util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/util.sh b/debian/util.sh index bce15bd911..51e50c47f1 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -199,7 +199,7 @@ create_dsc () { m) modules_list="$OPTARG";; p) modules_add="$modules_add $OPTARG";; s) speed="$OPTARG";; - u) suite_postfix="$OPTARG"; suite_postfix_p=true; ;; + u) suite_postfix="$OPTARG"; suite_postfix_p=true;; z) zl="$OPTARG";; esac done From 6ae15b9fa1ae4f636e7bb4d1459671a6b1606f9e Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Tue, 10 May 2016 18:18:19 -0700 Subject: [PATCH 07/72] FS-8623: Fix libvpx Solaris Studio build --- libs/libvpx/build/make/configure.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libs/libvpx/build/make/configure.sh b/libs/libvpx/build/make/configure.sh index d888268dc8..c8a3291b74 100644 --- a/libs/libvpx/build/make/configure.sh +++ b/libs/libvpx/build/make/configure.sh @@ -317,10 +317,20 @@ EOF } check_cflags() { - log check_cflags "$@" - check_cc -Werror "$@" < Date: Wed, 11 May 2016 14:49:21 +0800 Subject: [PATCH 08/72] FS-9151 #resolve --- src/mod/applications/mod_av/avformat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 347ca8f732..7d0ca45815 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1459,6 +1459,8 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo if (context->video_st.st && (error = av_read_frame(context->fc, &pkt)) < 0) { if (error == AVERROR_EOF) { + if (!context->has_video) break; + eof = 1; /* just make sure*/ pkt.data = NULL; From 6cc31acf7e714de40ed349cf7064b1a16141ff3e Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 11 May 2016 18:02:58 -0500 Subject: [PATCH 09/72] FS-9155 [Centos Packaging] fix lang_es and lang_pt package to have the right language module --- freeswitch.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 376454749b..15a5d2d715 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -1543,7 +1543,7 @@ LOGGERS_MODULES="loggers/mod_console loggers/mod_graylog2 loggers/mod_logfile lo # Phrase engine language modules # ###################################################################################################################### -SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_fr say/mod_say_he say/mod_say_ru say/mod_say_sv" +SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_es say/mod_say_pt say/mod_say_fr say/mod_say_he say/mod_say_ru say/mod_say_sv" ###################################################################################################################### # @@ -2442,7 +2442,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/vm/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/dir/*.xml -%{MODINSTDIR}/mod_say_en.so* +%{MODINSTDIR}/mod_say_es.so* %files lang-pt %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt @@ -2453,7 +2453,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/vm/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/dir/*.xml -%{MODINSTDIR}/mod_say_en.so* +%{MODINSTDIR}/mod_say_pt.so* %files lang-sv %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/sv From 0a5145133b067dc47feb664c75361f2e6985d6af Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Thu, 12 May 2016 01:09:12 +0100 Subject: [PATCH 10/72] FS-9152 [avmd] #fix warnings on FreeBSD Use function __isnan to avoid __Generic type extension on FreeBSD. Clang 3.4.1 complains about -Wc++11-extensions even when it has them defined. --- src/mod/applications/mod_avmd/avmd_desa2.c | 5 ++++- src/mod/applications/mod_avmd/avmd_desa2_tweaked.c | 7 +++++-- src/mod/applications/mod_avmd/mod_avmd.c | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_avmd/avmd_desa2.c b/src/mod/applications/mod_avmd/avmd_desa2.c index abecf6ee64..b1d19eb8ae 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2.c +++ b/src/mod/applications/mod_avmd/avmd_desa2.c @@ -5,8 +5,11 @@ #ifdef WIN32 #include #define ISNAN(x) (!!(_isnan(x))) +#define ISINF(x) (isinf(x)) #else -#define ISNAN(x) (isnan(x)) +int __isnan(double); +#define ISNAN(x) (__isnan(x)) +#define ISINF(x) (__isinf(x)) #endif #include "avmd_buffer.h" #include "avmd_desa2.h" diff --git a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c index 0b75b9eed1..8eae1753f3 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c +++ b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c @@ -5,8 +5,11 @@ #ifdef WIN32 #include #define ISNAN(x) (!!(_isnan(x))) +#define ISINF(x) (isinf(x)) #else -#define ISNAN(x) (isnan(x)) +int __isnan(double); +#define ISNAN(x) (__isnan(x)) +#define ISINF(x) (__isinf(x)) #endif #include "avmd_buffer.h" #include "avmd_desa2_tweaked.h" @@ -48,7 +51,7 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i) we do simplified, modified for speed version : */ result = n/d; - if (isinf(result)) { + if (ISINF(result)) { if (n < 0.0) return -10.0; else diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 75c432ec61..de896e8fbb 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -38,8 +38,11 @@ #ifdef WIN32 #include #define ISNAN(x) (!!(_isnan(x))) +#define ISINF(x) (isinf(x)) #else -#define ISNAN(x) (isnan(x)) +int __isnan(double); +#define ISNAN(x) (__isnan(x)) +#define ISINF(x) (__isinf(x)) #endif @@ -1471,7 +1474,7 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) sample_to_skip_n = AVMD_SAMLPE_TO_SKIP_N; #endif } else { - if (isnan(omega)) { + if (ISNAN(omega)) { #ifdef AVMD_DEBUG switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD, SKIP NaN >>>\n"); From 1ea32d4009611c2eef16bedc19630fc86cdbe662 Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Thu, 5 May 2016 18:39:58 +0100 Subject: [PATCH 11/72] FS-9010 [avmd] Dynamic passing of parameters Add dynamic passing of parameters, initialize session to dynamically passed arguments or to default global config if dynamic init fails --- src/mod/applications/mod_avmd/mod_avmd.c | 238 +++++++++++++++++++++-- 1 file changed, 225 insertions(+), 13 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index de896e8fbb..8602ad1656 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -105,8 +105,11 @@ int __isnan(double); #define AVMD_SYNTAX " < start | stop | set [inbound|outbound|default] | load [inbound|outbound] | reload | show >" /*! Number of expected parameters in api call. */ -#define AVMD_PARAMS_MIN 1u -#define AVMD_PARAMS_MAX 2u +#define AVMD_PARAMS_API_MIN 1u +#define AVMD_PARAMS_API_MAX 2u +#define AVMD_PARAMS_APP_MAX 30u +#define AVMD_PARAMS_APP_START_MIN 0u +#define AVMD_PARAMS_APP_START_MAX 20u /* don't forget to update avmd_events_str table * if you modify this */ @@ -126,6 +129,12 @@ const char* avmd_events_str[] = { [AVMD_EVENT_BEEP] = "avmd::beep" #define AVMD_CHAR_BUF_LEN 20u #define AVMD_BUF_LINEAR_LEN 160u +enum avmd_app +{ + AVMD_APP_START_APP = 0, + AVMD_APP_STOP_APP = 1, + AVMD_APP_START_FUNCTION = 2 /* deprecated since version 1.6.8 */ +}; /* Prototypes */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown); @@ -225,9 +234,11 @@ avmd_reloadxml_event_handler(switch_event_t *event); static void avmd_show(switch_stream_handle_t *stream, switch_mutex_t *mutex); -/*! \brief The avmd session data initialization function. - * @param avmd_session A reference to a avmd session. - * @param fs_session A reference to a FreeSWITCH session. + +/*! \brief The avmd session data initialization function. + * @param avmd_session A reference to a avmd session. + * @param fs_session A reference to a FreeSWITCH session. + * @details Avmd globals mutex must be locked. */ static switch_status_t init_avmd_session_data(avmd_session_t *avmd_session, @@ -259,7 +270,7 @@ init_avmd_session_data(avmd_session_t *avmd_session, #ifdef AVMD_REQUIRE_CONTINUOUS_STREAK avmd_session->samples_streak = SAMPLES_CONSECUTIVE_STREAK; #endif - memset(&avmd_session->settings, 0, sizeof(struct avmd_settings)); + memcpy(&avmd_session->settings, &avmd_globals.settings, sizeof(struct avmd_settings)); switch_mutex_init(&avmd_session->mutex, SWITCH_MUTEX_DEFAULT, switch_core_session_get_pool(fs_session)); avmd_session->sample_count = 0; @@ -733,8 +744,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) if (avmd_load_xml_configuration(NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Couldn't load XML configuration\n"); - return SWITCH_STATUS_TERM; + "Couldn't load XML configuration! Loading default settings\n"); + avmd_set_xml_default_configuration(NULL); } if ((switch_event_bind(modname, SWITCH_EVENT_RELOADXML, NULL, @@ -817,6 +828,180 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) return SWITCH_STATUS_SUCCESS; } +void +avmd_config_dump(avmd_session_t *s) +{ + struct avmd_settings *settings; + + if (s == NULL) return; + settings = &s->settings; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, + "Avmd dynamic configuration: debug [%u], report_status [%u], fast_math [%u]," + " require_continuous_streak [%u], sample_n_continuous_streak [%u], " + "sample_n_to_skeep [%u], simplified_estimation [%u], " + "inbound_channel [%u], outbound_channel [%u]\n", + settings->debug, settings->report_status, settings->fast_math, + settings->require_continuous_streak, settings->sample_n_continuous_streak, + settings->sample_n_to_skeep, settings->simplified_estimation, + settings->inbound_channnel, settings->outbound_channnel); + return; +} + +static switch_status_t +avmd_parse_cmd_data_one_entry(char *candidate, struct avmd_settings *settings) +{ + char *candidate_parsed[3]; + int argc; + const char *key; + const char *val; + + if (settings == NULL) return SWITCH_STATUS_TERM; + if (candidate == NULL) return SWITCH_STATUS_NOOP; + + argc = switch_separate_string(candidate, '=', candidate_parsed, (sizeof(candidate_parsed) / sizeof(candidate_parsed[0]))); + if (argc > 2) { + /* currently we accept only option=value syntax */ + return SWITCH_STATUS_IGNORE; + } + + /* this may be option parameter if valid */ + key = candidate_parsed[0]; /* option name */ + if (zstr(key)) { + /* empty key */ + return SWITCH_STATUS_NOT_INITALIZED; + } + val = candidate_parsed[1]; /* value of the option: whole string starting at 1 past the '=' */ + if (zstr(val)) { + /* nothing after "=" found, empty value */ + return SWITCH_STATUS_MORE_DATA; + } + /* candidate string has "=" somewhere in the middle and some value, + * try to find what option it is by comparing at most given number of bytes */ + if (!strcmp(key, "debug")) { + settings->debug = switch_true(val); + } else if (!strcmp(key, "report_status")) { + settings->report_status = switch_true(val); + } else if (!strcmp(key, "fast_math")) { + settings->fast_math = switch_true(val); + } else if (!strcmp(key, "require_continuous_streak")) { + settings->require_continuous_streak = switch_true(val); + } else if (!strcmp(key, "sample_n_continuous_streak")) { + if(avmd_parse_u16_user_input(val, &settings->sample_n_continuous_streak, 0, UINT16_MAX) == -1) { + return SWITCH_STATUS_FALSE; + } + } else if (!strcmp(key, "sample_n_to_skeep")) { + if(avmd_parse_u16_user_input(val, &settings->sample_n_to_skeep, 0, UINT16_MAX) == -1) { + return SWITCH_STATUS_FALSE; + } + } else if (!strcmp(key, "simplified_estimation")) { + settings->simplified_estimation = switch_true(val); + } else if (!strcmp(key, "inbound_channel")) { + settings->inbound_channnel = switch_true(val); + } else if (!strcmp(key, "outbound_channel")) { + settings->outbound_channnel = switch_true(val); + } else { + return SWITCH_STATUS_NOTFOUND; + } + return SWITCH_STATUS_SUCCESS; +} + +/* RCU style: reads, copies and then updates only if everything is fine, + * if it returns SWITCH_STATUS_SUCCESS parsing went OK and avmd settings + * are updated accordingly to @cmd_data, if SWITCH_STATUS_FALSE then + * parsing error occurred and avmd session is being left untouched */ +static switch_status_t +avmd_parse_cmd_data(avmd_session_t *s, const char *cmd_data, enum avmd_app app) +{ + char *mydata; + struct avmd_settings settings; + int argc = 0, idx; + char *argv[AVMD_PARAMS_APP_MAX * 2] = { 0 }; + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (s == NULL) { + return SWITCH_STATUS_NOOP; + } + if (zstr(cmd_data)) { + return SWITCH_STATUS_SUCCESS; + } + + /* copy current settings first */ + memcpy(&settings, &s->settings, sizeof (struct avmd_settings)); + switch (app) + { + case AVMD_APP_START_APP: + /* avmd_start_app */ + + /* try to parse settings */ + mydata = switch_core_session_strdup(s->session, cmd_data); + argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))); + if (argc < AVMD_PARAMS_APP_START_MIN || argc > AVMD_PARAMS_APP_START_MAX) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Syntax Error, avmd_start APP takes [%u] to [%u] parameters\n", + AVMD_PARAMS_APP_START_MIN, AVMD_PARAMS_APP_START_MAX); + switch_goto_status(SWITCH_STATUS_MORE_DATA, fail); + } + /* iterate over params, check if they mean something to us, set */ + idx = 0; + while (idx < argc) { + status = avmd_parse_cmd_data_one_entry(argv[idx], &settings); + if (status != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Error parsing option [%d] [%s]\n", idx + 1, argv[idx]); /* idx + 1 to report option 0 as 1 for users convenience */ + switch (status) + { + case SWITCH_STATUS_TERM: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "NULL settings struct passed to parser\n"); + break; + case SWITCH_STATUS_NOOP: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "NULL settings string passed to parser\n"); + break; + case SWITCH_STATUS_IGNORE: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Syntax error. Currently we accept only option=value syntax\n"); + break; + case SWITCH_STATUS_NOT_INITALIZED: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Syntax error. No key specified\n"); + break; + case SWITCH_STATUS_MORE_DATA: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Syntax error. No value for the key? Currently we accept only option=value syntax\n"); + break; + case SWITCH_STATUS_FALSE: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Bad value for this option\n"); + break; + case SWITCH_STATUS_NOTFOUND: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "Option not found. Please check option name is correct\n"); + break; + default: + break; + } + status = SWITCH_STATUS_FALSE; + goto fail; + } + ++idx; + } + /* OK */ + goto end_copy; + default: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_ERROR, + "There is no app with index [%u] for avmd\n", app); + switch_goto_status(SWITCH_STATUS_NOTFOUND, fail); + } + +end_copy: + /* commit the change */ + memcpy(&s->settings, &settings, sizeof (struct avmd_settings)); + return SWITCH_STATUS_SUCCESS; +fail: + return status; +} + SWITCH_STANDARD_APP(avmd_start_app) { switch_media_bug_t *bug; @@ -895,7 +1080,7 @@ SWITCH_STANDARD_APP(avmd_start_app) goto end; } - status = init_avmd_session_data(avmd_session, session, NULL); + status = init_avmd_session_data(avmd_session, session, NULL); if (status != SWITCH_STATUS_SUCCESS) { switch (status) { case SWITCH_STATUS_MEMERR: @@ -918,11 +1103,38 @@ SWITCH_STANDARD_APP(avmd_start_app) SWITCH_LOG_ERROR, "Failed to init avmd session." " Unknown error\n"); break; - } goto end; } + /* dynamic configuation */ + status = avmd_parse_cmd_data(avmd_session, data, AVMD_APP_START_APP); + switch (status) { + case SWITCH_STATUS_SUCCESS: + break; + case SWITCH_STATUS_NOOP: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_ERROR, "Failed to set dynamic parameters for avmd session." + " Session is NULL! Default settings are loaded\n"); + goto end; + case SWITCH_STATUS_FALSE: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_ERROR, "Failed to set dynamic parameters for avmd session." + " Parsing error, please check the parameters passed to this APP." + " Default settings are loaded\n"); + goto end; + default: + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_ERROR, "Failed to set dynamic parameteres for avmd session." + " Unknown error. Default settings are loaded\n"); + goto end; + } + + if (avmd_session->settings.debug == 1) { + /* report dynamic parameters */ + avmd_config_dump(avmd_session); + } + /* Add a media bug that allows me to intercept the * reading leg of the audio stream */ status = switch_core_media_bug_add( @@ -1093,7 +1305,7 @@ SWITCH_STANDARD_API(avmd_api_main) int argc; const char *uuid, *uuid_dup; const char *command; - char *dupped = NULL, *argv[AVMD_PARAMS_MAX + 1] = { 0 }; + char *dupped = NULL, *argv[AVMD_PARAMS_API_MAX + 1] = { 0 }; switch_core_media_flag_t flags = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_core_session_t *fs_session = NULL; @@ -1115,9 +1327,9 @@ SWITCH_STANDARD_API(avmd_api_main) /* If we don't have the expected number of parameters * display usage */ - if (argc < AVMD_PARAMS_MIN) { + if (argc < AVMD_PARAMS_API_MIN) { stream->write_function(stream, "-ERR, avmd takes [%u] min and [%u] max parameters!\n" - "-USAGE: %s\n\n", AVMD_PARAMS_MIN, AVMD_PARAMS_MAX, AVMD_SYNTAX); + "-USAGE: %s\n\n", AVMD_PARAMS_API_MIN, AVMD_PARAMS_API_MAX, AVMD_SYNTAX); goto end; } From 98cb363f187a8ba5ad21b5a722a4f6dcaac21243 Mon Sep 17 00:00:00 2001 From: Emmanuel Schmidbauer Date: Thu, 12 May 2016 14:14:10 -0400 Subject: [PATCH 12/72] FS-9148: add new voicemail.conf.xml param `send-full-vm-header` - if enabled, `Voice-Message` header sends urgent new and urgent saved --- .../applications/mod_voicemail/mod_voicemail.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 43917d88e3..bebcfde9ca 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -28,7 +28,7 @@ * John Wehle (john@feith.com) * Raymond Chandler * Kristin King - * Emmanuel Schmidbauer + * Emmanuel Schmidbauer * * mod_voicemail.c -- Voicemail Module * @@ -689,6 +689,7 @@ vm_profile_t *profile_set_config(vm_profile_t *profile) SWITCH_CONFIG_SET_ITEM(profile->config[i++], "allow-empty-password-auth", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->allow_empty_password_auth, SWITCH_TRUE, NULL, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "auto-playback-recordings", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->auto_playback_recordings, SWITCH_FALSE, NULL, NULL, NULL); + SWITCH_CONFIG_SET_ITEM(profile->config[i++], "send-full-vm-header", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->send_full_vm_header, SWITCH_FALSE, NULL, NULL, NULL); switch_assert(i < VM_PROFILE_CONFIGITEM_COUNT); @@ -1935,11 +1936,13 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", yn); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Update-Reason", update_reason); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", id, domain_name); - /* - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, - total_new_urgent_messages, total_saved_urgent_messages); - */ - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); + + if (profile->send_full_vm_header) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, + total_new_urgent_messages, total_saved_urgent_messages); + } else { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); + } switch_event_fire(&event); From 8a4ad0da035d8a551eea743b05004ee030bf73e0 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 12 May 2016 15:05:56 -0400 Subject: [PATCH 13/72] Revert "FS-9148: add new voicemail.conf.xml param `send-full-vm-header`" This reverts commit 98cb363f187a8ba5ad21b5a722a4f6dcaac21243. This commit does not compile --- .../applications/mod_voicemail/mod_voicemail.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index bebcfde9ca..43917d88e3 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -28,7 +28,7 @@ * John Wehle (john@feith.com) * Raymond Chandler * Kristin King - * Emmanuel Schmidbauer + * Emmanuel Schmidbauer * * mod_voicemail.c -- Voicemail Module * @@ -689,7 +689,6 @@ vm_profile_t *profile_set_config(vm_profile_t *profile) SWITCH_CONFIG_SET_ITEM(profile->config[i++], "allow-empty-password-auth", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->allow_empty_password_auth, SWITCH_TRUE, NULL, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "auto-playback-recordings", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->auto_playback_recordings, SWITCH_FALSE, NULL, NULL, NULL); - SWITCH_CONFIG_SET_ITEM(profile->config[i++], "send-full-vm-header", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->send_full_vm_header, SWITCH_FALSE, NULL, NULL, NULL); switch_assert(i < VM_PROFILE_CONFIGITEM_COUNT); @@ -1936,13 +1935,11 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", yn); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Update-Reason", update_reason); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", id, domain_name); - - if (profile->send_full_vm_header) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, - total_new_urgent_messages, total_saved_urgent_messages); - } else { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); - } + /* + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, + total_new_urgent_messages, total_saved_urgent_messages); + */ + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); switch_event_fire(&event); From df4490a7dfcaa6a087ea436979292b38dc7a5072 Mon Sep 17 00:00:00 2001 From: Emmanuel Schmidbauer Date: Thu, 12 May 2016 15:44:39 -0400 Subject: [PATCH 14/72] FS-9148: add new voicemail.conf.xml param `send-full-vm-header` --- .../applications/mod_voicemail/mod_voicemail.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 43917d88e3..f2e2b3a1d7 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -28,7 +28,7 @@ * John Wehle (john@feith.com) * Raymond Chandler * Kristin King - * Emmanuel Schmidbauer + * Emmanuel Schmidbauer * * mod_voicemail.c -- Voicemail Module * @@ -181,6 +181,7 @@ struct vm_profile { switch_bool_t auto_playback_recordings; switch_bool_t db_password_override; switch_bool_t allow_empty_password_auth; + switch_bool_t send_full_vm_header; switch_thread_rwlock_t *rwlock; switch_memory_pool_t *pool; uint32_t flags; @@ -689,6 +690,7 @@ vm_profile_t *profile_set_config(vm_profile_t *profile) SWITCH_CONFIG_SET_ITEM(profile->config[i++], "allow-empty-password-auth", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->allow_empty_password_auth, SWITCH_TRUE, NULL, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "auto-playback-recordings", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->auto_playback_recordings, SWITCH_FALSE, NULL, NULL, NULL); + SWITCH_CONFIG_SET_ITEM(profile->config[i++], "send-full-vm-header", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->send_full_vm_header, SWITCH_FALSE, NULL, NULL, NULL); switch_assert(i < VM_PROFILE_CONFIGITEM_COUNT); @@ -1935,11 +1937,13 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", yn); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Update-Reason", update_reason); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", id, domain_name); - /* - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, - total_new_urgent_messages, total_saved_urgent_messages); - */ - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); + + if (profile->send_full_vm_header) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, + total_new_urgent_messages, total_saved_urgent_messages); + } else { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); + } switch_event_fire(&event); From 040b83a7af498c0a3ab1781a9836a7b43f033d62 Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Thu, 12 May 2016 18:34:23 -0300 Subject: [PATCH 15/72] FS-9157 [verto] Added possibility to use dedicated audio/video tags for each dialog --- html5/verto/js/src/jquery.verto.js | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/html5/verto/js/src/jquery.verto.js b/html5/verto/js/src/jquery.verto.js index e4643c1f57..68cc6d6d80 100644 --- a/html5/verto/js/src/jquery.verto.js +++ b/html5/verto/js/src/jquery.verto.js @@ -132,8 +132,13 @@ } }); + var tag = verto.options.tag; + if (typeof(tag) === "function") { + tag = tag(); + } + if (verto.options.ringFile && verto.options.tag) { - verto.ringer = $("#" + verto.options.tag); + verto.ringer = $("#" + tag); } verto.rpcClient.call('login', {}); @@ -1885,6 +1890,11 @@ $.verto.dialog = function(direction, verto, params) { var dialog = this; + var tag = verto.options.tag; + if (typeof(tag) === "function") { + tag = tag(); + } + dialog.params = $.extend({ useVideo: verto.options.useVideo, useStereo: verto.options.useStereo, @@ -1892,7 +1902,7 @@ useCamera: verto.options.deviceParams.useCamera, useMic: verto.options.deviceParams.useMic, useSpeak: verto.options.deviceParams.useSpeak, - tag: verto.options.tag, + tag: tag, localTag: verto.options.localTag, login: verto.options.login, videoParams: verto.options.videoParams @@ -2185,6 +2195,11 @@ dialog.setState($.verto.enum.state.destroy); break; case $.verto.enum.state.destroy: + + if (typeof(dialog.verto.options.tag) === "function") { + $('#' + dialog.params.tag).remove(); + } + delete dialog.verto.dialogs[dialog.callID]; if (dialog.params.screenShare) { dialog.rtc.stopPeer(); From 007458931125bc4b5bfee362e37123e330266776 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 12 May 2016 17:18:13 -0500 Subject: [PATCH 16/72] FS-9157 update jsmin --- html5/verto/demo/js/verto-min.js | 109 +++++++++++++++---------- html5/verto/video_demo/js/verto-min.js | 9 +- 2 files changed, 72 insertions(+), 46 deletions(-) diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index 2ea234eb45..dbe0017137 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -6,12 +6,13 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\ function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i=resList.length){var res={'validRes':$.FSRTC.validRes,'bestResSupported':$.FSRTC.bestResSupported()};localStorage.setItem("res_"+cam,$.toJSON(res));if(func)return func(res);return;} var video={mandatory:{},optional:[]} if(cam){video.optional=[{sourceId:cam}];} -w=resList[resI][0];h=resList[resI][1];resI++;video.mandatory={"minWidth":w,"minHeight":h,"maxWidth":w,"maxHeight":h};if(window.moz){video=video.mandatory;if(!video.width)video.width=video.minWidth;if(!video.height)video.height=video.minHeight;if(!video.frameRate)video.frameRate=video.minFrameRate;} -getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.stop();console.info(w+"x"+h+" supported.");$.FSRTC.validRes.push([w,h]);checkRes(cam,func);},onerror:function(e){console.error(w+"x"+h+" not supported.");checkRes(cam,func);}});} +w=resList[resI][0];h=resList[resI][1];resI++;video.mandatory={"minWidth":w,"minHeight":h,"maxWidth":w,"maxHeight":h};getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info(w+"x"+h+" supported.");$.FSRTC.validRes.push([w,h]);checkRes(cam,func);},onerror:function(e){console.error(w+"x"+h+" not supported.");checkRes(cam,func);}});} $.FSRTC.getValidRes=function(cam,func){var used=[];var cached=localStorage.getItem("res_"+cam);if(cached){var cache=$.parseJSON(cached);if(cache){$.FSRTC.validRes=cache.validRes;console.log("CACHED RES FOR CAM "+cam,cache);}else{console.error("INVALID CACHE");} return func?func(cache):null;} $.FSRTC.validRes=[];resI=0;checkRes(cam,func);} -$.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.stop();console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true)}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);} -console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};} +$.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true);}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);} +console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.speedTest=function(bytes,cb){var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this.speedCB=cb;this.speedBytes=bytes;socket.send("#SPU "+bytes);var loops=bytes/1024;var rem=bytes%1024;var i;var data=new Array(1024).join(".");for(i=0;i-1){var tmp=$.parseJSON(data[4]);data[4]=tmp.oldStatus;data[5]=null;} +return data;} +function genArray(obj){var data=obj.asArray();for(var i in data){data[i]=genRow(data[i]);} +return data;} +la.onChange=function(obj,args){var index=0;var iserr=0;if(!dt){if(!config.aoColumns){if(args.action!="init"){return;} config.aoColumns=[];for(var i in args.data){config.aoColumns.push({"sTitle":args.data[i]});}} dt=jq.dataTable(config);} if(dt&&(args.action=="del"||args.action=="modify")){index=args.index;if(index===undefined&&args.key){index=la.indexOf(args.key);} if(index===undefined){console.error("INVALID PACKET Missing INDEX\n",args);return;}} if(config.onChange){config.onChange(obj,args);} try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data");return;} -dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} -if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);} +dt.fnClearTable();dt.fnAddData(genArray(obj));dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} +if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(genArray(obj));}else{dt.fnAddData(genRow(args.data));} dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;} -dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} +dt.fnUpdate(genRow(args.data),index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(genArray(obj));break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.conf=function(verto,params){var conf=this;conf.params=$.extend({dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);conf.verto=verto;conf.serno=CONFMAN_SERNO++;createMainModeratorMethods();verto.subscribe(conf.params.laData.modChannel,{handler:function(v,e){if(conf.params.onBroadcast){conf.params.onBroadcast(verto,conf,e.data);}}});verto.subscribe(conf.params.laData.chatChannel,{handler:function(v,e){if(typeof(conf.params.chatCallback)==="function"){conf.params.chatCallback(v,e);}}});};$.verto.conf.prototype.modCommand=function(cmd,id,value){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.conf.prototype.destroy=function(){var conf=this;conf.destroyed=true;conf.params.onBroadcast(conf.verto,conf,'destroy');if(conf.params.laData.modChannel){conf.verto.unsubscribe(conf.params.laData.modChannel);} if(conf.params.laData.chatChannel){conf.verto.unsubscribe(conf.params.laData.chatChannel);}};function createMainModeratorMethods(){$.verto.conf.prototype.listVideoLayouts=function(){this.modCommand("list-videoLayouts",null,null);};$.verto.conf.prototype.play=function(file){this.modCommand("play",null,file);};$.verto.conf.prototype.stop=function(){this.modCommand("stop",null,"all");};$.verto.conf.prototype.record=function(file){this.modCommand("recording",null,["start",file]);};$.verto.conf.prototype.stopRecord=function(){this.modCommand("recording",null,["stop","all"]);};$.verto.conf.prototype.snapshot=function(file){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("vid-write-png",null,file);};$.verto.conf.prototype.setVideoLayout=function(layout){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("vid-layout",null,layout);};$.verto.conf.prototype.kick=function(memberID){this.modCommand("kick",parseInt(memberID));};$.verto.conf.prototype.muteMic=function(memberID){this.modCommand("tmute",parseInt(memberID));};$.verto.conf.prototype.muteVideo=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} +this.modCommand("vid-write-png",null,file);};$.verto.conf.prototype.setVideoLayout=function(layout,canvasID){if(!this.params.hasVid){throw'Conference has no video';} +if(canvasID){this.modCommand("vid-layout",null,[layout,canvasID]);}else{this.modCommand("vid-layout",null,layout);}};$.verto.conf.prototype.kick=function(memberID){this.modCommand("kick",parseInt(memberID));};$.verto.conf.prototype.muteMic=function(memberID){this.modCommand("tmute",parseInt(memberID));};$.verto.conf.prototype.muteVideo=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} this.modCommand("tvmute",parseInt(memberID));};$.verto.conf.prototype.presenter=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} this.modCommand("vid-res-id",parseInt(memberID),"presenter");};$.verto.conf.prototype.videoFloor=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} this.modCommand("vid-floor",parseInt(memberID),"force");};$.verto.conf.prototype.banner=function(memberID,text){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("vid-banner",parseInt(memberID),escape(text));};$.verto.conf.prototype.volumeDown=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("volume_in",parseInt(memberID),"down");};$.verto.conf.prototype.volumeUp=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("volume_in",parseInt(memberID),"up");};$.verto.conf.prototype.transfer=function(memberID,exten){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("transfer",parseInt(memberID),exten);};$.verto.conf.prototype.sendChat=function(message,type){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};} +this.modCommand("vid-banner",parseInt(memberID),escape(text));};$.verto.conf.prototype.volumeDown=function(memberID){this.modCommand("volume_out",parseInt(memberID),"down");};$.verto.conf.prototype.volumeUp=function(memberID){this.modCommand("volume_out",parseInt(memberID),"up");};$.verto.conf.prototype.gainDown=function(memberID){this.modCommand("volume_in",parseInt(memberID),"down");};$.verto.conf.prototype.gainUp=function(memberID){this.modCommand("volume_in",parseInt(memberID),"up");};$.verto.conf.prototype.transfer=function(memberID,exten){this.modCommand("transfer",parseInt(memberID),exten);};$.verto.conf.prototype.sendChat=function(message,type){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};} $.verto.modfuncs={};$.verto.confMan=function(verto,params){var confMan=this;confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;confMan.canvasCount=confMan.params.laData.canvasCount;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var snapshot_id="snapshot_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="

"+""+""+""+""+ -(confMan.params.hasVid?"":"")+"

";jq.html(html);$.verto.modfuncs.change_video_layout=function(id,canvas_id){var val=$("#"+id+" option:selected").text();if(val!=="none"){confMan.modCommand("vid-layout",null,[val,canvas_id]);}};if(confMan.params.hasVid){for(var j=0;j
"+"Video Layout Canvas "+(j+1)+" "+"

";jq.append(vlhtml);} +(confMan.params.hasVid?"":"")+"

";jq.html(html);$.verto.modfuncs.change_video_layout=function(id,canvas_id){var val=$("#"+id+" option:selected").text();if(val!=="none"){confMan.modCommand("vid-layout",null,[val,canvas_id]);}};if(confMan.params.hasVid){for(var j=0;j
"+"Video Layout Canvas "+(j+1)+" "+"

";jq.append(vlhtml);} $("#"+snapshot_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("vid-write-png",null,file);}});} $("#"+play_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("play",null,file);}});$("#"+stop_id).click(function(){confMan.modCommand("stop",null,"all");});$("#"+recording_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("recording",null,["start",file]);}});$("#"+rec_stop_id).click(function(){confMan.modCommand("recording",null,["stop","all"]);});} -function genControls(jq,rowid){var x=parseInt(rowid);var kick_id="kick_"+x;var canvas_in_next_id="canvas_in_next_"+x;var canvas_in_prev_id="canvas_in_prev_"+x;var canvas_out_next_id="canvas_out_next_"+x;var canvas_out_prev_id="canvas_out_prev_"+x;var canvas_in_set_id="canvas_in_set_"+x;var canvas_out_set_id="canvas_out_set_"+x;var layer_set_id="layer_set_"+x;var layer_next_id="layer_next_"+x;var layer_prev_id="layer_prev_"+x;var tmute_id="tmute_"+x;var tvmute_id="tvmute_"+x;var vbanner_id="vbanner_"+x;var tvpresenter_id="tvpresenter_"+x;var tvfloor_id="tvfloor_"+x;var box_id="box_"+x;var volup_id="volume_in_up"+x;var voldn_id="volume_in_dn"+x;var transfer_id="transfer"+x;var html="
";html+="General Controls
";html+=""+""+""+""+"";if(confMan.params.hasVid){html+="

Video Controls
";html+=""+""+""+"";if(confMan.canvasCount>1){html+="

Canvas Controls
"+""+""+""+"
"+""+""+"";} +function genControls(jq,rowid){var x=parseInt(rowid);var kick_id="kick_"+x;var canvas_in_next_id="canvas_in_next_"+x;var canvas_in_prev_id="canvas_in_prev_"+x;var canvas_out_next_id="canvas_out_next_"+x;var canvas_out_prev_id="canvas_out_prev_"+x;var canvas_in_set_id="canvas_in_set_"+x;var canvas_out_set_id="canvas_out_set_"+x;var layer_set_id="layer_set_"+x;var layer_next_id="layer_next_"+x;var layer_prev_id="layer_prev_"+x;var tmute_id="tmute_"+x;var tvmute_id="tvmute_"+x;var vbanner_id="vbanner_"+x;var tvpresenter_id="tvpresenter_"+x;var tvfloor_id="tvfloor_"+x;var box_id="box_"+x;var gainup_id="gain_in_up"+x;var gaindn_id="gain_in_dn"+x;var volup_id="vol_in_up"+x;var voldn_id="vol_in_dn"+x;var transfer_id="transfer"+x;var html="
";html+="General Controls
";html+=""+""+""+""+""+""+"";if(confMan.params.hasVid){html+="

Video Controls
";html+=""+""+""+"";if(confMan.canvasCount>1){html+="

Canvas Controls
"+""+""+""+"
"+""+""+"";} html+="
"+""+""+""+"
";} jq.html(html);if(!jq.data("mouse")){$("#"+box_id).hide();} jq.mouseover(function(e){jq.data({"mouse":true});$("#"+box_id).show();});jq.mouseout(function(e){jq.data({"mouse":false});$("#"+box_id).hide();});$("#"+transfer_id).click(function(){var xten=prompt("Enter Extension");if(xten){confMan.modCommand("transfer",x,xten);}});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+layer_set_id).click(function(){var cid=prompt("Please enter layer ID","");if(cid){confMan.modCommand("vid-layer",x,cid);}});$("#"+layer_next_id).click(function(){confMan.modCommand("vid-layer",x,"next");});$("#"+layer_prev_id).click(function(){confMan.modCommand("vid-layer",x,"prev");});$("#"+canvas_in_set_id).click(function(){var cid=prompt("Please enter canvas ID","");if(cid){confMan.modCommand("vid-canvas",x,cid);}});$("#"+canvas_out_set_id).click(function(){var cid=prompt("Please enter canvas ID","");if(cid){confMan.modCommand("vid-watching-canvas",x,cid);}});$("#"+canvas_in_next_id).click(function(){confMan.modCommand("vid-canvas",x,"next");});$("#"+canvas_in_prev_id).click(function(){confMan.modCommand("vid-canvas",x,"prev");});$("#"+canvas_out_next_id).click(function(){confMan.modCommand("vid-watching-canvas",x,"next");});$("#"+canvas_out_prev_id).click(function(){confMan.modCommand("vid-watching-canvas",x,"prev");});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});if(confMan.params.hasVid){$("#"+tvmute_id).click(function(){confMan.modCommand("tvmute",x);});$("#"+tvpresenter_id).click(function(){confMan.modCommand("vid-res-id",x,"presenter");});$("#"+tvfloor_id).click(function(){confMan.modCommand("vid-floor",x,"force");});$("#"+vbanner_id).click(function(){var text=prompt("Please enter text","");if(text){confMan.modCommand("vid-banner",x,escape(text));}});} -$("#"+volup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_in",x,"down");});return html;} +$("#"+gainup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+gaindn_id).click(function(){confMan.modCommand("volume_in",x,"down");});$("#"+volup_id).click(function(){confMan.modCommand("volume_out",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_out",x,"down");});return html;} var atitle="";var awidth=0;verto.subscribe(confMan.params.laData.chatChannel,{handler:function(v,e){if(typeof(confMan.params.chatCallback)==="function"){confMan.params.chatCallback(v,e);}}});if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=600;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready

");}else{$(confMan.params.mainModID).html("");} verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);} -if(e.data["conf-command"]==="list-videoLayouts"){for(var j=0;jb)?1:-1));});for(var i in options){$(vlselect_id).append(new Option(options[i],options[i]));x++;}} if(x){$(vlselect_id).selectmenu('refresh',true);}else{$(vlayout_id).hide();}}}else{if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"

");if(confMan.lastTimeout){clearTimeout(confMan.lastTimeout);confMan.lastTimeout=0;} confMan.lastTimeout=setTimeout(function(){$(confMan.params.displayID).html(confMan.destroyed?"":"Moderator Controls Ready

");},4000);}}}});if(confMan.params.hasVid){confMan.modCommand("list-videoLayouts",null,null);}} var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};} confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID","sWidth":"50"},{"sTitle":"Number","sWidth":"250"},{"sTitle":"Name","sWidth":"250"},{"sTitle":"Codec","sWidth":"100"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"200px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1400,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.sendChat=function(message,type){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} if(confMan.params.laData.chatChannel){confMan.verto.unsubscribe(confMan.params.laData.chatChannel);} if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);} -if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:verto.options.deviceParams.useCamera,useMic:verto.options.deviceParams.useMic,useSpeak:verto.options.deviceParams.useSpeak,tag:verto.options.tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=dialog.params.useCamera;dialog.useMic=dialog.params.useMic;dialog.useSpeak=dialog.params.useSpeak;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} +if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;var tag=verto.options.tag;if(typeof(tag)==="function"){tag=tag();} +dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:verto.options.deviceParams.useCamera,useMic:verto.options.deviceParams.useMic,useSpeak:verto.options.deviceParams.useSpeak,tag:tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=dialog.params.useCamera;dialog.useMic=dialog.params.useMic;dialog.useSpeak=dialog.params.useSpeak;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}} if(dialog.params.localTag){dialog.localVideo=document.getElementById(dialog.params.localTag);} dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;} @@ -238,18 +254,24 @@ if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="No if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";} RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;} RTCcallbacks.onICESDP=function(rtc){console.log("RECV "+rtc.type+" SDP",rtc.mediaData.SDP);if(dialog.state==$.verto.enum.state.requesting||dialog.state==$.verto.enum.state.answering||dialog.state==$.verto.enum.state.active){location.reload();return;} -if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;} +if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.screenShare?null:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;} obj.dialogParams[i]=dialog.params[i];} dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;} return false;} +function find_name(id){for(var i in $.verto.audioOutDevices){var source=$.verto.audioOutDevices[i];if(source.id===id){return(source.label);}} +return id;} +$.verto.dialog.prototype.setAudioPlaybackDevice=function(sinkId,callback,arg){var dialog=this;var element=dialog.audioStream;if(typeof element.sinkId!=='undefined'){var devname=find_name(sinkId);console.info("Dialog: "+dialog.callID+" Setting speaker:",element,devname);element.setSinkId(sinkId).then(function(){console.log("Dialog: "+dialog.callID+' Success, audio output device attached: '+sinkId);if(callback){callback(true,devname,arg);}}).catch(function(error){var errorMessage=error;if(error.name==='SecurityError'){errorMessage="Dialog: "+dialog.callID+' You need to use HTTPS for selecting audio output '+'device: '+error;} +if(callback){callback(false,null,arg);} +console.error(errorMessage);});}else{console.warn("Dialog: "+dialog.callID+' Browser does not support output device selection.');if(callback){callback(false,null,arg);}}} $.verto.dialog.prototype.setState=function(state){var dialog=this;if(dialog.state==$.verto.enum.state.ringing){dialog.stopRinging();} if(dialog.state==state||!checkStateChange(dialog.state,state)){console.error("Dialog "+dialog.callID+": INVALID state change from "+dialog.state.name+" to "+state.name);dialog.hangup();return false;} console.log("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;} if(!dialog.cause){dialog.cause="NORMAL CLEARING";} if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);} -switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"){var videoElement=dialog.audioStream;setTimeout(function(){console.info("Setting speaker:",videoElement,speaker);attachSinkId(videoElement,speaker);},500);} +switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"&&speaker!=="none"){setTimeout(function(){dialog.setAudioPlaybackDevice(speaker);},500);} break;case $.verto.enum.state.trying:setTimeout(function(){if(dialog.state==$.verto.enum.state.trying){dialog.setState($.verto.enum.state.hangup);}},30000);break;case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});} -dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(!dialog.params.screenShare){dialog.rtc.stop();} +dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:if(typeof(dialog.verto.options.tag)==="function"){$('#'+dialog.params.tag).remove();} +delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();} break;} return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} @@ -258,7 +280,7 @@ if(success){} break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;} if(params.cause){dialog.cause=params.cause;}} if(dialog.state.val>=$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;} -dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;} +dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;} if(!msg.body){console.error("Missing Body");err++;} if(err){return false;} dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(!params){params={};} @@ -273,7 +295,8 @@ dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.h dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1,hangup:1},requesting:{trying:1,hangup:1,active:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$.verto.unloadJobs=[];$(window).bind('beforeunload',function(){for(var f in $.verto.unloadJobs){$.verto.unloadJobs[f]();} for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.purge();verto.logout();}} return $.verto.warnOnUnload;});$.verto.videoDevices=[];$.verto.audioInDevices=[];$.verto.audioOutDevices=[];var checkDevices=function(runtime){console.info("enumerating devices");var aud_in=[],aud_out=[],vid=[];if((!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices)&&MediaStreamTrack.getSources){MediaStreamTrack.getSources(function(media_sources){for(var i=0;i$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});} -dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();} +dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:if(typeof(dialog.verto.options.tag)==="function"){$('#'+dialog.params.tag).remove();} +delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();} break;} return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} From 76b634139792f022f5398816363e3306288a41f1 Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Fri, 13 May 2016 16:17:03 -0300 Subject: [PATCH 17/72] Incrementing Verto version in package.json --- html5/verto/js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html5/verto/js/package.json b/html5/verto/js/package.json index 1165968599..9da32bcf10 100644 --- a/html5/verto/js/package.json +++ b/html5/verto/js/package.json @@ -1,6 +1,6 @@ { "name": "verto", - "version": "0.0.1", + "version": "0.0.2", "devDependencies": { "grunt": "~0.4.5", "grunt-contrib-jshint": "~0.10.0", From 8b6f40f9678ddde68f7018c8d2d3e86592536da6 Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Fri, 13 May 2016 22:21:04 -0300 Subject: [PATCH 18/72] FS-8584 - [mod_callcenter] Requesting agents and tiers when reloading queue Before this callcenter_config queue reload [queuename] only reloads the queue parameters and now it'll include a CC-Queue header with the queuename when using mod_xml_curl and request a new config for updating agents and tiers related to the queue. If you are using mod_xml_curl please make sure to return the raw xml config file with all the settings, queues, agents and tiers tags when we request the config without a CC-Queue specified. If this header is present you can build the xml with items only related to the queue requested. --- .../mod_callcenter/mod_callcenter.c | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 3750b441f4..d626eb2ed0 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -49,6 +49,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load); */ SWITCH_MODULE_DEFINITION(mod_callcenter, mod_callcenter_load, mod_callcenter_shutdown, NULL); +static switch_status_t load_agent(const char *agent_name, switch_event_t *params); +static switch_status_t load_tiers(switch_bool_t load_all, const char *queue_name, const char *agent_name, switch_event_t *params); static const char *global_cf = "callcenter.conf"; struct cc_status_table { @@ -674,10 +676,10 @@ end: return ret; } -static cc_queue_t *load_queue(const char *queue_name) +static cc_queue_t *load_queue(const char *queue_name, switch_bool_t request_agents, switch_bool_t request_tiers) { cc_queue_t *queue = NULL; - switch_xml_t x_queues, x_queue, cfg, xml; + switch_xml_t x_queues, x_queue, cfg, xml, x_agents, x_agent; switch_event_t *event = NULL; switch_event_t *params = NULL; @@ -735,6 +737,20 @@ static cc_queue_t *load_queue(const char *queue_name) } + /* Importing from XML config Agents */ + if (queue && request_agents && (x_agents = switch_xml_child(cfg, "agents"))) { + for (x_agent = switch_xml_child(x_agents, "agent"); x_agent; x_agent = x_agent->next) { + const char *agent = switch_xml_attr(x_agent, "name"); + if (agent) { + load_agent(agent, params); + } + } + } + /* Importing from XML config Agent Tiers */ + if (queue && request_tiers) { + load_tiers(SWITCH_TRUE, NULL, NULL, params); + } + end: if (xml) { @@ -755,7 +771,7 @@ static cc_queue_t *get_queue(const char *queue_name) switch_mutex_lock(globals.mutex); if (!(queue = switch_core_hash_find(globals.queue_hash, queue_name))) { - queue = load_queue(queue_name); + queue = load_queue(queue_name, SWITCH_FALSE, SWITCH_FALSE); } if (queue) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "[%s] rwlock\n", queue->name); @@ -1255,11 +1271,10 @@ cc_status_t cc_tier_del(const char *queue_name, const char *agent) return result; } -static switch_status_t load_agent(const char *agent_name) +static switch_status_t load_agent(const char *agent_name, switch_event_t *params) { switch_xml_t x_agents, x_agent, cfg, xml; - - if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, params))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); return SWITCH_STATUS_FALSE; } @@ -1348,12 +1363,12 @@ static switch_status_t load_tier(const char *queue, const char *agent, const cha return SWITCH_STATUS_SUCCESS; } -static switch_status_t load_tiers(switch_bool_t load_all, const char *queue_name, const char *agent_name) +static switch_status_t load_tiers(switch_bool_t load_all, const char *queue_name, const char *agent_name, switch_event_t *params) { switch_xml_t x_tiers, x_tier, cfg, xml; switch_status_t result = SWITCH_STATUS_FALSE; - if (!(xml = switch_xml_open_cfg(global_cf, &cfg, NULL))) { + if (!(xml = switch_xml_open_cfg(global_cf, &cfg, params))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", global_cf); return SWITCH_STATUS_FALSE; } @@ -1453,7 +1468,7 @@ static switch_status_t load_config(void) /* Loading queue into memory struct */ if ((x_queues = switch_xml_child(cfg, "queues"))) { for (x_queue = switch_xml_child(x_queues, "queue"); x_queue; x_queue = x_queue->next) { - load_queue(switch_xml_attr_soft(x_queue, "name")); + load_queue(switch_xml_attr_soft(x_queue, "name"), SWITCH_FALSE, SWITCH_FALSE); } } @@ -1462,13 +1477,13 @@ static switch_status_t load_config(void) for (x_agent = switch_xml_child(x_agents, "agent"); x_agent; x_agent = x_agent->next) { const char *agent = switch_xml_attr(x_agent, "name"); if (agent) { - load_agent(agent); + load_agent(agent, NULL); } } } /* Importing from XML config Agent Tiers */ - load_tiers(SWITCH_TRUE, NULL, NULL); + load_tiers(SWITCH_TRUE, NULL, NULL, NULL); end: switch_mutex_unlock(globals.mutex); @@ -3158,7 +3173,7 @@ SWITCH_STANDARD_API(cc_config_api_function) goto done; } else { const char *agent = argv[0 + initial_argc]; - switch (load_agent(agent)) { + switch (load_agent(agent, NULL)) { case SWITCH_STATUS_SUCCESS: stream->write_function(stream, "%s", "+OK\n"); break; @@ -3351,7 +3366,7 @@ SWITCH_STANDARD_API(cc_config_api_function) if (!strcasecmp(queue, "all")) { load_all = SWITCH_TRUE; } - switch (load_tiers(load_all, queue, agent)) { + switch (load_tiers(load_all, queue, agent, NULL)) { case SWITCH_STATUS_SUCCESS: stream->write_function(stream, "%s", "+OK\n"); break; @@ -3379,8 +3394,7 @@ SWITCH_STANDARD_API(cc_config_api_function) } else { const char *queue_name = argv[0 + initial_argc]; cc_queue_t *queue = NULL; - if ((queue = get_queue(queue_name))) { - queue_rwunlock(queue); + if ((queue = load_queue(queue_name, SWITCH_TRUE, SWITCH_TRUE))) { stream->write_function(stream, "%s", "+OK\n"); } else { stream->write_function(stream, "%s", "-ERR Invalid Queue not found!\n"); @@ -3406,8 +3420,7 @@ SWITCH_STANDARD_API(cc_config_api_function) const char *queue_name = argv[0 + initial_argc]; cc_queue_t *queue = NULL; destroy_queue(queue_name); - if ((queue = get_queue(queue_name))) { - queue_rwunlock(queue); + if ((queue = load_queue(queue_name, SWITCH_TRUE, SWITCH_TRUE))) { stream->write_function(stream, "%s", "+OK\n"); } else { stream->write_function(stream, "%s", "-ERR Invalid Queue not found!\n"); From 7f24fc7ab54af49882bbaf4e359b446fb50de7be Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Sat, 14 May 2016 13:42:17 -0700 Subject: [PATCH 19/72] FS-9158 [sofia-sip] Add include for changes in 65460fa --- libs/sofia-sip/libsofia-sip-ua/tport/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/Makefile.am b/libs/sofia-sip/libsofia-sip-ua/tport/Makefile.am index 6eb9a4ae85..6207f5a023 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/Makefile.am +++ b/libs/sofia-sip/libsofia-sip-ua/tport/Makefile.am @@ -15,7 +15,8 @@ AM_CPPFLAGS = -I$(srcdir)/../bnf -I../bnf \ -I$(srcdir)/../http -I../http \ -I$(srcdir)/../url -I../url \ -I$(srcdir)/../sip -I../sip \ - -I$(srcdir)/../su -I../su + -I$(srcdir)/../su -I../su \ + -I$(srcdir)/include # ---------------------------------------------------------------------- # Build targets From 1c9f6cc301f2ca050f0d416816ffc5ec04793b69 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 16 May 2016 12:23:11 -0500 Subject: [PATCH 20/72] FS-9153 #resolve [uuid_bridge issue on ESL] --- src/mod/event_handlers/mod_event_socket/mod_event_socket.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index a9ba87bf48..afb17be41f 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -2771,7 +2771,9 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) channel = switch_core_session_get_channel(listener->session); } - if (channel && (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { + if (channel && + !switch_channel_test_flag(channel, CF_REDIRECT) && !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_RESET) && + (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { switch_channel_set_state(channel, CS_RESET); } From 2c030254795e29f63dc72ec6fdb4334ba1393351 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 16 May 2016 14:46:11 -0400 Subject: [PATCH 21/72] FS-9164: [core] add Session-Per-Sec-Last to heartbeat event --- src/switch_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core.c b/src/switch_core.c index 4a8865612b..039531bb86 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -93,6 +93,7 @@ static void send_heartbeat(void) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Last", "%u", runtime.sps_last); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Max", "%u", runtime.sps_peak); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-FiveMin", "%u", runtime.sps_peak_fivemin); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); From 465a0b6f1d3f229b4067c3db418b8f86c9fa2e47 Mon Sep 17 00:00:00 2001 From: Antonio Date: Tue, 17 May 2016 18:40:27 +0200 Subject: [PATCH 22/72] FS-9034 revert commit in sofia.c that prevents register in new thread --- src/mod/endpoints/mod_sofia/sofia.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f2f458ffec..3d5c8fe018 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2027,15 +2027,18 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) sofia_dispatch_event_t *de = *dep; switch_memory_pool_t *pool; //sofia_profile_t *profile = (*dep)->profile; - + switch_thread_data_t *td; switch_core_new_memory_pool(&pool); *dep = NULL; de->pool = pool; + td = switch_core_alloc(pool, sizeof(*td)); + td->func = sofia_msg_thread_run_once; + td->obj = de; - + switch_thread_pool_launch_thread(&td); } void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) From 6300cd0773ec1518ebff35db29330e4b96463deb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 17 May 2016 13:41:19 -0500 Subject: [PATCH 23/72] FS-9167 #resolve [Playing file when all video feeds are vmuted does not show file] --- src/mod/applications/mod_conference/conference_file.c | 2 +- src/mod/applications/mod_conference/conference_video.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_file.c b/src/mod/applications/mod_conference/conference_file.c index 6cf27559a3..eceff51148 100644 --- a/src/mod/applications/mod_conference/conference_file.c +++ b/src/mod/applications/mod_conference/conference_file.c @@ -240,7 +240,7 @@ switch_status_t conference_file_play(conference_obj_t *conference, char *file, u flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT; - if (conference->members_with_video && conference_utils_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) { + if (conference_utils_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) { flags |= SWITCH_FILE_FLAG_VIDEO; } diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index dd16741fb5..90f3144071 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1459,7 +1459,7 @@ void conference_video_canvas_set_fnode_layer(mcu_canvas_t *canvas, conference_fi fnode->layer_id = idx; fnode->canvas_id = canvas->canvas_id; - if (layer->member_id > -1) { + if (layer->member_id > 0) { conference_member_t *member; if ((member = conference_member_get(canvas->conference, layer->member_id))) { From 969904bf46f952d5750b47355eeb0e2b4073b791 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 18 May 2016 12:47:30 -0500 Subject: [PATCH 24/72] FS-9153 #resolve [uuid_bridge issue on ESL] --- src/mod/event_handlers/mod_event_socket/mod_event_socket.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index afb17be41f..e463bf3f83 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -515,7 +515,9 @@ SWITCH_STANDARD_APP(socket_function) switch_ivr_parse_all_events(session); - if (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var))) { + if (switch_channel_get_state(channel) != CS_HIBERNATE && + !switch_channel_test_flag(channel, CF_REDIRECT) && !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_RESET) + && (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { switch_channel_set_state(channel, CS_EXECUTE); } @@ -2771,7 +2773,7 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) channel = switch_core_session_get_channel(listener->session); } - if (channel && + if (channel && switch_channel_get_state(channel) != CS_HIBERNATE && !switch_channel_test_flag(channel, CF_REDIRECT) && !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_RESET) && (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { switch_channel_set_state(channel, CS_RESET); From 2b10500231188c058a2de02f411f25e0af31288e Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Wed, 18 May 2016 15:20:15 -0500 Subject: [PATCH 25/72] FS-9160 #resolve tweak sip_invite_failure_* chan vars for properly reporting last outbound call failure when there are multiple bridge attempts on a single call --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 ++ src/mod/endpoints/mod_sofia/sofia.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index bc20ac2968..8c3f063839 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -501,6 +501,8 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending CANCEL to %s\n", switch_channel_get_name(channel)); if (!tech_pvt->got_bye) { switch_channel_set_variable(channel, "sip_hangup_disposition", "send_cancel"); + switch_channel_set_variable(channel, "sip_invite_failure_status", "487"); + switch_channel_set_variable(channel, "sip_invite_failure_phrase", "CANCEL"); } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { nua_cancel(tech_pvt->nh, diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 3d5c8fe018..0312195f0c 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1531,6 +1531,8 @@ static void our_sofia_event_callback(nua_event_t event, if (sip && channel) { switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_cancel"); + switch_channel_set_variable(channel, "sip_invite_failure_status", "487"); + switch_channel_set_variable(channel, "sip_invite_failure_phrase", "CANCEL"); if (sip->sip_reason) { char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason); @@ -6042,7 +6044,6 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status tagi_t tags[]) { char *call_info = NULL; - if (sip && session) { switch_channel_t *channel = switch_core_session_get_channel(session); const char *uuid; @@ -6068,8 +6069,13 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status >= 400) { char status_str[5]; switch_snprintf(status_str, sizeof(status_str), "%d", status); + switch_channel_set_variable(channel, "sip_invite_failure_status", status_str); + switch_channel_set_variable(channel, "sip_invite_failure_phrase", phrase); switch_channel_set_variable_partner(channel, "sip_invite_failure_status", status_str); switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", phrase); + } else { + switch_channel_set_variable_partner(channel, "sip_invite_failure_status", NULL); + switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", NULL); } if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850") From 46f4fda018637197dd19a9ed985fc29e7b1a5c87 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 19 May 2016 15:31:03 -0500 Subject: [PATCH 26/72] remove extra condition code that can never be called --- src/switch_core_media.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 8a25514604..5ff0a3afa6 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2704,11 +2704,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio return SWITCH_STATUS_GENERR; } - - if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) { - return SWITCH_STATUS_FALSE; - } - if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { if (engine->read_impl.encoded_bytes_per_packet) { bytes = engine->read_impl.encoded_bytes_per_packet; From 585cccd940f8b679a6b58a5e7605df2d3e8365bc Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Thu, 19 May 2016 18:43:05 -0700 Subject: [PATCH 27/72] FS-9185: fix format ifdefs for Solaris SPARC Fix SWITCH_INT64_T_FMT and SWITCH_TIME_T_FMT definitions for Solaris/SPARC FS-9185 #resolve --- configure.ac | 2 ++ src/include/switch_platform.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index efe5473ab0..bfc55fa89e 100644 --- a/configure.ac +++ b/configure.ac @@ -1122,6 +1122,8 @@ elif test "$ac_cv_sizeof_long" = "8"; then case "$host" in *pc-solaris2*) ;; + sparc-*-solaris2*) + ;; *-solaris2*|*apple-darwin*|*-openbsd*) if test "$ac_cv_sizeof_long_long" = "8"; then int64_t_fmt='#define SWITCH_INT64_T_FMT "lld"' diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index 933c4d3688..962bf972b3 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -279,7 +279,7 @@ typedef intptr_t switch_ssize_t; #endif -#if defined(__sun__) && defined(__x86_64) +#if defined(__sun__) && (defined(__x86_64) || defined(__arch64__)) #define SWITCH_TIME_T_FMT SWITCH_SIZE_T_FMT #else #define SWITCH_TIME_T_FMT SWITCH_INT64_T_FMT From 08199210c1f548a1aa9a302c32eb89fabbf90301 Mon Sep 17 00:00:00 2001 From: karl anderson Date: Thu, 2 Apr 2015 19:30:14 -0400 Subject: [PATCH 28/72] [mod_sofia] [FS-9188] added channel var to suppress auto-answer notify --- src/mod/endpoints/mod_sofia/sofia.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 0312195f0c..f151956bd0 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -6919,8 +6919,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { const char *full_to = NULL; - const char *val; - if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) { + const char *var; + if ((var = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(var) && + !((var = switch_channel_get_variable(channel, "sip_auto_answer_suppress_notify")) && switch_true(var))) { full_to = switch_str_nil(switch_channel_get_variable(channel, "sip_full_to")); nua_notify(nh, From 800655f774f12d76883f3a07ee35782006fb4c03 Mon Sep 17 00:00:00 2001 From: Spencer Thomason Date: Thu, 19 May 2016 14:16:26 -0700 Subject: [PATCH 29/72] FS-9184: Allow show calls to be filtered by accountcode --- .../applications/mod_commands/mod_commands.c | 8 +++---- src/switch_core_sqldb.c | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 35a4965172..135896e60f 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -5443,12 +5443,12 @@ SWITCH_STANDARD_API(show_function) } if (strchr(argv[2], '%')) { sprintf(sql, - "select * from channels where hostname='%s' and uuid like '%s' or name like '%s' or cid_name like '%s' or cid_num like '%s' or presence_data like '%s' order by created_epoch", - switch_core_get_switchname(), argv[2], argv[2], argv[2], argv[2], argv[2]); + "select * from channels where hostname='%s' and uuid like '%s' or name like '%s' or cid_name like '%s' or cid_num like '%s' or presence_data like '%s' or accountcode like '%s' order by created_epoch", + switch_core_get_switchname(), argv[2], argv[2], argv[2], argv[2], argv[2], argv[2]); } else { sprintf(sql, - "select * from channels where hostname='%s' and uuid like '%%%s%%' or name like '%%%s%%' or cid_name like '%%%s%%' or cid_num like '%%%s%%' or presence_data like '%%%s%%' order by created_epoch", - switch_core_get_switchname(), argv[2], argv[2], argv[2], argv[2], argv[2]); + "select * from channels where hostname='%s' and uuid like '%%%s%%' or name like '%%%s%%' or cid_name like '%%%s%%' or cid_num like '%%%s%%' or presence_data like '%%%s%%' or accountcode like '%%%s%%' order by created_epoch", + switch_core_get_switchname(), argv[2], argv[2], argv[2], argv[2], argv[2], argv[2]); } if (argv[4] && !strcasecmp(argv[3], "as")) { as = argv[4]; diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ff1ee6ff9f..fe64efaf9a 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2346,11 +2346,12 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CHANNEL_EXECUTE: { new_sql() = switch_mprintf("update channels set application='%q',application_data='%q'," - "presence_id='%q',presence_data='%q' where uuid='%q'", + "presence_id='%q',presence_data='%q',accountcode='%q' where uuid='%q'", switch_event_get_header_nil(event, "application"), switch_event_get_header_nil(event, "application-data"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "unique-id") ); @@ -2361,18 +2362,20 @@ static void core_event_handler(switch_event_t *event) { if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set " - "presence_id='%q',presence_data='%q', call_uuid='%q',%s where uuid='%q'", + "presence_id='%q',presence_data='%q',accountcode='%q',call_uuid='%q',%s where uuid='%q'", switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "channel-call-uuid"), extra_cols, switch_event_get_header_nil(event, "unique-id")); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set " - "presence_id='%q',presence_data='%q', call_uuid='%q' where uuid='%q'", + "presence_id='%q',presence_data='%q',accountcode='%q',call_uuid='%q' where uuid='%q'", switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "channel-call-uuid"), switch_event_get_header_nil(event, "unique-id")); } @@ -2463,7 +2466,7 @@ static void core_event_handler(switch_event_t *event) if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," "sent_callee_name='%q',sent_callee_num='%q'," - "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s " + "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',accountcode='%q',%s " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "caller-caller-id-name"), @@ -2478,13 +2481,14 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), extra_cols, switch_event_get_header_nil(event, "unique-id")); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," "sent_callee_name='%q',sent_callee_num='%q'," - "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' " + "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',accountcode='%q' " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "caller-caller-id-name"), @@ -2499,6 +2503,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "unique-id")); } break; @@ -2705,6 +2710,7 @@ static char create_channels_sql[] = " hostname VARCHAR(256),\n" " presence_id VARCHAR(4096),\n" " presence_data VARCHAR(4096),\n" + " accountcode VARCHAR(256),\n" " callstate VARCHAR(64),\n" " callee_name VARCHAR(1024),\n" " callee_num VARCHAR(256),\n" @@ -2804,6 +2810,7 @@ static char detailed_calls_sql[] = "a.hostname as hostname," "a.presence_id as presence_id," "a.presence_data as presence_data," + "a.accountcode as accountcode," "a.callstate as callstate," "a.callee_name as callee_name," "a.callee_num as callee_num," @@ -2835,6 +2842,7 @@ static char detailed_calls_sql[] = "b.hostname as b_hostname," "b.presence_id as b_presence_id," "b.presence_data as b_presence_data," + "b.accountcode as b_accountcode," "b.callstate as b_callstate," "b.callee_name as b_callee_name," "b.callee_num as b_callee_num," @@ -2874,6 +2882,7 @@ static char basic_calls_sql[] = "a.presence_id as presence_id," "a.presence_data as presence_data," + "a.accountcode as accountcode," "a.callstate as callstate," "a.callee_name as callee_name," "a.callee_num as callee_num," @@ -2897,6 +2906,7 @@ static char basic_calls_sql[] = "b.presence_id as b_presence_id," "b.presence_data as b_presence_data," + "b.accountcode as b_accountcode," "b.callstate as b_callstate," "b.callee_name as b_callee_name," "b.callee_num as b_callee_num," @@ -3437,7 +3447,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, 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 call_uuid, read_bit_rate, sent_callee_name, initial_cid_name, initial_cid_num, initial_ip_addr, initial_dest, initial_dialplan, initial_context, accountcode from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid from calls", "DROP TABLE calls", create_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 * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); From dc7753f51667e235ec7171a697f14989c9759e6f Mon Sep 17 00:00:00 2001 From: Luis Azedo Date: Sun, 13 Dec 2015 15:28:26 +0000 Subject: [PATCH 30/72] FS-8652 handle early-only param in replaces header --- src/mod/endpoints/mod_sofia/sofia.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 5269b720ca..d2f06b5586 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -10306,13 +10306,20 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia } } else { if (!zstr(bridge_uuid)) { - switch_channel_mark_hold(b_channel, SWITCH_FALSE); - tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid); - if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS) - && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(b_channel, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id); - switch_event_fire(&event); + if (sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) && + switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercept rejected\n", bridge_uuid); + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED"); + } else { + switch_channel_mark_hold(b_channel, SWITCH_FALSE); + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercepted\n", bridge_uuid); + if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS) && + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(b_channel, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id); + switch_event_fire(&event); + } } } else { const char *b_app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE); From 93e401e78bc1b595313a6ce5b1a643b15ad96fcc Mon Sep 17 00:00:00 2001 From: Seven Du Date: Tue, 24 May 2016 15:54:22 +0800 Subject: [PATCH 31/72] FS-8979 #resolve #comment please test --- src/mod/formats/mod_imagick/mod_imagick.c | 89 ++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/src/mod/formats/mod_imagick/mod_imagick.c b/src/mod/formats/mod_imagick/mod_imagick.c index 2ded733f3e..8d95965780 100644 --- a/src/mod/formats/mod_imagick/mod_imagick.c +++ b/src/mod/formats/mod_imagick/mod_imagick.c @@ -61,8 +61,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_imagick_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_imagick_shutdown); SWITCH_MODULE_DEFINITION(mod_imagick, mod_imagick_load, mod_imagick_shutdown, NULL); +typedef enum pdf_loading_state_s { + PLS_LOADING, + PLS_BREAK, + PLS_DONE +} pdf_loading_state_t; + struct pdf_file_context { switch_memory_pool_t *pool; + switch_mutex_t *mutex; switch_image_t *img; int reads; int sent; @@ -75,16 +82,51 @@ struct pdf_file_context { Image *images; ExceptionInfo *exception; int autoplay; + const char *path; + int lazy; + pdf_loading_state_t loading_state; switch_time_t next_play_time; }; typedef struct pdf_file_context pdf_file_context_t; +static void *SWITCH_THREAD_FUNC open_pdf_thread_run(switch_thread_t *thread, void *obj) +{ + pdf_file_context_t *context = (pdf_file_context_t *)obj; + int pagenumber = context->lazy; + char path[1024]; + + while (context->loading_state == PLS_LOADING) { + Image *tmp_images; + switch_snprintf(path, sizeof(path), "%s[%d]", context->path, pagenumber); + switch_set_string(context->image_info->filename, path); + if ((tmp_images = ReadImages(context->image_info, context->exception))) { + pagenumber++; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s page %d loaded\n", context->path, pagenumber); + AppendImageToList(&context->images, tmp_images); + context->pagecount = pagenumber; + } else { + break; + } + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "read file: %s %s, pagecount: %d\n", + context->path, context->loading_state == PLS_BREAK ? "break" : "done", pagenumber); + + switch_mutex_lock(context->mutex); + context->loading_state = PLS_DONE; + switch_mutex_unlock(context->mutex); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read Images Thread Ended.\n"); + return NULL; +} + static switch_status_t imagick_file_open(switch_file_handle_t *handle, const char *path) { pdf_file_context_t *context; char *ext; unsigned int flags = 0; + char range_path[1024]; if ((ext = strrchr((char *)path, '.')) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); @@ -121,13 +163,14 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha context->exception = AcquireExceptionInfo(); context->image_info = AcquireImageInfo(); - switch_set_string(context->image_info->filename, path); + context->path = switch_core_strdup(handle->memory_pool, path); if (handle->params) { const char *max = switch_event_get_header(handle->params, "img_ms"); const char *autoplay = switch_event_get_header(handle->params, "autoplay"); const char *density = switch_event_get_header(handle->params, "density"); const char *quality = switch_event_get_header(handle->params, "quality"); + const char *lazy = switch_event_get_header(handle->params, "lazy"); int tmp; if (max) { @@ -148,6 +191,23 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha if (tmp > 0) context->image_info->quality = tmp; } + if (lazy) { + int tmp = atoi(lazy); + + if (tmp >= 0) { + context->lazy = tmp; + } else { + context->lazy = 1; + } + } + } + + if (context->lazy) { + switch_snprintf(range_path, sizeof(range_path), "%s[0-%d]", path, context->lazy - 1); + switch_set_string(context->image_info->filename, range_path); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "loading first %d page%s\n", context->lazy, context->lazy > 1 ? "s" : ""); + } else { + switch_set_string(context->image_info->filename, path); } context->images = ReadImages(context->image_info, context->exception); @@ -175,7 +235,20 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha handle->private_info = context; context->pool = handle->memory_pool; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s], pagecount: %d\n", path, context->pagecount); + if (context->lazy) { + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + + switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, context->pool); + context->loading_state = PLS_LOADING; + switch_thread_create(&thread, thd_attr, open_pdf_thread_run, context, context->pool); + } + + if (context->lazy) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File %s, read the first %d page(s)", path, context->lazy); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File %s", path); + } return SWITCH_STATUS_SUCCESS; } @@ -184,6 +257,18 @@ static switch_status_t imagick_file_close(switch_file_handle_t *handle) { pdf_file_context_t *context = (pdf_file_context_t *)handle->private_info; + if (context->lazy) { + switch_mutex_lock(context->mutex); + if (context->loading_state == PLS_LOADING) context->loading_state = PLS_BREAK; + switch_mutex_unlock(context->mutex); + + while (context->loading_state != PLS_DONE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "waiting for pdf loading thread done, loading_state: %d\n", context->loading_state); + switch_yield(1000000); + switch_cond_next(); + } + } + switch_img_free(&context->img); if (context->images) DestroyImageList(context->images); From a8c497cbac5c99458f65f5d86cd3d170a8afceff Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Wed, 25 May 2016 15:27:12 +0200 Subject: [PATCH 32/72] debian: fix compatibility with systemd 215 on Jessie Since FS-8788, this error is printed to the journal: [/lib/systemd/system/freeswitch.service:22] Failed to parse resource value, ignoring: 240K It turns out that suffixes are only introduced in systemd 228 which is not available in Debian Jessie. Use 240*1024, rounded up to a nice human-readable number. --- debian/freeswitch-systemd.freeswitch.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/freeswitch-systemd.freeswitch.service b/debian/freeswitch-systemd.freeswitch.service index cc0cf1d582..b9fbdb9d76 100644 --- a/debian/freeswitch-systemd.freeswitch.service +++ b/debian/freeswitch-systemd.freeswitch.service @@ -19,7 +19,7 @@ Group=daemon LimitCORE=infinity LimitNOFILE=100000 LimitNPROC=60000 -LimitSTACK=240K +LimitSTACK=250000 LimitRTPRIO=infinity LimitRTTIME=7000000 IOSchedulingClass=realtime From e26dbafa6ac03e59c84010e786f55228786432a9 Mon Sep 17 00:00:00 2001 From: "nneul at mst.edu" Date: Wed, 25 May 2016 10:40:28 -0500 Subject: [PATCH 33/72] FS-9198 [mod_skinny] fix small memory leaks --- src/mod/endpoints/mod_skinny/skinny_server.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index ad635ab2e2..47d4647750 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -1246,27 +1246,27 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r listener->soft_key_set_set = switch_core_strdup(profile->pool, value); } else if (!strcasecmp(name, "ext-voicemail")) { if (!listener->ext_voicemail || strcmp(value,listener->ext_voicemail)) { - listener->ext_voicemail = switch_core_strdup(profile->pool, value); + listener->ext_voicemail = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-redial")) { if (!listener->ext_redial || strcmp(value,listener->ext_redial)) { - listener->ext_redial = switch_core_strdup(profile->pool, value); + listener->ext_redial = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-meetme")) { if (!listener->ext_meetme || strcmp(value,listener->ext_meetme)) { - listener->ext_meetme = switch_core_strdup(profile->pool, value); + listener->ext_meetme = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-pickup")) { if (!listener->ext_pickup || strcmp(value,listener->ext_pickup)) { - listener->ext_pickup = switch_core_strdup(profile->pool, value); + listener->ext_pickup = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-cfwdall")) { if (!listener->ext_cfwdall || strcmp(value,listener->ext_cfwdall)) { - listener->ext_cfwdall = switch_core_strdup(profile->pool, value); + listener->ext_cfwdall = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-autodial")) { if (!listener->ext_autodial || strcmp(value,listener->ext_autodial)) { - listener->ext_autodial = switch_core_strdup(profile->pool, value); + listener->ext_autodial = switch_core_strdup(listener->pool, value); } } } From 0151b8edddc1fc718ef2e87ab4178b615ec01a59 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 25 May 2016 10:59:15 -0500 Subject: [PATCH 34/72] FS-9106 followup and tweaks on this patch after some testing --- src/mod/applications/mod_conference/conference_video.c | 4 ++-- src/switch_vpx.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 90f3144071..eb69e2e192 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1480,7 +1480,7 @@ void conference_video_launch_muxing_write_thread(conference_member_t *member) switch_mutex_lock(conference_globals.hash_mutex); if (!member->video_muxing_write_thread) { switch_threadattr_create(&thd_attr, member->pool); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); + //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&member->video_muxing_write_thread, thd_attr, conference_video_muxing_write_thread_run, member, member->pool); } @@ -1493,7 +1493,7 @@ void conference_video_launch_muxing_thread(conference_obj_t *conference, mcu_can switch_mutex_lock(conference_globals.hash_mutex); if (!canvas->video_muxing_thread) { switch_threadattr_create(&thd_attr, conference->pool); - switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); + //switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); conference_utils_set_flag(conference, CFLAG_VIDEO_MUXING); switch_thread_create(&canvas->video_muxing_thread, thd_attr, diff --git a/src/switch_vpx.c b/src/switch_vpx.c index 6ad449f14e..ebfe51da97 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -360,7 +360,7 @@ static switch_status_t init_encoder(switch_codec_t *codec) vpx_codec_enc_cfg_t *config = &context->config; int token_parts = 1; int cpus = switch_core_cpu_count(); - int sane; + int sane, threads = 1; if (!context->codec_settings.video.width) { context->codec_settings.video.width = 1280; @@ -404,7 +404,9 @@ static switch_status_t init_encoder(switch_codec_t *codec) config->rc_target_bitrate = context->bandwidth; config->g_lag_in_frames = 0; config->kf_max_dist = 360;//2000; - config->g_threads = cpus - 1;//(cpus > 1) ? 2 : 1; + threads = cpus / 4; + if (threads < 0) threads = 1; + config->g_threads = threads; if (context->is_vp9) { //config->rc_dropframe_thresh = 2; From 8339c1f98041ebfa59c95fa07e6b3ac8b8a064e1 Mon Sep 17 00:00:00 2001 From: "nneul at mst.edu" Date: Wed, 25 May 2016 13:57:46 -0500 Subject: [PATCH 35/72] FS-9201 [mod_skinny] fix leak in api call to list devices --- src/mod/endpoints/mod_skinny/skinny_api.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mod/endpoints/mod_skinny/skinny_api.c b/src/mod/endpoints/mod_skinny/skinny_api.c index aba3abf97a..f9f734f630 100644 --- a/src/mod/endpoints/mod_skinny/skinny_api.c +++ b/src/mod/endpoints/mod_skinny/skinny_api.c @@ -94,6 +94,7 @@ static switch_status_t skinny_api_list_devices(const char *line, const char *cur return status; } if (!(argc = switch_separate_string(myline, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) || argc < 4) { + switch_safe_free(myline); return status; } @@ -115,6 +116,8 @@ static switch_status_t skinny_api_list_devices(const char *line, const char *cur status = SWITCH_STATUS_SUCCESS; } + switch_safe_free(myline); + return status; } From ae8e5cb1185c54347a751b0d16f286fdf45b1f1b Mon Sep 17 00:00:00 2001 From: "nneul at mst.edu" Date: Wed, 25 May 2016 14:14:03 -0500 Subject: [PATCH 36/72] FS-9202 [mod_skinny] fix leak in speed dial --- src/mod/endpoints/mod_skinny/skinny_server.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index 47d4647750..b1da93b4c4 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -116,9 +116,6 @@ switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *l if (!button || !button->shortname[0]) { skinny_log_l(listener, SWITCH_LOG_CRIT, "Line %d not found on device\n", *line_instance_p); - if ( button ) { - switch_safe_free(button); - } goto error; } @@ -202,17 +199,13 @@ error: } listener->profile->ib_failed_calls++; - if ( button ) { - switch_safe_free(button); - } + switch_safe_free(button); return SWITCH_STATUS_FALSE; done: *session = nsession; listener->profile->ib_calls++; - if ( button ) { - switch_safe_free(button); - } + switch_safe_free(button); return SWITCH_STATUS_SUCCESS; } @@ -1531,11 +1524,12 @@ switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_mess } if ( !session ) { skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle speed dial stimulus message, couldn't create incoming session.\n"); + switch_safe_free(button_speed_dial); return SWITCH_STATUS_FALSE; } skinny_session_process_dest(session, listener, line_instance, button_speed_dial->line, '\0', 0); - switch_safe_free(button_speed_dial); } + switch_safe_free(button_speed_dial); break; case SKINNY_BUTTON_HOLD: session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); From 67e1db09d38d3cb67d09eb0fe0cfb576f3d93485 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 26 May 2016 10:09:57 -0500 Subject: [PATCH 37/72] FS-9198 #resolve [Small memory leaks in mod_skinny] --- .../applications/mod_conference/conference_video.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index eb69e2e192..d1d057f8f5 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -330,9 +330,13 @@ void conference_video_reset_image(switch_image_t *img, switch_rgb_color_t *color void conference_video_clear_layer(mcu_layer_t *layer) { - switch_img_fill(layer->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &layer->canvas->bgcolor); + if (layer->canvas && layer->canvas->img) { + switch_img_fill(layer->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &layer->canvas->bgcolor); + } + layer->banner_patched = 0; layer->refresh = 1; + } void conference_video_reset_layer(mcu_layer_t *layer) @@ -641,8 +645,7 @@ void conference_video_detach_video_layer(conference_member_t *member) switch_mutex_lock(canvas->mutex); if (member->video_layer_id < 0) { - switch_mutex_unlock(canvas->mutex); - return; + goto end; } layer = &canvas->layers[member->video_layer_id]; @@ -676,6 +679,8 @@ void conference_video_detach_video_layer(conference_member_t *member) conference_video_set_canvas_bgimg(canvas, NULL); } + end: + switch_mutex_unlock(canvas->mutex); conference_video_release_canvas(&canvas); From 68892535ca188a1dabb942bfcc77932aec0b08c9 Mon Sep 17 00:00:00 2001 From: "nneul at mst.edu" Date: Thu, 26 May 2016 16:08:21 -0500 Subject: [PATCH 38/72] FS-9199 easier memory allocation debugging and analysis --- scripts/perl/analyze-debug-alloc.pl | 136 ++++++++++++++++++++++++++++ src/switch_core_memory.c | 12 ++- 2 files changed, 144 insertions(+), 4 deletions(-) create mode 100755 scripts/perl/analyze-debug-alloc.pl diff --git a/scripts/perl/analyze-debug-alloc.pl b/scripts/perl/analyze-debug-alloc.pl new file mode 100755 index 0000000000..fe13092211 --- /dev/null +++ b/scripts/perl/analyze-debug-alloc.pl @@ -0,0 +1,136 @@ +#!/usr/bin/perl + +# analyze-debug-alloc.pl +# generate allocation report by processing log files + +# Note that this script is only useful when run against freeswitch log files +# produced when server is running with DEBUG_ALLOC and DEBUG_ALLOC2 set. +# It's purely for diagnosing memory leaks. + +use strict; +use JSON; + +my $debug = 0; + +my @logs = sort glob("freeswitch.log.*"); +push( @logs, "freeswitch.log" ); + +my %pools = (); + +foreach my $file (@logs) { + open( my $in, "<$file" ); + while ( defined( my $line = <$in> ) ) { + if ( $line =~ /(0x[0-9A-Fa-f]+) DESTROY POOL$/o ) { + my $paddr = $1; + if ( !$pools{$paddr} ) { + $debug && print "WARN: No ref to pool $paddr.\n"; + } + else { + foreach my $alloc ( @{ $pools{$paddr}->{allocs} } ) { + + # debug, might not be needed + } + delete $pools{$paddr}; + } + } + elsif ( $line =~ /(0x[0-9A-Fa-f]+) Free Pool/o ) { + my $paddr = $1; + if ( !$pools{$paddr} ) { + $debug && print "WARN: No ref to pool $paddr.\n"; + } + else { + foreach my $alloc ( @{ $pools{$paddr}->{allocs} } ) { + + # debug, might not be needed + } + delete $pools{$paddr}; + } + } + elsif ( $line =~ /(0x[0-9A-Fa-f]+) New Pool (.*)$/o ) { + my $paddr = $1; + my $where = $2; + if ( $pools{$paddr} ) { + $debug && print "WARN: Duplicate pool $paddr at $where.\n"; + } + $pools{$paddr}->{where} = $where; + if ( !$pools{$paddr}->{allocs} ) { + $pools{$paddr}->{allocs} = []; + } + } + elsif ( $line =~ /CONSOLE\] \s*(.*?:\d+) (0x[0-9A-Fa-f]+) Core Allocate (.*:\d+)\s+(\d+)$/o ) { + my $where = $1; + my $paddr = $2; + my $pwhere = $3; + my $size = $4; + if ( !$pools{$paddr} ) { + $debug && print "WARN: Missing pool ref for alloc of $size from $paddr at $where (pool $pwhere)\n"; + } + $pools{$paddr}->{where} = $where; + push( @{ $pools{$paddr}->{allocs} }, { size => $size, where => $where } ); + } + elsif ( $line =~ /CONSOLE\] \s*(.*?:\d+) (0x[0-9A-Fa-f]+) Core Strdup Allocate (.*:\d+)\s+(\d+)$/o ) { + my $where = $1; + my $paddr = $2; + my $pwhere = $3; + my $size = $4; + if ( !$pools{$paddr} ) { + $debug + && print "WARN: Missing pool ref for strdup alloc of $size from $paddr at $where (pool $pwhere)\n"; + } + $pools{$paddr}->{where} = $where; + push( @{ $pools{$paddr}->{allocs} }, { size => $size, where => $where } ); + } + } +} + +my $used = 0; +my $pcount = 0; +my $acount = 0; +my %pool_cnt_by_where = (); +my %alloc_size_by_where = (); +my %alloc_cnt_by_where = (); +foreach my $pool ( keys %pools ) { + my $where = $pools{$pool}->{where}; + $pcount++; + $pool_cnt_by_where{$where}++; + + foreach my $alloc ( @{ $pools{$pool}->{allocs} } ) { + my $sz = $alloc->{size}; + my $where = $alloc->{where}; + + $acount++; + $alloc_size_by_where{$where} += $sz; + $alloc_cnt_by_where{$where}++; + + $used += $sz; + } +} + +print "Used: $used\n"; +print "Pool Count: $pcount\n"; +print "Alloc Count: $acount\n"; + +my $json = new JSON; +$json->pretty(1); +$json->canonical(1); + +print "Pool Count by Where:\n"; +foreach my $pool ( sort { $pool_cnt_by_where{$a} <=> $pool_cnt_by_where{$b} || $a cmp $b } keys %pool_cnt_by_where ) { + print $pool_cnt_by_where{$pool}, "\t", $pool, "\n"; +} +print "\n"; + +print "Alloc Count by Where:\n"; +foreach my $pool ( sort { $alloc_cnt_by_where{$a} <=> $alloc_cnt_by_where{$b} || $a cmp $b } keys %alloc_cnt_by_where ) +{ + print $alloc_cnt_by_where{$pool}, "\t", $pool, "\n"; +} +print "\n"; + +print "Alloc Size by Where:\n"; +foreach + my $pool ( sort { $alloc_size_by_where{$a} <=> $alloc_size_by_where{$b} || $a cmp $b } keys %alloc_size_by_where ) +{ + print $alloc_size_by_where{$pool}, "\t", $pool, "\n"; +} +print "\n"; diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 7b1ae8f1c2..90fa1fc96d 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -37,6 +37,7 @@ //#define DEBUG_ALLOC //#define DEBUG_ALLOC2 +//#define DEBUG_ALLOC_CUTOFF 0 /* Lower to zero to log all pool allocations when DEBUG_ALLOC is defined */ //#define DESTROY_POOLS //#define INSTANTLY_DESTROY_POOLS //#define LOCK_MORE @@ -45,6 +46,9 @@ #ifndef SWITCH_POOL_RECYCLE #define PER_POOL_LOCK 1 #endif +#ifndef DEBUG_ALLOC_CUTOFF +#define DEBUG_ALLOC_CUTOFF 500 +#endif static struct { #ifdef USE_MEM_LOCK @@ -79,7 +83,7 @@ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t * #endif #ifdef DEBUG_ALLOC - if (memory > 500) + if (memory > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p %p Session Allocate %s %d\n", (void *) session->pool, (void *) session, apr_pool_tag(session->pool, NULL), (int) memory); #endif @@ -247,7 +251,7 @@ SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t #ifdef DEBUG_ALLOC len = strlen(todup); - if (len > 500) + if (len > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p %p Sess Strdup Allocate %s %ld\n", (void *) session->pool, (void *)session, apr_pool_tag(session->pool, NULL), strlen(todup)); #endif @@ -286,7 +290,7 @@ SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, co len = strlen(todup) + 1; #ifdef DEBUG_ALLOC - if (len > 500) + if (len > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Strdup Allocate %s %d\n", (void *) pool, apr_pool_tag(pool, NULL), (int)len); #endif @@ -457,7 +461,7 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, swi #endif #ifdef DEBUG_ALLOC - if (memory > 500) + if (memory > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Allocate %s %d\n", (void *) pool, apr_pool_tag(pool, NULL), (int) memory); /*switch_assert(memory < 20000); */ From 57aa22638c1ff2c2d6ead38cc7a6c923b1a3759d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 27 May 2016 14:52:51 -0500 Subject: [PATCH 39/72] FS-9207 #resolve [Add ignore_sdp_ice=true to ignore ICE when parsing an SDP] --- src/switch_core_media.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 5ff0a3afa6..50df501340 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3347,6 +3347,10 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t const char *val; int ice_seen = 0, cid = 0, ai = 0; + if (switch_true(switch_channel_get_variable_dup(smh->session->channel, "ignore_sdp_ice", SWITCH_FALSE, -1))) { + return SWITCH_STATUS_BREAK; + } + //if (engine->ice_in.is_chosen[0] && engine->ice_in.is_chosen[1]) { //return SWITCH_STATUS_SUCCESS; //} From a4cf41771e7f8d3648b422aed6284ccdc93734e2 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sun, 29 May 2016 21:00:49 +0800 Subject: [PATCH 40/72] A-law idle byte was defined incorrectly. --- libs/spandsp/src/spandsp/g711.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/spandsp/src/spandsp/g711.h b/libs/spandsp/src/spandsp/g711.h index f722c6067c..62e537acff 100644 --- a/libs/spandsp/src/spandsp/g711.h +++ b/libs/spandsp/src/spandsp/g711.h @@ -50,9 +50,12 @@ specification by other means. #if !defined(_SPANDSP_G711_H_) #define _SPANDSP_G711_H_ +/*! The A-law alternate mark inversion mask */ +#define G711_ALAW_AMI_MASK 0x55 + /* The usual values to use on idle channels, to emulate silence */ /*! Idle value for A-law channels */ -#define G711_ALAW_IDLE_OCTET 0x5D +#define G711_ALAW_IDLE_OCTET (0x80 ^ G711_ALAW_AMI_MASK) /*! Idle value for u-law channels */ #define G711_ULAW_IDLE_OCTET 0xFF @@ -192,9 +195,6 @@ static __inline__ int16_t ulaw_to_linear(uint8_t ulaw) * John Wiley & Sons, pps 98-111 and 472-476. */ -/*! The A-law alternate mark inversion mask */ -#define G711_ALAW_AMI_MASK 0x55 - /*! \brief Encode a linear sample to A-law \param linear The sample to encode. \return The A-law value. From eb369130d97802e3e739cebace38d76887cdf450 Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Mon, 30 May 2016 21:05:22 +0100 Subject: [PATCH 41/72] FS-9142 [avmd] Dynamic settings Add checking of per session settings with locking synced on avmd session mutex --- .../conf/autoload_configs/avmd.conf.xml | 2 +- src/mod/applications/mod_avmd/mod_avmd.c | 362 +++++++----------- 2 files changed, 146 insertions(+), 218 deletions(-) diff --git a/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml b/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml index 9d7363c68a..039658cf8d 100644 --- a/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml +++ b/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml @@ -38,7 +38,7 @@ - + - + diff --git a/src/mod/applications/mod_osp/docs/mod_osp.txt b/src/mod/applications/mod_osp/docs/mod_osp.txt index a12e718740..fa339bac37 100644 --- a/src/mod/applications/mod_osp/docs/mod_osp.txt +++ b/src/mod/applications/mod_osp/docs/mod_osp.txt @@ -43,7 +43,7 @@ OSP provider parameter names ane values cab be: - http-retry-limit: HTTP retry times. The default is 2. - http-timeout: HTTP timeout. The default is 10000 in ms. - work-mode: OSP module work mode (direct and indirect). The default is "direct". - - service-type: OSP service type (voice and npquery). The default is "voice". + - service-type: OSP service type (voice, npquery and cnamquery (this option has not been implemented)). The default is "voice". - max-destinations: Max destinations OSP server will return. It is up to 12. The default is 12. 3 OSP Applications @@ -54,7 +54,7 @@ The OSP applications are called in dial plan like this: *PROFILE* is an OSP service provider profile name configured in osp.conf.xml. If data attribute is not provided or its value is empty, profile name "default" is used. 3.1 OSPLookup Application -osplookup application does OSP authorization request and gets first supported destination for inbound calls. It exports a set channel variables for FreeSWITCH dial plan logic. +osplookup application does OSP authorization request and gets first supported destination for inbound calls. It exports a set of channel variables for FreeSWITCH dial plan logic. osplookup application accepts two sets of channel variables that are used to pass additional inbound call information and outbound control parameters to OSP module. It also exports a set of channel variables for outbound channels and FreeSWITCH dial plan logic. 3.1.1 Inbound Call Information @@ -64,7 +64,9 @@ osplookup application accepts two sets of channel variables that are used to pas 3.1.2 Outbound Control Parameters - osp_networkid_userparam: The URI user parameter name that is used to present destination network ID. For example, sip:callednumber;networkid=dnid@host. - - osp_networkid_uriparam: The URI parameter name that is used to present destination network ID. For example, sip:callednumber @host;networkid=dnid. + - osp_networkid_uriparam: The URI parameter name that is used to present destination network ID. For example, sip:callednumber@host;networkid=dnid. + - osp_outstring_userparam: The URI user parameter string. For example, sip:callednumber;outstring@host. + - osp_outstring_uriparam: The URI parameter string. For example, sip:callednumber@host;outstring. - osp_user_phone: Flag to add "user=phone" URI parameter. The default is "disabled". - osp_outbound_proxy: Outbound proxy IP address channel variable. @@ -79,7 +81,7 @@ osplookup application accepts two sets of channel variables that are used to pas - osp_termiation_cause: Destination termination cause. It will be used by ospnext application and OSP module state handlers. 3.2 OSPNext Application -ospnext application gets next supported destination for inbound calls. It exports a set channel variables for FreeSWITCH dial plan logic. +ospnext application gets next supported destination for inbound calls. It exports a set of channel variables for FreeSWITCH dial plan logic. ospnext application accepts a set of channel variables exported by osplookup application to pass OSP call transaction information to OSP module. It also exports a set of channel variables for outbound channels and FreeSWITCH dial plan logic. 3.2.1 Transaction Parameters @@ -157,7 +159,7 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + @@ -176,15 +178,14 @@ OSP module state handler accepts a set of channel variables exported by osplooku - @@ -206,27 +207,68 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + + - - + - + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -265,10 +307,18 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + + + + + + + - + @@ -283,7 +333,9 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + diff --git a/src/mod/applications/mod_osp/mod_osp.c b/src/mod/applications/mod_osp/mod_osp.c index 19ea56e399..693d240826 100644 --- a/src/mod/applications/mod_osp/mod_osp.c +++ b/src/mod/applications/mod_osp/mod_osp.c @@ -34,6 +34,8 @@ #include #include +#define OSP_FREESWITCH "freeswitch" /* FreeSWITCH */ + /* OSP Buffer Size Constants */ #define OSP_SIZE_NORSTR 512 /* OSP normal string buffer size */ #define OSP_SIZE_KEYSTR 1024 /* OSP certificate string buffer size */ @@ -64,18 +66,22 @@ /* OSP Handle Constant */ #define OSP_INVALID_HANDLE -1 /* Invalid OSP handle, provider, transaction etc. */ -/* OSP Provider Contants */ +/* OSP Provider Constants */ #define OSP_AUDIT_URL "localhost" /* OSP default Audit URL */ #define OSP_LOCAL_VALID 1 /* OSP token validating method, locally */ #define OSP_CUSTOMER_ID "" /* OSP customer ID */ #define OSP_DEVICE_ID "" /* OSP device ID */ -/* URI Contants */ -#define OSP_URI_DELIM '@' /* URI delimit */ -#define OSP_USER_DELIM ";:" /* URI userinfo delimit */ -#define OSP_HOST_DELIM ";>" /* URI hostport delimit */ +/* URI/SDP Constants */ +#define OSP_URI_DELIM '@' /* URI delimiter */ +#define OSP_USER_DELIM ";:" /* URI userinfo delimiter */ +#define OSP_HOST_DELIM ";>" /* URI hostport delimiter */ +#define OSP_SDP_DELIM '\r' /* SDP line delimiter */ +#define OSP_IP_DELIM '/' /* SDP multicast address delimiter */ +#define OSP_SDP_CHEADER "c=IN IP4 " /* SDP connection line header */ +#define OSP_CHEADER_SIZE 9 /* SDP connection line header length */ -/* OSP Module Other Contants */ +/* OSP Module Other Constants */ #define OSP_MAX_CINFO 8 /* Max number of custom info */ #define OSP_DEF_STRING "" /* OSP default empty string */ #define OSP_DEF_STATS -1 /* OSP default statistics */ @@ -101,6 +107,8 @@ #define OSP_VAR_CUSTOMINFO "osp_custom_info_" /* Custom info, inbound */ #define OSP_VAR_DNIDUSERPARAM "osp_networkid_userparam" /* Destination network ID user parameter name, outbound */ #define OSP_VAR_DNIDURIPARAM "osp_networkid_uriparam" /* Destination network ID URI parameter name, outbound */ +#define OSP_VAR_OUTUSERPARAM "osp_outstring_userparam" /* Fixed outbound parameter string user parameter, outbound */ +#define OSP_VAR_OUTURIPARAM "osp_outstring_uriparam" /* Fixed outbound parameter string URI parameter, outbound */ #define OSP_VAR_USERPHONE "osp_user_phone" /* If to add "user=phone", outbound */ #define OSP_VAR_OUTPROXY "osp_outbound_proxy" /* Outbound proxy, outbound */ #define OSP_VAR_PROFILE "osp_profile_name" /* Profile name */ @@ -108,13 +116,15 @@ #define OSP_VAR_TRANSID "osp_transaction_id" /* Transaction ID */ #define OSP_VAR_ROUTETOTAL "osp_route_total" /* Total number of destinations */ #define OSP_VAR_ROUTECOUNT "osp_route_count" /* Destination count */ -#define OSP_VAR_TCCODE "osp_termination_cause" /* Terimation cause */ +#define OSP_VAR_TCCODE "osp_termination_cause" /* Termination cause */ #define OSP_VAR_AUTOROUTE "osp_auto_route" /* Bridge route string */ #define OSP_VAR_LOOKUPSTATUS "osp_lookup_status" /* OSP lookup function status */ #define OSP_VAR_NEXTSTATUS "osp_next_status" /* OSP next function status */ /* OSP Using FreeSWITCH Variable Names */ +#define OSP_FS_SIPLOCALIP "sip_local_network_addr" /* Inbound SIP local IP */ #define OSP_FS_CALLID "sip_call_id" /* Inbound SIP Call-ID */ +#define OSP_FS_FROMDISPLAY "sip_from_display" /* Inbound SIP From display name */ #define OSP_FS_FROMUSER "sip_from_user" /* Inbound SIP From user */ #define OSP_FS_TOHOST "sip_to_host" /* Inbound SIP To host */ #define OSP_FS_TOPORT "sip_to_port" /* Inbound SIP To port */ @@ -122,15 +132,20 @@ #define OSP_FS_PAI "sip_P-Asserted-Identity" /* Inbound SIP P-Asserted-Identity header */ #define OSP_FS_DIV "sip_h_Diversion" /* Inbound SIP Diversion header */ #define OSP_FS_PCI "sip_h_P-Charge-Info" /* Inbound SIP P-Charge-Info header */ +#define OSP_FS_USERAGENT "sip_user_agent" /* Inbound SIP User-Agent header */ +#define OSP_FS_RURIUSERPARAM "sip_invite_tel_params" /* Outbound RURI user parameter */ +#define OSP_FS_RURIURIPARAM "sip_invite_params" /* Outbound RURI URI parameter */ #define OSP_FS_OUTCALLING "origination_caller_id_number" /* Outbound calling number */ +#define OSP_FS_HANGUPCAUSE "last_bridge_hangup_cause" /* Termination cause */ +#define OSP_FS_BLEGPREFIX "Other-Leg" /* Originatee variable prefix */ +#define OSP_FS_BLEGSTART "Other-Leg-Channel-Created-Time" /* Usage B-leg start time */ #define OSP_FS_SIPRELEASE "sip_hangup_disposition" /* Usage SIP release source */ #define OSP_FS_SRCCODEC "write_codec" /* Usage source codec */ -#define OSP_FS_DESTCODEC "read_codec" /* Usage destiantion codec */ -#define OSP_FS_RTPSRCREPOCTS "rtp_audio_out_media_bytes" /* Usage source->reporter octets */ -#define OSP_FS_RTPDESTREPOCTS "rtp_audio_in_media_bytes" /* Usage destination->reporter octets */ -#define OSP_FS_RTPSRCREPPKTS "rtp_audio_out_media_packet_count" /* Usage source->reporter packets */ -#define OSP_FS_RTPDESTREPPKTS "rtp_audio_in_media_packet_count" /* Usage destination->reporter packets */ -#define OSP_FS_HANGUPCAUSE "last_bridge_hangup_cause" /* Termination cause */ +#define OSP_FS_DESTCODEC "read_codec" /* Usage destination codec */ +#define OSP_FS_SRCSDP SWITCH_R_SDP_VARIABLE /* Usage source SDP */ +#define OSP_FS_DESTSDP SWITCH_B_SDP_VARIABLE /* Usage destination SDP */ +#define OSP_FS_RTPINOCTS "rtp_audio_in_media_bytes" /* Usage in octets (A-leg downstream or B-leg upstream) */ +#define OSP_FS_RTPINPKTS "rtp_audio_in_media_packet_count" /* Usage in packets (A-leg downstream or B-leg upstream)*/ /* FreeSWITCH Endpoint Parameters */ typedef struct osp_endpoint { @@ -158,7 +173,8 @@ typedef enum osp_workmode { /* OSP Service Types */ typedef enum osp_srvtype { OSP_SRV_VOICE = 0, /* Normal voice service */ - OSP_SRV_NPQUERY /* Number portability query service */ + OSP_SRV_NPQUERY, /* Number portability query service */ + OSP_SRV_CNAMQUERY /* CNAM query service */ } osp_srvtype_t; /* OSP Profile Parameters */ @@ -194,11 +210,13 @@ typedef struct osp_inbound { int npdi; /* Inbound NP database dip indicator */ const char *tohost; /* Inbound host of To URI */ const char *toport; /* Inbound port of To URI */ + const char *fromdisplay; /* Inbound display name of From header */ char rpiduser[OSP_SIZE_NORSTR]; /* Inbound user of SIP Remote-Party-ID header */ char paiuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP P-Asserted-Identity header */ + char pciuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP P-Charge-Info header */ char divuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP Diversion header */ char divhost[OSP_SIZE_NORSTR]; /* Inbound hostport of SIP Diversion header */ - char pciuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP P-Charge-Info header */ + const char *useragent; /* Inbound User-Agent header */ const char *cinfo[OSP_MAX_CINFO]; /* Custom info */ } osp_inbound_t; @@ -218,6 +236,7 @@ typedef struct osp_results { char npcic[OSP_SIZE_NORSTR]; /* Outbound NP carrier identification code */ int npdi; /* Outbound NP database dip indicator */ char opname[OSPC_OPNAME_NUMBER][OSP_SIZE_NORSTR]; /* Outbound Operator names */ + char cnam[OSP_SIZE_NORSTR]; /* CNAM */ OSPE_PROTOCOL_NAME protocol; /* Signaling protocol */ switch_bool_t supported; /* Supported by FreeRADIUS OSP module */ switch_call_cause_t cause; /* Termination cause for current destination */ @@ -227,33 +246,52 @@ typedef struct osp_results { typedef struct osp_outbound { const char *dniduserparam; /* Destination network ID user parameter name */ const char *dniduriparam; /* Destination network ID URI parameter name */ + const char *outuserparam; /* Fixed outbound parameter string user parameter */ + const char *outuriparam; /* Fixed outbound parameter string URI parameter */ switch_bool_t userphone; /* If to add "user=phone" parameter */ const char *outproxy; /* Outbound proxy IP address */ } osp_outbound_t; /* OSP Usage Parameters */ typedef struct osp_usage { - OSPE_RELEASE release; /* Release source */ - switch_call_cause_t cause; /* Termination cause */ - switch_time_t start; /* Call start time */ - switch_time_t alert; /* Call alert time */ - switch_time_t connect; /* Call answer time */ - switch_time_t end; /* Call end time */ - switch_time_t duration; /* Call duration */ - switch_time_t pdd; /* Post dial delay, in us */ - const char *srccodec; /* Source codec */ - const char *destcodec; /* Destination codec */ - int rtpsrcrepoctets; /* RTP source->reporter bytes */ - int rtpdestrepoctets; /* RTP destination->reporter bytes */ - int rtpsrcreppackets; /* RTP source->reporter packets */ - int rtpdestreppackets; /* RTP destiantion->reporter packets */ + OSPE_RELEASE release; /* Release source */ + switch_call_cause_t cause; /* Termination cause */ + switch_time_t start; /* Call start time */ + switch_time_t alert; /* Call alert time */ + switch_time_t connect; /* Call answer time */ + switch_time_t end; /* Call end time */ + switch_time_t duration; /* Call duration */ + switch_time_t pdd; /* Post dial delay, in us */ + switch_time_t pstart; /* Provider call start time */ + switch_time_t ppdd; /* Provider post dial delay, in us */ + const char *localip; /* FreeSWITCH local signal address */ + char srcmediaip[OSP_SIZE_NORSTR]; /* Source media IP */ + char destmediaip[OSP_SIZE_NORSTR]; /* Source media IP */ + const char *srccodec; /* Source codec */ + const char *destcodec; /* Destination codec */ + int rtpsrcrepoctets; /* RTP source->reporter bytes */ + int rtpsrcreppackets; /* RTP source->reporter packets */ } osp_usage_t; -/* Macro functions for debug */ -#define OSP_DEBUG(_fmt, ...) if (osp_global.debug) { switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__); } -#define OSP_DEBUG_MSG(_msg) OSP_DEBUG("%s", _msg) -#define OSP_DEBUG_START OSP_DEBUG_MSG("Start") -#define OSP_DEBUG_END OSP_DEBUG_MSG("End") +/* Macro functions for log */ +/* Normal log */ +#define OSP_DEBUG(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_INFO(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_NOTICE(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_WARN(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_ERROR(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_CRIT(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_ALERT(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +/* Normal OSP log */ +#define OSP_LOG(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +/* OSP debug log */ +#define OSP_TEST(_fmt, ...) if (osp_global.debug) { switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__); } +#define OSP_TEST_MSG(_msg) OSP_TEST("%s", _msg) +#define OSP_TEST_START OSP_TEST_MSG("Start") +#define OSP_TEST_END OSP_TEST_MSG("End") +/* OSP develop log */ +#define OSP_DEV(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) + /* Macro to prevent NULL string */ #define OSP_FILTER_NULLSTR(_str) (switch_strlen_zero(_str) ? OSP_DEF_STRING : (_str)) /* Macro to prevent NULL integer */ @@ -285,7 +323,7 @@ static switch_status_t osp_find_profile( osp_profile_t *p; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; if (name) { if (profile) { @@ -304,12 +342,12 @@ static switch_status_t osp_find_profile( } if (status == SWITCH_STATUS_SUCCESS) { - OSP_DEBUG("Found profile '%s'", name); + OSP_TEST("Found profile '%s'", name); } else { - OSP_DEBUG("Unable to find profile '%s'", name); + OSP_TEST("Unable to find profile '%s'", name); } - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -331,16 +369,16 @@ static switch_status_t osp_load_config( int number; switch_status_t status = SWITCH_STATUS_SUCCESS; - OSP_DEBUG_START; + OSP_TEST_START; /* Load OSP module configuration file */ if (!(xml = switch_xml_open_cfg(OSP_CONFIG_FILE, &xcfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open OSP module configuration file '%s'\n", OSP_CONFIG_FILE); - OSP_DEBUG_END; + OSP_ERROR("Failed to open OSP module configuration file '%s'", OSP_CONFIG_FILE); + OSP_TEST_END; return SWITCH_STATUS_FALSE; } - OSP_DEBUG_MSG("Parsing settings"); + OSP_TEST_MSG("Parsing settings"); /* Init OSP module global status */ memset(&osp_global, 0, sizeof(osp_global)); @@ -370,7 +408,7 @@ static switch_status_t osp_load_config( if (!switch_strlen_zero(value)) { osp_global.debug = switch_true(value); } - OSP_DEBUG("debug-info: '%d'", osp_global.debug); + OSP_TEST("debug-info: '%d'", osp_global.debug); } else if (!strcasecmp(name, "log-level")) { /* OSP module debug message log level */ if (switch_strlen_zero(value)) { @@ -392,13 +430,13 @@ static switch_status_t osp_load_config( } else if (!strcasecmp(value, "debug")) { osp_global.loglevel = SWITCH_LOG_DEBUG; } - OSP_DEBUG("log-level: '%d'", osp_global.loglevel); + OSP_TEST("log-level: '%d'", osp_global.loglevel); } else if (!strcasecmp(name, "crypto-hardware")) { /* OSP module crypto hardware flag */ if (!switch_strlen_zero(value)) { osp_global.hardware = switch_true(value); } - OSP_DEBUG("crypto-hardware: '%d'", osp_global.hardware); + OSP_TEST("crypto-hardware: '%d'", osp_global.hardware); } else if (!strcasecmp(name, "default-protocol")) { /* OSP module default signaling protocol */ if (switch_strlen_zero(value)) { @@ -412,14 +450,14 @@ static switch_status_t osp_load_config( } else if (!strcasecmp(value, OSP_PROTOCOL_SKYPE)) { osp_global.protocol = OSPC_PROTNAME_SKYPE; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported protocol '%s'\n", value); + OSP_WARN("Unsupported protocol '%s'", value); } - OSP_DEBUG("default-protocol: '%d'", osp_global.protocol); + OSP_TEST("default-protocol: '%d'", osp_global.protocol); } else if (!strcasecmp(name, OSP_PROTOCOL_SIP)) { /* SIP endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SIP].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate SIP module name\n"); + OSP_CRIT("%s", "Failed to duplicate SIP module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -427,17 +465,17 @@ static switch_status_t osp_load_config( /* SIP endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SIP].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate SIP profile name\n"); + OSP_CRIT("%s", "Failed to duplicate SIP profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("SIP: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile); + OSP_TEST("SIP: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile); } else if (!strcasecmp(name, OSP_PROTOCOL_H323)) { /* H.323 endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_Q931].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate H.323 module name\n"); + OSP_CRIT("%s", "Failed to duplicate H.323 module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -445,17 +483,17 @@ static switch_status_t osp_load_config( /* H.323 endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_Q931].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate H.323 profile name\n"); + OSP_CRIT("%s", "Failed to duplicate H.323 profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("H.323: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_Q931].module, osp_global.endpoint[OSPC_PROTNAME_Q931].profile); + OSP_TEST("H.323: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_Q931].module, osp_global.endpoint[OSPC_PROTNAME_Q931].profile); } else if (!strcasecmp(name, OSP_PROTOCOL_IAX)) { /* IAX endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_IAX].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate IAX module name\n"); + OSP_CRIT("%s", "Failed to duplicate IAX module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -463,17 +501,17 @@ static switch_status_t osp_load_config( /* IAX endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_IAX].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate IAX profile name\n"); + OSP_CRIT("%s", "Failed to duplicate IAX profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("IAX: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_IAX].module, osp_global.endpoint[OSPC_PROTNAME_IAX].profile); + OSP_TEST("IAX: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_IAX].module, osp_global.endpoint[OSPC_PROTNAME_IAX].profile); } else if (!strcasecmp(name, OSP_PROTOCOL_SKYPE)) { /* Skype endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SKYPE].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate Skype module name\n"); + OSP_CRIT("%s", "Failed to duplicate Skype module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -481,14 +519,14 @@ static switch_status_t osp_load_config( /* Skype endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SKYPE].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate Skype profile name\n"); + OSP_CRIT("%s", "Failed to duplicate Skype profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("SKYPE: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SKYPE].module, osp_global.endpoint[OSPC_PROTNAME_SKYPE].profile); + OSP_TEST("SKYPE: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SKYPE].module, osp_global.endpoint[OSPC_PROTNAME_SKYPE].profile); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter '%s'\n", name); + OSP_WARN("Unknown parameter '%s'", name); } } } @@ -496,7 +534,7 @@ static switch_status_t osp_load_config( if (status != SWITCH_STATUS_SUCCESS) { /* Fail for SWITCH_STATUS_MEMERR */ switch_xml_free(xml); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -508,24 +546,24 @@ static switch_status_t osp_load_config( if (switch_strlen_zero(name)) { name = OSP_DEF_PROFILE; } - OSP_DEBUG("Parsing profile '%s'", name); + OSP_TEST("Parsing profile '%s'", name); - /* Check duplate profile name */ + /* Check duplicate profile name */ if (osp_find_profile(name, NULL) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored duplicate profile '%s'\n", name); + OSP_WARN("Ignored duplicate profile '%s'", name); continue; } /* Allocate profile */ if (!(profile = switch_core_alloc(osp_global.pool, sizeof(*profile)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to alloc profile\n"); + OSP_CRIT("%s", "Failed to allocate profile"); status = SWITCH_STATUS_MEMERR; break; } /* Store profile name */ if (!(profile->name = switch_core_strdup(osp_global.pool, name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate profile name\n"); + OSP_CRIT("%s", "Failed to duplicate profile name"); status = SWITCH_STATUS_MEMERR; /* "profile" cannot free to pool in FreeSWITCH */ break; @@ -556,63 +594,63 @@ static switch_status_t osp_load_config( /* OSP service point URL */ if (profile->spnumber < OSP_MAX_SPNUMBER) { profile->spurl[profile->spnumber] = switch_core_strdup(osp_global.pool, value); - OSP_DEBUG("service-point-url[%d]: '%s'", profile->spnumber, profile->spurl[profile->spnumber]); + OSP_TEST("service-point-url[%d]: '%s'", profile->spnumber, profile->spurl[profile->spnumber]); profile->spnumber++; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored service point '%s'\n", value); + OSP_WARN("Ignored service point '%s'", value); } } else if (!strcasecmp(name, "device-ip")) { /* OSP client end IP */ profile->deviceip = switch_core_strdup(osp_global.pool, value); - OSP_DEBUG("device-ip: '%s'", profile->deviceip); + OSP_TEST("device-ip: '%s'", profile->deviceip); } else if (!strcasecmp(name, "ssl-lifetime")) { /* SSL lifetime */ if (sscanf(value, "%d", &number) == 1) { profile->lifetime = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ssl-lifetime must be a number\n"); + OSP_WARN("%s", "ssl-lifetime must be a number"); } - OSP_DEBUG("ssl-lifetime: '%d'", profile->lifetime); + OSP_TEST("ssl-lifetime: '%d'", profile->lifetime); } else if (!strcasecmp(name, "http-max-connections")) { /* HTTP max connections */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_MAXCONN) && (number <= OSP_MAX_MAXCONN)) { profile->maxconnect = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-max-connections must be between %d and %d\n", OSP_MIN_MAXCONN, OSP_MAX_MAXCONN); + OSP_WARN("http-max-connections must be between %d and %d", OSP_MIN_MAXCONN, OSP_MAX_MAXCONN); } - OSP_DEBUG("http-max-connections: '%d'", profile->maxconnect); + OSP_TEST("http-max-connections: '%d'", profile->maxconnect); } else if (!strcasecmp(name, "http-persistence")) { /* HTTP persistence */ if (sscanf(value, "%d", &number) == 1) { profile->persistence = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-persistence must be a number\n"); + OSP_WARN("%s", "http-persistence must be a number"); } - OSP_DEBUG("http-persistence: '%d'", profile->persistence); + OSP_TEST("http-persistence: '%d'", profile->persistence); } else if (!strcasecmp(name, "http-retry-delay")) { /* HTTP retry delay */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_RETRYDELAY) && (number <= OSP_MAX_RETRYDELAY)) { profile->retrydelay = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-retry-delay must be between %d and %d\n", OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY); + OSP_WARN("http-retry-delay must be between %d and %d", OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY); } - OSP_DEBUG("http-retry-delay: '%d'", profile->retrydelay); + OSP_TEST("http-retry-delay: '%d'", profile->retrydelay); } else if (!strcasecmp(name, "http-retry-limit")) { /* HTTP retry limit */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_RETRYLIMIT) && (number <= OSP_MAX_RETRYLIMIT)) { profile->retrylimit = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-retry-limit must be between %d and %d\n", OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT); + OSP_WARN("http-retry-limit must be between %d and %d", OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT); } - OSP_DEBUG("http-retry-limit: '%d'", profile->retrylimit); + OSP_TEST("http-retry-limit: '%d'", profile->retrylimit); } else if (!strcasecmp(name, "http-timeout")) { /* HTTP timeout value */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_TIMEOUT) && (number <= OSP_MAX_TIMEOUT)) { profile->timeout = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-timeout must be between %d and %d\n", OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT); + OSP_WARN("http-timeout must be between %d and %d", OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT); } - OSP_DEBUG("http-timeout: '%d'", profile->timeout); + OSP_TEST("http-timeout: '%d'", profile->timeout); } else if (!strcasecmp(name, "work-mode")) { /* OSP work mode */ if (!strcasecmp(value, "direct")) { @@ -620,35 +658,39 @@ static switch_status_t osp_load_config( } else if (!strcasecmp(value, "indirect")) { profile->workmode = OSP_MODE_INDIRECT; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown work mode '%s'\n", value); + OSP_WARN("Unknown work mode '%s'", value); } - OSP_DEBUG("work-mode: '%d'", profile->workmode); + OSP_TEST("work-mode: '%d'", profile->workmode); } else if (!strcasecmp(name, "service-type")) { /* OSP service type */ if (!strcasecmp(value, "voice")) { profile->srvtype = OSP_SRV_VOICE; } else if (!strcasecmp(value, "npquery")) { profile->srvtype = OSP_SRV_NPQUERY; + } else if (!strcasecmp(value, "cnamquery")) { + // Have not been implemented + // profile->srvtype = OSP_SRV_CNAMQUERY; + OSP_WARN("Unsupported service type '%s'", value); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown service type '%s'\n", value); + OSP_WARN("Unknown service type '%s'", value); } - OSP_DEBUG("service-type: '%d'", profile->srvtype); + OSP_TEST("service-type: '%d'", profile->srvtype); } else if (!strcasecmp(name, "max-destinations")) { /* Max destinations */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_MAXDEST) && (number <= OSP_MAX_MAXDEST)) { profile->maxdest = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "max-destinations must be between %d and %d\n", OSP_MIN_MAXDEST, OSP_MAX_MAXDEST); + OSP_WARN("max-destinations must be between %d and %d", OSP_MIN_MAXDEST, OSP_MAX_MAXDEST); } - OSP_DEBUG("max-destinations: '%d'", profile->maxdest); + OSP_TEST("max-destinations: '%d'", profile->maxdest); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter '%s'\n", name); + OSP_WARN("Unknown parameter '%s'", name); } } - /* Check number of service porints */ + /* Check number of service points */ if (!profile->spnumber) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Without service point URI in profile '%s'\n", profile->name); + OSP_WARN("Without service point URI in profile '%s'", profile->name); /* "profile" cannot free to pool in FreeSWITCH */ continue; } @@ -660,7 +702,7 @@ static switch_status_t osp_load_config( switch_xml_free(xml); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -681,13 +723,13 @@ static void osp_init_osptk(void) unsigned char cacertdata[OSP_SIZE_KEYSTR]; int error; - OSP_DEBUG_START; + OSP_TEST_START; /* Init OSP Toolkit */ if (osp_global.hardware) { if ((error = OSPPInit(OSPC_TRUE)) != OSPC_ERR_NO_ERROR) { /* Unable to enable crypto hardware, disable it */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to enable crypto hardware, error '%d'\n", error); + OSP_WARN("Unable to enable crypto hardware, error '%d'", error); osp_global.hardware = SWITCH_FALSE; OSPPInit(OSPC_FALSE); } @@ -708,11 +750,11 @@ static void osp_init_osptk(void) cacert.CertDataLength = sizeof(cacertdata); if ((error = OSPPBase64Decode(B64PKey, strlen(B64PKey), privatekey.PrivateKeyData, &privatekey.PrivateKeyLength)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to decode private key, error '%d'\n", error); + OSP_WARN("Unable to decode private key, error '%d'", error); } else if ((error = OSPPBase64Decode(B64LCert, strlen(B64LCert), localcert.CertData, &localcert.CertDataLength)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to decode local cert, error '%d'\n", error); + OSP_WARN("Unable to decode local cert, error '%d'", error); } else if ((error = OSPPBase64Decode(B64CACert, strlen(B64CACert), cacert.CertData, &cacert.CertDataLength)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to decode cacert, error '%d'\n", error); + OSP_WARN("Unable to decode cacert, error '%d'", error); } if (error == OSPC_ERR_NO_ERROR) { @@ -722,7 +764,7 @@ static void osp_init_osptk(void) profile->spurl, /* Service point URLs */ NULL, /* Weights */ OSP_AUDIT_URL, /* Audit URL */ - &privatekey, /* Provate key */ + &privatekey, /* Private key */ &localcert, /* Local cert */ 1, /* Number of cacerts */ &pcacert, /* cacerts */ @@ -737,15 +779,15 @@ static void osp_init_osptk(void) OSP_DEVICE_ID, /* Device ID */ &profile->provider); /* Provider handle */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to create provider for profile %s, error '%d'\n", profile->name, error); + OSP_WARN("Unable to create provider for profile %s, error '%d'", profile->name, error); profile->provider = OSP_INVALID_HANDLE; } else { - OSP_DEBUG("Created provider handle for profile '%s'", profile->name); + OSP_TEST("Created provider handle for profile '%s'", profile->name); } } } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -756,21 +798,21 @@ static void osp_cleanup_osptk(void) { osp_profile_t *profile; - OSP_DEBUG_START; + OSP_TEST_START; for (profile = osp_profiles; profile; profile = profile->next) { if (profile->provider != OSP_INVALID_HANDLE) { /* Delete provider handle */ OSPPProviderDelete(profile->provider, 0); profile->provider = OSP_INVALID_HANDLE; - OSP_DEBUG("Deleted provider handle for profile '%s'", profile->name); + OSP_TEST("Deleted provider handle for profile '%s'", profile->name); } } /* Cleanup OSP Toolkit */ OSPPCleanup(); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -783,7 +825,7 @@ static const char *osp_get_protocolname( { const char *name; - OSP_DEBUG_START; + OSP_TEST_START; switch (protocol) { case OSPC_PROTNAME_UNKNOWN: @@ -814,9 +856,9 @@ static const char *osp_get_protocolname( name = OSP_PROTOCOL_UNSUP; break; } - OSP_DEBUG("Protocol %d: '%s'", protocol, name); + OSP_TEST("Protocol %d: '%s'", protocol, name); - OSP_DEBUG_END; + OSP_TEST_END; return name; } @@ -831,7 +873,7 @@ static OSPE_PROTOCOL_NAME osp_get_protocol( { OSPE_PROTOCOL_NAME protocol; - OSP_DEBUG_START; + OSP_TEST_START; if (!strcasecmp(module, OSP_MODULE_SIP)) { protocol = OSPC_PROTNAME_SIP; @@ -844,9 +886,9 @@ static OSPE_PROTOCOL_NAME osp_get_protocol( } else { protocol = OSPC_PROTNAME_UNKNOWN; } - OSP_DEBUG("Module %s: '%d'", module, protocol); + OSP_TEST("Module %s: '%d'", module, protocol); - OSP_DEBUG_END; + OSP_TEST_END; return protocol; } @@ -877,7 +919,7 @@ static void osp_parse_userinfo( char *item; char *tmp; - OSP_DEBUG_START; + OSP_TEST_START; /* Set default values */ if (user && usersize) { @@ -925,12 +967,12 @@ static void osp_parse_userinfo( } } - OSP_DEBUG("user: '%s'", OSP_FILTER_NULLSTR(user)); - OSP_DEBUG("rn: '%s'", OSP_FILTER_NULLSTR(rn)); - OSP_DEBUG("cic: '%s'", OSP_FILTER_NULLSTR(cic)); - OSP_DEBUG("npdi: '%d'", OSP_FILTER_NULLINT(npdi)); + OSP_TEST("user: '%s'", OSP_FILTER_NULLSTR(user)); + OSP_TEST("rn: '%s'", OSP_FILTER_NULLSTR(rn)); + OSP_TEST("cic: '%s'", OSP_FILTER_NULLSTR(cic)); + OSP_TEST("npdi: '%d'", OSP_FILTER_NULLINT(npdi)); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -950,7 +992,7 @@ static void osp_parse_header_user( char *tmp; char *item; - OSP_DEBUG_START; + OSP_TEST_START; if (user && usersize) { user[0] = '\0'; @@ -970,10 +1012,10 @@ static void osp_parse_header_user( } } - OSP_DEBUG("user: '%s'", user); + OSP_TEST("user: '%s'", user); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -992,7 +1034,7 @@ static void osp_parse_header_host( char *head; char *tmp; - OSP_DEBUG_START; + OSP_TEST_START; if (hostsize) { host[0] = '\0'; @@ -1012,10 +1054,10 @@ static void osp_parse_header_host( } } - OSP_DEBUG("host: '%s'", host); + OSP_TEST("host: '%s'", host); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1034,7 +1076,7 @@ static void osp_convert_inout( char buffer[OSP_SIZE_NORSTR]; char *port; - OSP_DEBUG_START; + OSP_TEST_START; if (dest && destsize) { dest[0] = '\0'; @@ -1054,16 +1096,15 @@ static void osp_convert_inout( } else { switch_snprintf(dest, destsize, "[%s]", buffer); } - dest[destsize - 1] = '\0'; } else { switch_copy_string(dest, src, destsize); } } - OSP_DEBUG("out: '%s'", dest); + OSP_TEST("out: '%s'", dest); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1082,7 +1123,7 @@ static void osp_convert_outin( char *end; char *port; - OSP_DEBUG_START; + OSP_TEST_START; if (dest && destsize) { dest[0] = '\0'; @@ -1102,7 +1143,6 @@ static void osp_convert_outin( if (port) { switch_snprintf(dest, destsize, "%s:%s", buffer + 1, port); - dest[destsize - 1] = '\0'; } else { switch_copy_string(dest, buffer + 1, destsize); } @@ -1110,10 +1150,52 @@ static void osp_convert_outin( switch_copy_string(dest, src, destsize); } } - OSP_DEBUG("in: '%s'", dest); + OSP_TEST("in: '%s'", dest); } - OSP_DEBUG_END; + OSP_TEST_END; +} + +/* + * Get SDP connection IP + * param sdp SDP string + */ +static void osp_get_mediaip( + const char *sdp, + char *ip, + int ipsize) +{ + char *start; + char *end; + int size; + + OSP_TEST_START; + + if (ip && ipsize) { + ip[0] = '\0'; + + if (!switch_strlen_zero(sdp)) { + start = strstr(sdp, OSP_SDP_CHEADER); + if (start) { + start += OSP_CHEADER_SIZE; + end = strchr(start, OSP_SDP_DELIM); + if (end) { + size = end - start + 1; + } else { + size = ipsize; + } + switch_snprintf(ip, size, "%s", start); + + end = strchr(ip, OSP_IP_DELIM); + if (end) { + *end = '\0'; + } + } + } + OSP_TEST("ip: '%s'", ip); + } + + OSP_TEST_END; } /* @@ -1132,7 +1214,7 @@ static void osp_log_authreq( char term[OSP_SIZE_NORSTR]; int total; - OSP_DEBUG_START; + OSP_TEST_START; /* Get source device and source */ if (profile->workmode == OSP_MODE_INDIRECT) { @@ -1147,9 +1229,11 @@ static void osp_log_authreq( srcdev = inbound->srcdev; } - /* Get preferred destination for NP query */ - if (profile->srvtype == OSP_SRV_NPQUERY) { - srvtype = "npquery"; + /* Get preferred destination for NP/CNAM query */ + switch (profile->srvtype) { + case OSP_SRV_NPQUERY: + case OSP_SRV_CNAMQUERY: + srvtype = (profile->srvtype == OSP_SRV_NPQUERY) ? "npquery" : "cnamquery"; if (switch_strlen_zero(inbound->tohost)) { switch_copy_string(term, source, sizeof(term)); } else { @@ -1160,13 +1244,16 @@ static void osp_log_authreq( } } total = 1; - } else { + break; + case OSP_SRV_VOICE: + default: srvtype = "voice"; term[0] = '\0'; total = profile->maxdest; + break; } - switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, + OSP_LOG( "AuthReq: " "srvtype '%s' " "source '%s' " @@ -1178,12 +1265,14 @@ static void osp_log_authreq( "called '%s' " "lnp '%s/%s/%d' " "preferred '%s' " + "fromdisplay '%s' " "rpid '%s' " "pai '%s' " - "div '%s/%s' " "pci '%s' " + "div '%s/%s' " + "useragent '%s' " "cinfo '%s/%s/%s/%s/%s/%s/%s/%s' " - "maxcount '%d'\n", + "maxcount '%d'", srvtype, source, srcdev, @@ -1194,15 +1283,17 @@ static void osp_log_authreq( inbound->called, inbound->nprn, inbound->npcic, inbound->npdi, term, + OSP_FILTER_NULLSTR(inbound->fromdisplay), inbound->rpiduser, inbound->paiuser, - inbound->divuser, inbound->divhost, inbound->pciuser, + inbound->divuser, inbound->divhost, + OSP_FILTER_NULLSTR(inbound->useragent), OSP_FILTER_NULLSTR(inbound->cinfo[0]), OSP_FILTER_NULLSTR(inbound->cinfo[1]), OSP_FILTER_NULLSTR(inbound->cinfo[2]), OSP_FILTER_NULLSTR(inbound->cinfo[3]), OSP_FILTER_NULLSTR(inbound->cinfo[4]), OSP_FILTER_NULLSTR(inbound->cinfo[5]), OSP_FILTER_NULLSTR(inbound->cinfo[6]), OSP_FILTER_NULLSTR(inbound->cinfo[7]), total); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1213,9 +1304,9 @@ static void osp_log_authreq( static void osp_log_authrsp( osp_results_t *results) { - OSP_DEBUG_START; + OSP_TEST_START; - switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, + OSP_LOG( "AuthRsp: " "destcount '%d/%d' " "transid '%"PRIu64"' " @@ -1225,8 +1316,9 @@ static void osp_log_authrsp( "destination '%s' " "destnid '%s' " "lnp '%s/%s/%d' " + "cnam '%s' " "protocol '%s' " - "supported '%d'\n", + "supported '%d'", results->count, results->total, results->transid, @@ -1236,14 +1328,15 @@ static void osp_log_authrsp( results->dest, results->destnid, results->nprn, results->npcic, results->npdi, + results->cnam, osp_get_protocolname(results->protocol), results->supported); - OSP_DEBUG_END; + OSP_TEST_END; } /* - * Alway log UsageInd parameters + * Always log UsageInd parameters * param results Route info * param usage Usage info * return @@ -1252,32 +1345,34 @@ static void osp_log_usageind( osp_results_t *results, osp_usage_t *usage) { - OSP_DEBUG_START; + OSP_TEST_START; - switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, + OSP_LOG( "UsageInd: " "destcount '%d/%d' " "transid '%"PRIu64"' " "cause '%d' " "release '%d' " - "times '%"PRId64"/%"PRId64"/%"PRId64"/%"PRId64"' " + "times '%"PRId64"/%"PRId64"/%"PRId64"/%"PRId64"/%"PRId64"' " "duration '%"PRId64"' " - "pdd '%"PRId64"' " + "pdd '%"PRId64"/%"PRId64"' " + "mediaip '%s/%s' " "codec '%s/%s' " - "rtpctets '%d/%d' " - "rtppackets '%d/%d'\n", + "rtpctets '%d' " + "rtppackets '%d'", results->count, results->total, results->transid, results->cause ? results->cause : usage->cause, usage->release, - usage->start / 1000000, usage->alert / 1000000, usage->connect / 1000000, usage->end / 1000000, + usage->start / 1000000, usage->pstart / 1000000, usage->alert / 1000000, usage->connect / 1000000, usage->end / 1000000, usage->duration / 1000000, - usage->pdd / 1000, + usage->pdd / 1000, usage->ppdd / 1000, + usage->srcmediaip, usage->destmediaip, OSP_FILTER_NULLSTR(usage->srccodec), OSP_FILTER_NULLSTR(usage->destcodec), - usage->rtpsrcrepoctets, usage->rtpdestrepoctets, - usage->rtpsrcreppackets, usage->rtpdestreppackets); + usage->rtpsrcrepoctets, + usage->rtpsrcreppackets); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1295,33 +1390,34 @@ static void osp_get_inbound( int i; char name[OSP_SIZE_NORSTR]; - OSP_DEBUG_START; + OSP_TEST_START; /* Cleanup buffer */ memset(inbound, 0, sizeof(*inbound)); + inbound->protocol = OSPC_PROTNAME_UNKNOWN; /* Get caller profile */ caller = switch_channel_get_caller_profile(channel); /* osp_source_device */ inbound->actsrc = switch_channel_get_variable(channel, OSP_VAR_SRCDEV); - OSP_DEBUG("actsrc: '%s'", OSP_FILTER_NULLSTR(inbound->actsrc)); + OSP_TEST("actsrc: '%s'", OSP_FILTER_NULLSTR(inbound->actsrc)); /* Source device */ inbound->srcdev = caller->network_addr; - OSP_DEBUG("srcdev: '%s'", OSP_FILTER_NULLSTR(inbound->srcdev)); + OSP_TEST("srcdev: '%s'", OSP_FILTER_NULLSTR(inbound->srcdev)); /* osp_source_nid */ inbound->srcnid = switch_channel_get_variable(channel, OSP_VAR_SRCNID); - OSP_DEBUG("srcnid: '%s'", OSP_FILTER_NULLSTR(inbound->srcnid)); + OSP_TEST("srcnid: '%s'", OSP_FILTER_NULLSTR(inbound->srcnid)); /* Source signaling protocol */ inbound->protocol = osp_get_protocol(caller->source); - OSP_DEBUG("protocol: '%d'", inbound->protocol); + OSP_TEST("protocol: '%d'", inbound->protocol); /* Call-ID */ inbound->callid = switch_channel_get_variable(channel, OSP_FS_CALLID); - OSP_DEBUG("callid: '%s'", OSP_FILTER_NULLSTR(inbound->callid)); + OSP_TEST("callid: '%s'", OSP_FILTER_NULLSTR(inbound->callid)); /* Calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_FROMUSER))) { @@ -1329,56 +1425,64 @@ static void osp_get_inbound( } else { osp_parse_userinfo(caller->caller_id_number, inbound->calling, sizeof(inbound->calling), NULL, 0, NULL, 0, NULL); } - OSP_DEBUG("calling: '%s'", inbound->calling); + OSP_TEST("calling: '%s'", inbound->calling); /* Called number and LNP parameters */ osp_parse_userinfo(caller->destination_number, inbound->called, sizeof(inbound->called), inbound->nprn, sizeof(inbound->nprn), inbound->npcic, sizeof(inbound->npcic), &inbound->npdi); - OSP_DEBUG("called: '%s'", inbound->called); - OSP_DEBUG("nprn: '%s'", inbound->nprn); - OSP_DEBUG("npcic: '%s'", inbound->npcic); - OSP_DEBUG("npdi: '%d'", inbound->npdi); + OSP_TEST("called: '%s'", inbound->called); + OSP_TEST("nprn: '%s'", inbound->nprn); + OSP_TEST("npcic: '%s'", inbound->npcic); + OSP_TEST("npdi: '%d'", inbound->npdi); /* To header */ inbound->tohost = switch_channel_get_variable(channel, OSP_FS_TOHOST); - OSP_DEBUG("tohost: '%s'", OSP_FILTER_NULLSTR(inbound->tohost)); + OSP_TEST("tohost: '%s'", OSP_FILTER_NULLSTR(inbound->tohost)); inbound->toport = switch_channel_get_variable(channel, OSP_FS_TOPORT); - OSP_DEBUG("toport: '%s'", OSP_FILTER_NULLSTR(inbound->toport)); + OSP_TEST("toport: '%s'", OSP_FILTER_NULLSTR(inbound->toport)); + + /* From header display name */ + inbound->fromdisplay = switch_channel_get_variable(channel, OSP_FS_FROMDISPLAY); + OSP_TEST("FROM display: '%s'", OSP_FILTER_NULLSTR(inbound->fromdisplay)); /* RPID calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_RPID))) { osp_parse_header_user(tmp, inbound->rpiduser, sizeof(inbound->rpiduser)); } - OSP_DEBUG("RPID user: '%s'", inbound->rpiduser); + OSP_TEST("RPID user: '%s'", inbound->rpiduser); /* PAI calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_PAI))) { osp_parse_userinfo(tmp, inbound->paiuser, sizeof(inbound->paiuser), NULL, 0, NULL, 0, NULL); } - OSP_DEBUG("PAI user: '%s'", inbound->paiuser); + OSP_TEST("PAI user: '%s'", inbound->paiuser); + + /* PCI calling number */ + if ((tmp = switch_channel_get_variable(channel, OSP_FS_PCI))) { + osp_parse_header_user(tmp, inbound->pciuser, sizeof(inbound->pciuser)); + } + OSP_TEST("PCI user: '%s'", inbound->pciuser); /* DIV calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_DIV))) { osp_parse_header_user(tmp, inbound->divuser, sizeof(inbound->divuser)); osp_parse_header_host(tmp, inbound->divhost, sizeof(inbound->divhost)); } - OSP_DEBUG("DIV user: '%s'", inbound->divuser); - OSP_DEBUG("DIV host: '%s'", inbound->divhost); + OSP_TEST("DIV user: '%s'", inbound->divuser); + OSP_TEST("DIV host: '%s'", inbound->divhost); - /* PCI calling number */ - if ((tmp = switch_channel_get_variable(channel, OSP_FS_PCI))) { - osp_parse_header_user(tmp, inbound->pciuser, sizeof(inbound->pciuser)); - } - OSP_DEBUG("PCI user: '%s'", inbound->pciuser); + /* User-Agent header */ + inbound->useragent = switch_channel_get_variable(channel, OSP_FS_USERAGENT); + OSP_TEST("User-Agent: '%s'", OSP_FILTER_NULLSTR(inbound->useragent)); /* Custom info */ for (i = 0; i < OSP_MAX_CINFO; i++) { switch_snprintf(name, sizeof(name), "%s%d", OSP_VAR_CUSTOMINFO, i + 1); inbound->cinfo[i] = switch_channel_get_variable(channel, name); - OSP_DEBUG("cinfo[%d]: '%s'", i, OSP_FILTER_NULLSTR(inbound->cinfo[i])); + OSP_TEST("cinfo[%d]: '%s'", i, OSP_FILTER_NULLSTR(inbound->cinfo[i])); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1393,29 +1497,35 @@ static void osp_get_outbound( { const char *tmp; - OSP_DEBUG_START; + OSP_TEST_START; /* Cleanup buffer */ memset(outbound, 0, sizeof(*outbound)); - /* Get destination network ID namd & location info */ + /* Get destination network ID name & location info */ outbound->dniduserparam = switch_channel_get_variable(channel, OSP_VAR_DNIDUSERPARAM); - OSP_DEBUG("dniduserparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduserparam)); + OSP_TEST("dniduserparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduserparam)); outbound->dniduriparam = switch_channel_get_variable(channel, OSP_VAR_DNIDURIPARAM); - OSP_DEBUG("dniduriparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduriparam)); + OSP_TEST("dniduriparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduriparam)); + + /* Get fixed outbound parameter string & location info */ + outbound->outuserparam = switch_channel_get_variable(channel, OSP_VAR_OUTUSERPARAM); + OSP_TEST("outuserparam: '%s'", OSP_FILTER_NULLSTR(outbound->outuserparam)); + outbound->outuriparam = switch_channel_get_variable(channel, OSP_VAR_OUTURIPARAM); + OSP_TEST("outuriparam: '%s'", OSP_FILTER_NULLSTR(outbound->outuriparam)); /* Get "user=phone" insert flag */ tmp = switch_channel_get_variable(channel, OSP_VAR_USERPHONE); if (!switch_strlen_zero(tmp)) { outbound->userphone = switch_true(tmp); } - OSP_DEBUG("userphone: '%d'", outbound->userphone); + OSP_TEST("userphone: '%d'", outbound->userphone); /* Get outbound proxy info */ outbound->outproxy = switch_channel_get_variable(channel, OSP_VAR_OUTPROXY); - OSP_DEBUG("outporxy: '%s'", OSP_FILTER_NULLSTR(outbound->outproxy)); + OSP_TEST("outporxy: '%s'", OSP_FILTER_NULLSTR(outbound->outproxy)); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1434,7 +1544,12 @@ static switch_status_t osp_get_transaction( osp_profile_t *profile; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; + + /* Cleanup buffer */ + memset(results, 0, sizeof(*results)); + results->transaction = OSP_INVALID_HANDLE; + results->protocol = OSPC_PROTNAME_UNKNOWN; /* Get profile name */ if (!(results->profile = switch_channel_get_variable(channel, OSP_VAR_PROFILE))) { @@ -1443,13 +1558,13 @@ static switch_status_t osp_get_transaction( /* Get transaction handle */ if (osp_find_profile(results->profile, &profile) == SWITCH_STATUS_FALSE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find profile '%s'\n", results->profile); + OSP_ERROR("Failed to find profile '%s'", results->profile); } else if (profile->provider == OSP_INVALID_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disabled profile '%s'\n", results->profile); + OSP_ERROR("Disabled profile '%s'", results->profile); } else if (!(tmp = switch_channel_get_variable(channel, OSP_VAR_TRANSACTION)) || (sscanf(tmp, "%d", &results->transaction) != 1)){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get transaction handle'\n"); + OSP_ERROR("%s", "Failed to get transaction handle'"); } else if (results->transaction == OSP_INVALID_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid transaction handle'\n"); + OSP_ERROR("%s", "Invalid transaction handle'"); } else { if (!(tmp = switch_channel_get_variable(channel, OSP_VAR_TRANSID)) || (sscanf(tmp, "%"PRIu64"", &results->transid) != 1)) { results->transid = 0; @@ -1466,7 +1581,7 @@ static switch_status_t osp_get_transaction( } /* - * Get termiantion cause + * Get termination cause * The logic is * 1. osp_next_function should get TCCode from last_bridge_hangup_cause * 2. osp_on_reporting should get TCCode from osp_terimation_cause @@ -1485,23 +1600,23 @@ static switch_status_t osp_get_transaction( status = SWITCH_STATUS_SUCCESS; } - OSP_DEBUG("profile: '%s'", results->profile); - OSP_DEBUG("transaction: '%d'", results->transaction); - OSP_DEBUG("transid: '%"PRIu64"'", results->transid); - OSP_DEBUG("total: '%d'", results->total); - OSP_DEBUG("count: '%d'", results->count); - OSP_DEBUG("cause: '%d'", results->cause); + OSP_TEST("profile: '%s'", results->profile); + OSP_TEST("transaction: '%d'", results->transaction); + OSP_TEST("transid: '%"PRIu64"'", results->transid); + OSP_TEST("total: '%d'", results->total); + OSP_TEST("count: '%d'", results->count); + OSP_TEST("cause: '%d'", results->cause); - OSP_DEBUG_END; + OSP_TEST_END; return status; } /* * Retrieve usage info - * param channel channel + * param channel Channel * param originator Originator profile - * param terminator Terminator profile, not used at this time + * param originatee Originatee profile * param results Route info * param usage Usage info * return @@ -1509,21 +1624,26 @@ static switch_status_t osp_get_transaction( static void osp_get_usage( switch_channel_t *channel, switch_caller_profile_t *originator, - switch_caller_profile_t *terminator_unused, + switch_caller_profile_t *originatee, osp_results_t *results, osp_usage_t *usage) { const char *tmp; - switch_channel_timetable_t *times; + switch_channel_timetable_t *otimes; + switch_channel_timetable_t *ttimes; - OSP_DEBUG_START; + OSP_TEST_START; /* Cleanup buffer */ memset(usage, 0, sizeof(*usage)); + usage->release = OSPC_RELEASE_UNKNOWN; + usage->rtpsrcrepoctets = OSP_DEF_STATS; + usage->rtpsrcreppackets = OSP_DEF_STATS; /* Release source */ - usage->release = OSPC_RELEASE_UNKNOWN; if (osp_get_protocol(originator->source) == OSPC_PROTNAME_SIP) { + usage->localip = switch_channel_get_variable(channel, OSP_FS_SIPLOCALIP); + tmp = switch_channel_get_variable(channel, OSP_FS_SIPRELEASE); if (!tmp) { usage->release = OSPC_RELEASE_UNDEFINED; @@ -1537,56 +1657,67 @@ static void osp_get_usage( usage->release = OSPC_RELEASE_SOURCE; } } - OSP_DEBUG("release: '%d'", usage->release); + OSP_TEST("localip: '%s'", OSP_FILTER_NULLSTR(usage->localip)); + OSP_TEST("release: '%d'", usage->release); - /* Termiation cause */ + /* Termination cause */ usage->cause = switch_channel_get_cause_q850(channel); - OSP_DEBUG("cause: '%d'", usage->cause); + OSP_TEST("cause: '%d'", usage->cause); /* Timestamps */ - times = switch_channel_get_timetable(channel); - usage->start = times->created; - OSP_DEBUG("start: '%"PRIu64"'", usage->start); - usage->alert = times->progress; - OSP_DEBUG("alert: '%"PRIu64"'", usage->alert); - usage->connect = times->answered; - OSP_DEBUG("connect: '%"PRIu64"'", usage->connect); - usage->end = times->hungup; - OSP_DEBUG("end: '%"PRIu64"'", usage->end); - if (times->answered) { - usage->duration = times->hungup - times->answered; - OSP_DEBUG("duration: '%"PRIu64"'", usage->duration); + otimes = switch_channel_get_timetable(channel); + usage->start = otimes->created; + OSP_TEST("start: '%"PRId64"'", usage->start); + if (originatee && ((ttimes = originatee->times) || (ttimes = originatee->old_times))) { + usage->pstart = ttimes->created; + } else { + usage->pstart = usage->start; } - if (times->progress) { - usage->pdd = times->progress - usage->start; - OSP_DEBUG("pdd: '%"PRIu64"'", usage->pdd); + usage->alert = otimes->progress; + OSP_TEST("alert: '%"PRId64"'", usage->alert); + usage->connect = otimes->answered; + OSP_TEST("connect: '%"PRId64"'", usage->connect); + usage->end = otimes->hungup; + OSP_TEST("end: '%"PRId64"'", usage->end); + if (otimes->answered) { + usage->duration = otimes->hungup - otimes->answered; + OSP_TEST("duration: '%"PRId64"'", usage->duration); + } + if (otimes->progress) { + usage->pdd = otimes->progress - usage->start; + OSP_TEST("pdd: '%"PRId64"'", usage->pdd); + + usage->ppdd = otimes->progress - usage->pstart; + OSP_TEST("ppdd: '%"PRId64"'", usage->ppdd); } - /* Codecs */ - usage->srccodec = switch_channel_get_variable(channel, OSP_FS_SRCCODEC); - OSP_DEBUG("srccodec: '%s'", OSP_FILTER_NULLSTR(usage->srccodec)); - usage->destcodec = switch_channel_get_variable(channel, OSP_FS_DESTCODEC); - OSP_DEBUG("destcodec: '%s'", OSP_FILTER_NULLSTR(usage->destcodec)); + if (otimes->answered) { + /* Media addresses */ + tmp = switch_channel_get_variable(channel, OSP_FS_SRCSDP); + osp_get_mediaip(tmp, usage->srcmediaip, sizeof(usage->srcmediaip)); + OSP_TEST("srcmediaip: '%s'", usage->srcmediaip); + tmp = switch_channel_get_variable(channel, OSP_FS_DESTSDP); + osp_get_mediaip(tmp, usage->destmediaip, sizeof(usage->destmediaip)); + OSP_TEST("destmediaip: '%s'", usage->destmediaip); - /* QoS statistics */ - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPSRCREPOCTS)) || (sscanf(tmp, "%d", &usage->rtpsrcrepoctets) != 1)) { - usage->rtpsrcrepoctets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpsrcrepoctets: '%d'", usage->rtpsrcrepoctets); - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPDESTREPOCTS)) || (sscanf(tmp, "%d", &usage->rtpdestrepoctets) != 1)) { - usage->rtpdestrepoctets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpdestrepoctets: '%d'", usage->rtpdestrepoctets); - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPSRCREPPKTS)) || (sscanf(tmp, "%d", &usage->rtpsrcreppackets) != 1)) { - usage->rtpsrcreppackets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpsrcreppackets: '%d'", usage->rtpsrcreppackets); - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPDESTREPPKTS)) || (sscanf(tmp, "%d", &usage->rtpdestreppackets) != 1)) { - usage->rtpdestreppackets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpdestreppackets: '%d'", usage->rtpdestreppackets); + /* Codecs */ + usage->srccodec = switch_channel_get_variable(channel, OSP_FS_SRCCODEC); + OSP_TEST("srccodec: '%s'", OSP_FILTER_NULLSTR(usage->srccodec)); + usage->destcodec = switch_channel_get_variable(channel, OSP_FS_DESTCODEC); + OSP_TEST("destcodec: '%s'", OSP_FILTER_NULLSTR(usage->destcodec)); - OSP_DEBUG_END; + /* QoS statistics */ + if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPINOCTS)) || (sscanf(tmp, "%d", &usage->rtpsrcrepoctets) != 1)) { + usage->rtpsrcrepoctets = OSP_DEF_STATS; + } + OSP_TEST("rtpsrcrepoctets: '%d'", usage->rtpsrcrepoctets); + if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPINPKTS)) || (sscanf(tmp, "%d", &usage->rtpsrcreppackets) != 1)) { + usage->rtpsrcreppackets = OSP_DEF_STATS; + } + OSP_TEST("rtpsrcreppackets: '%d'", usage->rtpsrcreppackets); + } + + OSP_TEST_END; } /* @@ -1603,23 +1734,23 @@ static switch_status_t osp_check_destination( int error; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; if ((error = OSPPTransactionIsDestOSPEnabled(results->transaction, &enabled)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination OSP version, error '%d'\n", error); + OSP_ERROR("Failed to get destination OSP version, error '%d'", error); } else if ((error = OSPPTransactionGetDestProtocol(results->transaction, &protocol)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get signaling protocol, error '%d'\n", error); + OSP_ERROR("Failed to get signaling protocol, error '%d'", error); } else { + results->protocol = protocol; switch(protocol) { case OSPC_PROTNAME_UNDEFINED: case OSPC_PROTNAME_UNKNOWN: - protocol = osp_global.protocol; + results->protocol = osp_global.protocol; case OSPC_PROTNAME_SIP: case OSPC_PROTNAME_Q931: case OSPC_PROTNAME_IAX: case OSPC_PROTNAME_SKYPE: - results->protocol = protocol; - if (!switch_strlen_zero(osp_global.endpoint[protocol].module) && !switch_strlen_zero(osp_global.endpoint[protocol].profile)) { + if (!switch_strlen_zero(osp_global.endpoint[results->protocol].module) && !switch_strlen_zero(osp_global.endpoint[results->protocol].profile)) { results->supported = SWITCH_TRUE; results->cause = 0; status = SWITCH_STATUS_SUCCESS; @@ -1631,21 +1762,25 @@ static switch_status_t osp_check_destination( case OSPC_PROTNAME_SMPP: case OSPC_PROTNAME_XMPP: default: - results->protocol = protocol; results->supported = SWITCH_FALSE; /* Q.850 protocol error, unspecified */ results->cause = 111; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported protocol '%d'\n", protocol); + OSP_WARN("Unsupported protocol '%d'", protocol); break; } - OSP_DEBUG("protocol: '%d'", results->protocol); - OSP_DEBUG("supported: '%d'", results->supported); - OSP_DEBUG("cause: '%d'", results->cause); + OSP_TEST("protocol: '%d'", results->protocol); + OSP_TEST("supported: '%d'", results->supported); + OSP_TEST("cause: '%d'", results->cause); if ((error = OSPPTransactionGetDestinationNetworkId(results->transaction, sizeof(results->destnid), results->destnid)) != OSPC_ERR_NO_ERROR) { results->destnid[0] = '\0'; } - OSP_DEBUG("destnid: '%s'", results->destnid); + OSP_TEST("destnid: '%s'", results->destnid); + + if ((error = OSPPTransactionGetCNAM(results->transaction, sizeof(results->cnam), results->cnam)) != OSPC_ERR_NO_ERROR) { + results->cnam[0] = '\0'; + } + OSP_TEST("cnam: '%s'", results->cnam); error = OSPPTransactionGetNumberPortabilityParameters( results->transaction, @@ -1659,72 +1794,86 @@ static switch_status_t osp_check_destination( results->npcic[0] = '\0'; results->npdi = 0; } - OSP_DEBUG("nprn: '%s'", results->nprn); - OSP_DEBUG("npcic: '%s'", results->npcic); - OSP_DEBUG("npdi: '%d'", results->npdi); + OSP_TEST("nprn: '%s'", results->nprn); + OSP_TEST("npcic: '%s'", results->npcic); + OSP_TEST("npdi: '%d'", results->npdi); for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) { if ((error = OSPPTransactionGetOperatorName(results->transaction, type, sizeof(results->opname[type]), results->opname[type])) != OSPC_ERR_NO_ERROR) { results->opname[type][0] = '\0'; } - OSP_DEBUG("opname[%d]: '%s'", type, results->opname[type]); + OSP_TEST("opname[%d]: '%s'", type, results->opname[type]); } osp_log_authrsp(results); } - OSP_DEBUG_END; + OSP_TEST_END; return status; } /* - * Build parameter string for each channel - * param results Route info - * param buffer Buffer - * param bufsize Buffer size - * return - */ -static void osp_build_eachparam( - osp_results_t *results, - char *buffer, - switch_size_t bufsize) -{ - OSP_DEBUG_START; - - if (results && buffer && bufsize) { - switch_snprintf(buffer, bufsize, "[%s=%s]", OSP_FS_OUTCALLING, results->calling); - OSP_DEBUG("eachparam: '%s'", buffer); - } - - OSP_DEBUG_END; -} - -/* - * Build endpoint string + * Build parameter string for all channels * param results Route info * param outbound Outbound settings * param buffer Buffer * param bufsize Buffer size * return */ -static void osp_build_endpoint( +static void osp_build_allparam( osp_results_t *results, osp_outbound_t *outbound, char *buffer, switch_size_t bufsize) { - char *head = buffer; - switch_size_t len, size = bufsize; - - OSP_DEBUG_START; + OSP_TEST_START; if (results && buffer && bufsize) { switch (results->protocol) { case OSPC_PROTNAME_SIP: - /* module/profile/called */ - switch_snprintf(head, size, "%s/%s/%s", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile, results->called); - OSP_ADJUST_LEN(head, size, len); + case OSPC_PROTNAME_Q931: + case OSPC_PROTNAME_IAX: + case OSPC_PROTNAME_SKYPE: + default: + buffer[0] = '\0'; + break; + } + OSP_TEST("allparam: '%s'", buffer); + } + + OSP_TEST_END; +} + +/* + * Build parameter string for each channel + * param results Route info + * param outbound Outbound settings + * param buffer Buffer + * param bufsize Buffer size + * return + */ +static void osp_build_eachparam( + osp_results_t *results, + osp_outbound_t *outbound, + char *buffer, + switch_size_t bufsize) +{ + char *head; + switch_size_t len, size; + char userparam[OSP_SIZE_NORSTR] = { 0 }; + char uriparam[OSP_SIZE_NORSTR] = { 0 }; + char param[OSP_SIZE_NORSTR] = { 0 }; + + OSP_TEST_START; + + if (results && buffer && bufsize) { + /* Translated calling number */ + switch (results->protocol) { + case OSPC_PROTNAME_SIP: + /* User parameter string buffer */ + head = userparam; + size = sizeof(userparam); /* RN */ if (!switch_strlen_zero_buf(results->nprn)) { @@ -1750,9 +1899,15 @@ static void osp_build_endpoint( OSP_ADJUST_LEN(head, size, len); } - /* Destination */ - switch_snprintf(head, size, "@%s", results->dest); - OSP_ADJUST_LEN(head, size, len); + /* User parameter fixed outbound parameter string */ + if (!switch_strlen_zero(outbound->outuserparam)) { + switch_snprintf(head, size, ";%s", outbound->outuserparam); + OSP_ADJUST_LEN(head, size, len); + } + + /* URI parameter string buffer */ + head = uriparam; + size = sizeof(uriparam); /* URI parameter destination network ID */ if (!switch_strlen_zero(outbound->dniduriparam) && !switch_strlen_zero_buf(results->destnid)) { @@ -1760,12 +1915,88 @@ static void osp_build_endpoint( OSP_ADJUST_LEN(head, size, len); } + /* URI parameter fixed outbound parameter string */ + if (!switch_strlen_zero(outbound->outuriparam)) { + switch_snprintf(head, size, ";%s", outbound->outuriparam); + OSP_ADJUST_LEN(head, size, len); + } + /* user=phone */ if (outbound->userphone) { switch_snprintf(head, size, ";user=phone"); OSP_ADJUST_LEN(head, size, len); } + /* Parameter string buffer */ + head = param; + size = sizeof(param); + + if (!switch_strlen_zero(userparam)) { + switch_snprintf(head, size, ",%s=%s", OSP_FS_RURIUSERPARAM, userparam + 1); + OSP_ADJUST_LEN(head, size, len); + } + + if (!switch_strlen_zero(uriparam)) { + switch_snprintf(head, size, ",%s=%s", OSP_FS_RURIURIPARAM, uriparam + 1); + OSP_ADJUST_LEN(head, size, len); + } + break; + case OSPC_PROTNAME_Q931: + case OSPC_PROTNAME_IAX: + case OSPC_PROTNAME_SKYPE: + default: + break; + } + + /* Fill buffer */ + head = buffer; + size = bufsize; + + switch_snprintf(head, size - 1, "[%s=%s", OSP_FS_OUTCALLING, results->calling); + OSP_ADJUST_LEN(head, size, len); + + switch_snprintf(head, size - 1, "%s", param); + OSP_ADJUST_LEN(head, size, len); + + switch_snprintf(head, size, "]"); + OSP_ADJUST_LEN(head, size, len); + + OSP_TEST("eachparam: '%s'", buffer); + } + + OSP_TEST_END; +} + +/* + * Build endpoint string + * param results Route info + * param outbound Outbound settings + * param buffer Buffer + * param bufsize Buffer size + * return + */ +static void osp_build_endpoint( + osp_results_t *results, + osp_outbound_t *outbound, + char *buffer, + switch_size_t bufsize) +{ + char *head = buffer; + switch_size_t len, size = bufsize; + + OSP_TEST_START; + + if (results && buffer && bufsize) { + switch (results->protocol) { + case OSPC_PROTNAME_SIP: + /* module/profile/called */ + switch_snprintf(head, size, "%s/%s/%s", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile, results->called); + OSP_ADJUST_LEN(head, size, len); + + /* Destination */ + switch_snprintf(head, size, "@%s", results->dest); + OSP_ADJUST_LEN(head, size, len); + /* Outbound proxy */ if (!switch_strlen_zero(outbound->outproxy)) { switch_snprintf(head, size, ";fs_path=sip:%s", outbound->outproxy); @@ -1793,10 +2024,10 @@ static void osp_build_endpoint( buffer[0] = '\0'; break; } - OSP_DEBUG("endpoint: '%s'", buffer); + OSP_TEST("endpoint: '%s'", buffer); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1813,22 +2044,26 @@ static void osp_create_route( char *buffer, switch_size_t bufsize) { + char allparam[OSP_SIZE_NORSTR]; char eachparam[OSP_SIZE_NORSTR]; char endpoint[OSP_SIZE_NORSTR]; - OSP_DEBUG_START; + OSP_TEST_START; + + /* Build dial string for all channels part */ + osp_build_allparam(results, outbound, allparam, sizeof(allparam)); /* Build dial string for each channel part */ - osp_build_eachparam(results, eachparam, sizeof(eachparam)); + osp_build_eachparam(results, outbound, eachparam, sizeof(eachparam)); /* Build dial string for endpoint part */ osp_build_endpoint(results, outbound, endpoint, sizeof(endpoint)); /* Build dail string */ - switch_snprintf(buffer, bufsize, "%s%s", eachparam, endpoint); - OSP_DEBUG("route: '%s'", buffer); + switch_snprintf(buffer, bufsize, "%s%s%s", allparam, eachparam, endpoint); + OSP_TEST("route: '%s'", buffer); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1854,7 +2089,7 @@ static switch_status_t osp_request_auth( int i, error; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; /* Set source network ID */ OSPPTransactionSetNetworkIds(results->transaction, inbound->srcnid, NULL); @@ -1865,18 +2100,24 @@ static switch_status_t osp_request_auth( /* Set source LNP parameters */ OSPPTransactionSetNumberPortability(results->transaction, inbound->nprn, inbound->npcic, inbound->npdi); + /* Set From */ + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_FROM, OSPC_NFORMAT_DISPLAYNAME, inbound->fromdisplay); + /* Set RPID */ - OSPPTransactionSetRemotePartyId(results->transaction, OSPC_NFORMAT_E164, inbound->rpiduser); + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_RPID, OSPC_NFORMAT_E164, inbound->rpiduser); /* Set PAI */ - OSPPTransactionSetAssertedId(results->transaction, OSPC_NFORMAT_E164, inbound->paiuser); + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_PAI, OSPC_NFORMAT_E164, inbound->paiuser); - /* Set diversion */ + /* Set PCI */ + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_PCI, OSPC_NFORMAT_E164, inbound->pciuser); + + /* Set Diversion */ osp_convert_inout(inbound->divhost, tmp, sizeof(tmp)); OSPPTransactionSetDiversion(results->transaction, inbound->divuser, tmp); - /* Set PCI */ - OSPPTransactionSetChargeInfo(results->transaction, OSPC_NFORMAT_E164, inbound->pciuser); + /* Set User-Agent */ + OSPPTransactionSetUserAgent(results->transaction, inbound->useragent); /* Set custom info */ for (i = 0; i < OSP_MAX_CINFO; i++) { @@ -1901,8 +2142,10 @@ static switch_status_t osp_request_auth( osp_convert_inout(srcdev, dev, sizeof(dev)); /* Preferred and max destinations */ - if (profile->srvtype == OSP_SRV_NPQUERY) { - OSPPTransactionSetServiceType(results->transaction, OSPC_SERVICE_NPQUERY); + switch (profile->srvtype) { + case OSP_SRV_NPQUERY: + case OSP_SRV_CNAMQUERY: + OSPPTransactionSetServiceType(results->transaction, (profile->srvtype == OSP_SRV_NPQUERY) ? OSPC_SERVICE_NPQUERY : OSPC_SERVICE_CNAMQUERY); if (switch_strlen_zero(inbound->tohost)) { switch_copy_string(term, src, sizeof(term)); @@ -1917,13 +2160,18 @@ static switch_status_t osp_request_auth( preferred[0] = term; results->total = 1; - } else { + + break; + case OSP_SRV_VOICE: + default: OSPPTransactionSetServiceType(results->transaction, OSPC_SERVICE_VOICE); results->total = profile->maxdest; + + break; } - OSP_DEBUG_MSG("RequestAuthorisation"); + OSP_TEST_MSG("RequestAuthorisation"); /* Request authorization */ error = OSPPTransactionRequestAuthorisation( @@ -1942,10 +2190,10 @@ static switch_status_t osp_request_auth( NULL, /* Log buffer size */ NULL); /* Log buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to request routing for '%s/%s', error '%d'\n", inbound->calling, inbound->called, error); + OSP_WARN("Unable to request routing for '%s/%s', error '%d'", inbound->calling, inbound->called, error); results->total = 0; } else if (results->total == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Without destination\n"); + OSP_WARN("%s", "Without destination"); } else { context = OSPPTransactionGetContext(results->transaction, &error); if (error == OSPC_ERR_NO_ERROR) { @@ -1955,10 +2203,10 @@ static switch_status_t osp_request_auth( } status = SWITCH_STATUS_SUCCESS; } - OSP_DEBUG("transid: '%"PRIu64"'", results->transid); - OSP_DEBUG("total: '%d'", results->total); + OSP_TEST("transid: '%"PRIu64"'", results->transid); + OSP_TEST("total: '%d'", results->total); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -1976,12 +2224,12 @@ static switch_status_t osp_get_first( unsigned int callidlen = 0, tokenlen = 0; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; /* Set destination count */ results->count = 1; - OSP_DEBUG_MSG("GetFirstDestination"); + OSP_TEST_MSG("GetFirstDestination"); /* Get first destination */ error = OSPPTransactionGetFirstDestination( @@ -2003,16 +2251,16 @@ static switch_status_t osp_get_first( &tokenlen, /* Token buffer length */ NULL); /* Token buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get first destination, error '%d'\n", error); + OSP_ERROR("Failed to get first destination, error '%d'", error); } else { osp_convert_outin(term, results->dest, sizeof(results->dest)); /* Check destination */ status = osp_check_destination(results); } - OSP_DEBUG("status: '%d'", status); + OSP_TEST("status: '%d'", status); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2030,17 +2278,17 @@ static switch_status_t osp_get_next( unsigned int callidlen = 0, tokenlen = 0; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; while ((status == SWITCH_STATUS_FALSE) && (results->count < results->total)) { /* Set destination count */ results->count++; - OSP_DEBUG_MSG("GetNextDestination"); + OSP_TEST_MSG("GetNextDestination"); /* Get next destination */ error = OSPPTransactionGetNextDestination( - results->transaction, /* Transsaction handle */ + results->transaction, /* Transaction handle */ results->cause, /* Failure reason */ 0, /* Timestamp buffer size */ NULL, /* Valid after */ @@ -2059,7 +2307,7 @@ static switch_status_t osp_get_next( &tokenlen, /* Token buffer length */ NULL); /* Token buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination, error '%d'\n", error); + OSP_ERROR("Failed to get destination, error '%d'", error); break; } else { osp_convert_outin(term, results->dest, sizeof(results->dest)); @@ -2068,9 +2316,9 @@ static switch_status_t osp_get_next( status = osp_check_destination(results); } } - OSP_DEBUG("status: '%d'", status); + OSP_TEST("status: '%d'", status); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2087,9 +2335,10 @@ static switch_status_t osp_report_usage( { int error; unsigned int dummy = 0; + osp_profile_t *profile; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; /* Set role info */ OSPPTransactionSetRoleInfo(results->transaction, OSPC_RSTATE_STOP, OSPC_RFORMAT_OSP, OSPC_RVENDOR_FREESWITCH); @@ -2101,6 +2350,26 @@ static switch_status_t osp_report_usage( OSPPTransactionRecordFailure(results->transaction, usage->cause); } + /* Set provider post dial delay */ + OSPPTransactionSetProviderPDD(results->transaction, usage->ppdd / 1000); + + /* Set media address */ + if (!switch_strlen_zero(usage->srcmediaip)) { + OSPPTransactionSetSrcAudioAddr(results->transaction, usage->srcmediaip); + } + if (!switch_strlen_zero(usage->destmediaip)) { + OSPPTransactionSetDestAudioAddr(results->transaction, usage->destmediaip); + } + + /* Set signal local address */ + OSPPTransactionSetProxyIngressAddr(results->transaction, usage->localip); + OSPPTransactionSetProxyEgressAddr(results->transaction, usage->localip); + + /* Set CDR proxy */ + if (osp_find_profile(results->profile, &profile) == SWITCH_STATUS_SUCCESS) { + OSPPTransactionSetCDRProxy(results->transaction, profile->deviceip, OSP_FREESWITCH, NULL); + } + /* Set codecs */ if (!switch_strlen_zero(usage->srccodec)) { OSPPTransactionSetCodec(results->transaction, OSPC_CODEC_SOURCE, usage->srccodec); @@ -2113,17 +2382,11 @@ static switch_status_t osp_report_usage( if (usage->rtpsrcrepoctets != OSP_DEF_STATS) { OSPPTransactionSetOctets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, usage->rtpsrcrepoctets); } - if (usage->rtpdestrepoctets != OSP_DEF_STATS) { - OSPPTransactionSetOctets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, usage->rtpdestrepoctets); - } if (usage->rtpsrcreppackets != OSP_DEF_STATS) { OSPPTransactionSetPackets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, usage->rtpsrcreppackets); } - if (usage->rtpdestreppackets != OSP_DEF_STATS) { - OSPPTransactionSetPackets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, usage->rtpdestreppackets); - } - OSP_DEBUG_MSG("ReportUsage"); + OSP_TEST_MSG("ReportUsage"); /* Report usage */ error = OSPPTransactionReportUsage( @@ -2144,7 +2407,7 @@ static switch_status_t osp_report_usage( &dummy, /* Detail log buffer size */ NULL); /* Detail log buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to report usage, error '%d'\n", error); + OSP_ERROR("Failed to report usage, error '%d'", error); } else { status = SWITCH_STATUS_SUCCESS; } @@ -2152,7 +2415,7 @@ static switch_status_t osp_report_usage( /* Delete transaction handle */ OSPPTransactionDelete(results->transaction); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2161,48 +2424,48 @@ static switch_status_t osp_report_usage( * Export OSP lookup status to channel * param channel Originator channel * param status OSP lookup status - * param outbound Outbound info * param results Routing info + * param outbound Outbound info * return */ static void osp_export_lookup( switch_channel_t *channel, switch_status_t status, - osp_outbound_t *outbound, - osp_results_t *results) + osp_results_t *results, + osp_outbound_t *outbound) { char value[OSP_SIZE_ROUSTR]; - OSP_DEBUG_START; + OSP_TEST_START; /* Profile name */ switch_channel_set_variable_var_check(channel, OSP_VAR_PROFILE, results->profile, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_PROFILE, results->profile); + OSP_TEST("%s: '%s'", OSP_VAR_PROFILE, results->profile); /* Transaction handle */ switch_snprintf(value, sizeof(value), "%d", results->transaction); switch_channel_set_variable_var_check(channel, OSP_VAR_TRANSACTION, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_TRANSACTION, value); + OSP_TEST("%s: '%s'", OSP_VAR_TRANSACTION, value); /* Transaction ID */ switch_snprintf(value, sizeof(value), "%"PRIu64"", results->transid); switch_channel_set_variable_var_check(channel, OSP_VAR_TRANSID, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_TRANSID, value); + OSP_TEST("%s: '%s'", OSP_VAR_TRANSID, value); /* OSP lookup status */ switch_snprintf(value, sizeof(value), "%d", status); switch_channel_set_variable_var_check(channel, OSP_VAR_LOOKUPSTATUS, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_LOOKUPSTATUS, value); + OSP_TEST("%s: '%s'", OSP_VAR_LOOKUPSTATUS, value); /* Destination total */ switch_snprintf(value, sizeof(value), "%d", results->total); switch_channel_set_variable_var_check(channel, OSP_VAR_ROUTETOTAL, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_ROUTETOTAL, value); + OSP_TEST("%s: '%s'", OSP_VAR_ROUTETOTAL, value); /* Destination count */ switch_snprintf(value, sizeof(value), "%d", results->count); switch_channel_set_variable_var_check(channel, OSP_VAR_ROUTECOUNT, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_ROUTECOUNT, value); + OSP_TEST("%s: '%s'", OSP_VAR_ROUTECOUNT, value); /* Dial string */ if (status == SWITCH_STATUS_SUCCESS) { @@ -2212,9 +2475,9 @@ static void osp_export_lookup( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_AUTOROUTE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_AUTOROUTE, value); + OSP_TEST("%s: '%s'", OSP_VAR_AUTOROUTE, value); - /* Termiantion cause */ + /* Termination cause */ if (results->cause) { switch_snprintf(value, sizeof(value), "%d", results->cause); switch_channel_set_variable_var_check(channel, OSP_VAR_TCCODE, value, SWITCH_FALSE); @@ -2222,38 +2485,38 @@ static void osp_export_lookup( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_TCCODE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_TCCODE, value); + OSP_TEST("%s: '%s'", OSP_VAR_TCCODE, value); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Export OSP next status to channel * param channel Originator channel * param status OSP next status - * param outbound Outbound info * param results Routing info + * param outbound Outbound info * return */ static void osp_export_next( switch_channel_t *channel, switch_status_t status, - osp_outbound_t *outbound, - osp_results_t *results) + osp_results_t *results, + osp_outbound_t *outbound) { char value[OSP_SIZE_NORSTR]; - OSP_DEBUG_START; + OSP_TEST_START; /* OSP next status */ switch_snprintf(value, sizeof(value), "%d", status); switch_channel_set_variable_var_check(channel, OSP_VAR_NEXTSTATUS, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_NEXTSTATUS, value); + OSP_TEST("%s: '%s'", OSP_VAR_NEXTSTATUS, value); /* Destination count */ switch_snprintf(value, sizeof(value), "%d", results->count); switch_channel_set_variable_var_check(channel, OSP_VAR_ROUTECOUNT, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_ROUTECOUNT, value); + OSP_TEST("%s: '%s'", OSP_VAR_ROUTECOUNT, value); /* Dial string */ if (status == SWITCH_STATUS_SUCCESS) { @@ -2263,9 +2526,9 @@ static void osp_export_next( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_AUTOROUTE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_AUTOROUTE, value); + OSP_TEST("%s: '%s'", OSP_VAR_AUTOROUTE, value); - /* Termiantion cause */ + /* Termination cause */ if (results->cause) { switch_snprintf(value, sizeof(value), "%d", results->cause); switch_channel_set_variable_var_check(channel, OSP_VAR_TCCODE, value, SWITCH_FALSE); @@ -2273,35 +2536,42 @@ static void osp_export_next( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_TCCODE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_TCCODE, value); + OSP_TEST("%s: '%s'", OSP_VAR_TCCODE, value); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Request auth and get first OSP route * param channel Originator channel - * param results Routing info + * param profilename OSP profile name * return */ static void osp_do_lookup( switch_channel_t *channel, - osp_results_t *results) + const char *profilename) { int error; + osp_results_t results; osp_profile_t *profile; osp_inbound_t inbound; osp_outbound_t outbound; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; - if (osp_find_profile(results->profile, &profile) == SWITCH_STATUS_FALSE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find profile '%s'\n", results->profile); + /* Cleanup buffer */ + memset(&results, 0, sizeof(results)); + results.profile = profilename; + results.transaction = OSP_INVALID_HANDLE; + results.protocol = OSPC_PROTNAME_UNKNOWN; + + if (osp_find_profile(results.profile, &profile) == SWITCH_STATUS_FALSE) { + OSP_ERROR("Failed to find profile '%s'", results.profile); } else if (profile->provider == OSP_INVALID_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disabled profile '%s'\n", results->profile); - } else if ((error = OSPPTransactionNew(profile->provider, &results->transaction)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create transaction handle, error '%d'\n", error); + OSP_ERROR("Disabled profile '%s'", results.profile); + } else if ((error = OSPPTransactionNew(profile->provider, &results.transaction)) != OSPC_ERR_NO_ERROR) { + OSP_ERROR("Failed to create transaction handle, error '%d'", error); } else { /* Get inbound info */ osp_get_inbound(channel, &inbound); @@ -2310,9 +2580,9 @@ static void osp_do_lookup( osp_log_authreq(profile, &inbound); /* Do AuthReq */ - if (osp_request_auth(profile, &inbound, results) == SWITCH_STATUS_SUCCESS) { + if (osp_request_auth(profile, &inbound, &results) == SWITCH_STATUS_SUCCESS) { /* Get route */ - if ((osp_get_first(results) == SWITCH_STATUS_SUCCESS) || (osp_get_next(results) == SWITCH_STATUS_SUCCESS)) { + if ((osp_get_first(&results) == SWITCH_STATUS_SUCCESS) || (osp_get_next(&results) == SWITCH_STATUS_SUCCESS)) { /* Get outbound info */ osp_get_outbound(channel, &outbound); status = SWITCH_STATUS_SUCCESS; @@ -2321,80 +2591,99 @@ static void osp_do_lookup( } /* Export OSP lookup info */ - osp_export_lookup(channel, status, &outbound, results); + osp_export_lookup(channel, status, &results, &outbound); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Get next OSP route * param channel Originator channel - * param results Routing info * return */ static void osp_do_next( - switch_channel_t *channel, - osp_results_t *results) + switch_channel_t *channel) { + osp_results_t results; osp_outbound_t outbound; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; - if (osp_get_transaction(channel, SWITCH_FALSE, results) == SWITCH_STATUS_SUCCESS) { + if (osp_get_transaction(channel, SWITCH_FALSE, &results) == SWITCH_STATUS_SUCCESS) { /* Get next OSP route */ - if ((status = osp_get_next(results)) == SWITCH_STATUS_SUCCESS) { + if ((status = osp_get_next(&results)) == SWITCH_STATUS_SUCCESS) { /* Get outbound info */ osp_get_outbound(channel, &outbound); } } /* Export OSP next info */ - osp_export_next(channel, status, &outbound, results); + osp_export_next(channel, status, &results, &outbound); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Report OSP usage * param channel Originator channel - * param originator Originate profile - * param terminator Terminate profile + * param originator Originator profile + * param originatee Originatee profile * param results Routing info * return SWITCH_STATUS_SUCCESS Successful, SWITCH_STATUS_FALSE Failed */ static switch_status_t osp_do_report( switch_channel_t *channel, switch_caller_profile_t *originator, - switch_caller_profile_t *terminator, - osp_results_t *results) + switch_caller_profile_t *originatee) { + osp_results_t results; osp_usage_t usage; switch_status_t status = SWITCH_STATUS_SUCCESS; - OSP_DEBUG_START; + OSP_TEST_START; - if (osp_get_transaction(channel, SWITCH_TRUE, results) == SWITCH_STATUS_SUCCESS) { - /* Do not report usage for failed AuthReq */ - if (results->total) { + if (osp_get_transaction(channel, SWITCH_TRUE, &results) == SWITCH_STATUS_SUCCESS) { + if (results.total) { /* Get usage info */ - osp_get_usage(channel, originator, terminator, results, &usage); + osp_get_usage(channel, originator, originatee, &results, &usage); /* Log usage info */ - osp_log_usageind(results, &usage); + osp_log_usageind(&results, &usage); /* Report OSP usage */ - status = osp_report_usage(results, &usage); + status = osp_report_usage(&results, &usage); } else { - OSP_DEBUG_MSG("Do not report usage"); + /* Do not report usage for failed AuthReq */ + OSP_TEST_MSG("Do not report usage"); } } - OSP_DEBUG_END; + OSP_TEST_END; return status; } +/* + * Log variables, copy from FS info application, only for debug purpose + * param session Session + */ +void osp_log_info( + switch_core_session_t *session) +{ + switch_event_t *event; + char *buffer; + + if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(session), event); + switch_event_serialize(event, &buffer, SWITCH_FALSE); + switch_assert(buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ALERT, "CHANNEL_DATA:\n%s\n", buffer); + switch_event_destroy(&event); + free(buffer); + } +} + /* * OSP module CLI command * Macro expands to: @@ -2409,23 +2698,23 @@ SWITCH_STANDARD_API(osp_cli_function) osp_profile_t *profile; char *loglevel; - OSP_DEBUG_START; + OSP_TEST_START; if (session) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This function cannot be called from the dialplan.\n"); - OSP_DEBUG_END; + OSP_ERROR("%s", "This function cannot be called from the dialplan."); + OSP_TEST_END; return SWITCH_STATUS_FALSE; } if (switch_strlen_zero(cmd)) { stream->write_function(stream, "Usage: osp status\n"); - OSP_DEBUG_END; + OSP_TEST_END; return SWITCH_STATUS_SUCCESS; } if (!(params = switch_safe_strdup(cmd))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate parameters\n"); - OSP_DEBUG_END; + OSP_CRIT("%s", "Failed to duplicate parameters"); + OSP_TEST_END; return SWITCH_STATUS_MEMERR; } @@ -2498,7 +2787,7 @@ SWITCH_STANDARD_API(osp_cli_function) stream->write_function(stream, " ssl-lifetime: %d\n", profile->lifetime); stream->write_function(stream, " http-max-connections: %d\n", profile->maxconnect); stream->write_function(stream, " http-persistence: %d\n", profile->persistence); - stream->write_function(stream, " http-retry-dalay: %d\n", profile->retrydelay); + stream->write_function(stream, " http-retry-delay: %d\n", profile->retrydelay); stream->write_function(stream, " http-retry-limit: %d\n", profile->retrylimit); stream->write_function(stream, " http-timeout: %d\n", profile->timeout); switch (profile->workmode) { @@ -2514,6 +2803,9 @@ SWITCH_STANDARD_API(osp_cli_function) case OSP_SRV_NPQUERY: stream->write_function(stream, " service-type: npquery\n"); break; + case OSP_SRV_CNAMQUERY: + stream->write_function(stream, " service-type: cnamquery\n"); + break; case OSP_SRV_VOICE: default: stream->write_function(stream, " service-type: voice\n"); @@ -2531,7 +2823,7 @@ SWITCH_STANDARD_API(osp_cli_function) switch_safe_free(params); - OSP_DEBUG_END; + OSP_TEST_END; return SWITCH_STATUS_SUCCESS; } @@ -2546,32 +2838,29 @@ SWITCH_STANDARD_APP(osp_lookup_function) int argc = 0; char *argv[2] = { 0 }; char *params = NULL; - osp_results_t results; + const char *profile; - OSP_DEBUG_START; + OSP_TEST_START; if (osp_global.shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "OSP application inavailable\n"); + OSP_WARN("%s", "OSP application unavailable"); } else if (!(channel = switch_core_session_get_channel(session))) { /* Make sure there is a valid channel when starting the OSP application */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to find origiantor channel\n"); + OSP_CRIT("%s", "Failed to find channel"); } else if (!(params = switch_core_session_strdup(session, data))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to alloc parameters\n"); + OSP_CRIT("%s", "Failed to allocate parameters"); } else { - memset(&results, 0, sizeof(osp_results_t)); if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - results.profile = argv[0]; + profile = argv[0]; } else { - results.profile = OSP_DEF_PROFILE; + profile = OSP_DEF_PROFILE; } - results.transaction = OSP_INVALID_HANDLE; - results.protocol = OSPC_PROTNAME_UNKNOWN; /* Do OSP lookup */ - osp_do_lookup(channel, &results); + osp_do_lookup(channel, profile); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -2581,24 +2870,20 @@ SWITCH_STANDARD_APP(osp_lookup_function) SWITCH_STANDARD_APP(osp_next_function) { switch_channel_t *channel; - osp_results_t results; - OSP_DEBUG_START; + OSP_TEST_START; if (osp_global.shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "OSP application inavailable\n"); + OSP_WARN("%s", "OSP application unavailable"); } else if (!(channel = switch_core_session_get_channel(session))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to find origiantor channel\n"); + /* Make sure there is a valid channel when starting the OSP application */ + OSP_CRIT("%s", "Failed to find originator channel"); } else { - memset(&results, 0, sizeof(osp_results_t)); - results.transaction = OSP_INVALID_HANDLE; - results.protocol = OSPC_PROTNAME_UNKNOWN; - /* Do OSP next */ - osp_do_next(channel, &results); + osp_do_next(channel); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -2611,39 +2896,33 @@ static switch_status_t osp_on_reporting( { switch_channel_t *channel; switch_caller_profile_t *originator; - switch_caller_profile_t *terminator; - osp_results_t results; + switch_caller_profile_t *originatee; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; if (osp_global.shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OSP application inavailable\n"); + OSP_CRIT("%s", "OSP application unavailable"); } else if (!(channel = switch_core_session_get_channel(session))) { /* Make sure there is a valid channel when starting the OSP application */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to find origiantor channel\n"); + OSP_CRIT("%s", "Failed to find channel"); + } else if (!(originator = switch_channel_get_caller_profile(channel))) { + OSP_CRIT("%s", "Failed to find profile"); } else if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { /* A-leg */ - OSP_DEBUG_MSG("A-leg"); + OSP_TEST_MSG("A-leg"); - /* Get originator profile */ - if ((originator = switch_channel_get_caller_profile(channel))) { - /* Get terminator profile, may be NULL */ - terminator = switch_channel_get_originatee_caller_profile(channel); + /* Originatee profile */ + originatee = switch_channel_get_originatee_caller_profile(channel); - memset(&results, 0, sizeof(osp_results_t)); - results.transaction = OSP_INVALID_HANDLE; - results.protocol = OSPC_PROTNAME_UNKNOWN; - - /* Do OSP usage report */ - status = osp_do_report(channel, originator, terminator, &results); - } + /* Do OSP usage report */ + status = osp_do_report(channel, originator, originatee); } else { /* B-leg */ - OSP_DEBUG_MSG("B-leg"); + OSP_TEST_MSG("B-leg"); } - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2683,11 +2962,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load) switch_application_interface_t *app_interface; switch_status_t status = SWITCH_STATUS_SUCCESS; - OSP_DEBUG_START; + OSP_TEST_START; /* Load OSP module configuration */ if ((status = osp_load_config(pool)) != SWITCH_STATUS_SUCCESS) { - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2703,12 +2982,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load) /* Add OSP module applications */ SWITCH_ADD_APP(app_interface, "osplookup", "Perform an OSP lookup", "Perform an OSP lookup", osp_lookup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); - SWITCH_ADD_APP(app_interface, "ospnext", "Retrive next OSP route", "Retrive next OSP route", osp_next_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); + SWITCH_ADD_APP(app_interface, "ospnext", "Retrieve next OSP route", "Retrieve next OSP route", osp_next_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); /* Add OSP module state handlers */ switch_core_add_state_handler(&osp_handlers); - OSP_DEBUG_END; + OSP_TEST_END; /* Indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; @@ -2721,7 +3000,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load) */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_osp_shutdown) { - OSP_DEBUG_START; + OSP_TEST_START; /* Shutdown OSP module */ osp_global.shutdown = SWITCH_TRUE; @@ -2729,10 +3008,10 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_osp_shutdown) /* Cleanup OSP client end */ osp_cleanup_osptk(); - /* Remoeve OSP module state handlers */ + /* Remove OSP module state handlers */ switch_core_remove_state_handler(&osp_handlers); - OSP_DEBUG_END; + OSP_TEST_END; return SWITCH_STATUS_SUCCESS; } @@ -2747,4 +3026,3 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_osp_shutdown) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet */ - From 3910dab95a1ef1dec8cb540d0e11578440f446ba Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 9 Jun 2016 06:58:40 +0800 Subject: [PATCH 63/72] FS-8979 #comment fire event when done --- src/mod/formats/mod_imagick/mod_imagick.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/mod/formats/mod_imagick/mod_imagick.c b/src/mod/formats/mod_imagick/mod_imagick.c index 8d95965780..7680e65a13 100644 --- a/src/mod/formats/mod_imagick/mod_imagick.c +++ b/src/mod/formats/mod_imagick/mod_imagick.c @@ -84,6 +84,7 @@ struct pdf_file_context { int autoplay; const char *path; int lazy; + char *lazy_cookie; pdf_loading_state_t loading_state; switch_time_t next_play_time; }; @@ -106,6 +107,18 @@ static void *SWITCH_THREAD_FUNC open_pdf_thread_run(switch_thread_t *thread, voi AppendImageToList(&context->images, tmp_images); context->pagecount = pagenumber; } else { + switch_event_t *event = NULL; + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "imagick::info") == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "loaded"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", context->path); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "pagecount", "%d", context->pagecount); + if (context->lazy_cookie) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "cookie", context->lazy_cookie); + } + switch_event_fire(&event); + } + break; } } @@ -171,6 +184,7 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha const char *density = switch_event_get_header(handle->params, "density"); const char *quality = switch_event_get_header(handle->params, "quality"); const char *lazy = switch_event_get_header(handle->params, "lazy"); + const char *lazy_cookie = switch_event_get_header(handle->params, "cookie"); int tmp; if (max) { @@ -191,6 +205,7 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha if (tmp > 0) context->image_info->quality = tmp; } + if (lazy) { int tmp = atoi(lazy); @@ -200,6 +215,10 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha context->lazy = 1; } } + + if (lazy_cookie) { + context->lazy_cookie = switch_core_strdup(handle->memory_pool, lazy_cookie); + } } if (context->lazy) { From 718142bb12785d6293483c2c575dc45477300d36 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 20 May 2016 11:12:08 -0500 Subject: [PATCH 64/72] FS-9144 #resolve [Implement video-mute-exit-canvas and recording in personal-canvas mode.] --- .../mod_conference/conference_api.c | 9 -- .../mod_conference/conference_record.c | 20 ++-- .../mod_conference/conference_video.c | 107 +++++++++++------- 3 files changed, 77 insertions(+), 59 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 11a2efadcb..fe93d42ce9 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1079,10 +1079,6 @@ switch_status_t conference_api_sub_vid_personal(conference_obj_t *conference, sw if (argv[2]) { on = switch_true(argv[2]); if (on) { - if (conference->record_count > 0) { - stream->write_function(stream, "-ERR conference is recording, not enabling vid-personal.\n"); - return SWITCH_STATUS_SUCCESS; - } conference_utils_set_flag(conference, CFLAG_PERSONAL_CANVAS); } else { conference_utils_clear_flag(conference, CFLAG_PERSONAL_CANVAS); @@ -2515,11 +2511,6 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s return SWITCH_STATUS_SUCCESS; } - if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) { - stream->write_function(stream, "-ERR Personal Canvas enabled, recording not permitted.\n"); - return SWITCH_STATUS_SUCCESS; - } - if (argv[3]) { if (argv[3]) { diff --git a/src/mod/applications/mod_conference/conference_record.c b/src/mod/applications/mod_conference/conference_record.c index 7eb8fd0a18..89afeab14b 100644 --- a/src/mod/applications/mod_conference/conference_record.c +++ b/src/mod/applications/mod_conference/conference_record.c @@ -65,11 +65,6 @@ void conference_record_launch_thread(conference_obj_t *conference, char *path, i return; } - if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Personal Canvas enabled, recording not permitted.\n"); - return; - } - rec->conference = conference; rec->path = switch_core_strdup(pool, path); rec->pool = pool; @@ -235,9 +230,10 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; if (conference_utils_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) { + char *orig_path = rec->path; flags |= SWITCH_FILE_FLAG_VIDEO; + if (canvas) { - char *orig_path = rec->path; rec->path = switch_core_sprintf(rec->pool, "{channels=%d,samplerate=%d,vw=%d,vh=%d,fps=%0.2f}%s", conference->channels, conference->rate, @@ -245,9 +241,18 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v canvas->height, conference->video_fps.fps, orig_path); + } else { + rec->path = switch_core_sprintf(rec->pool, "{channels=%d,samplerate=%d,vw=%d,vh=%d,fps=%0.2f}%s", + conference->channels, + conference->rate, + conference->canvas_width, + conference->canvas_height, + conference->video_fps.fps, + orig_path); + } } - + if (switch_core_file_open(&member->rec->fh, rec->path, (uint8_t) conference->channels, conference->rate, flags, rec->pool) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s]\n", rec->path); @@ -390,6 +395,7 @@ void *SWITCH_THREAD_FUNC conference_record_thread_run(switch_thread_t *thread, v switch_mutex_unlock(conference->mutex); switch_core_file_close(&member->rec->fh); } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Recording of %s Stopped\n", rec->path); if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { conference_event_add_data(conference, event); diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 5fc896407b..1e5d1cc10d 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1613,8 +1613,8 @@ void conference_video_check_recording(conference_obj_t *conference, mcu_canvas_t if (!imember->rec) { continue; } - - if (canvas && imember->canvas_id != canvas->canvas_id) { + + if (!conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) && canvas && imember->canvas_id != canvas->canvas_id) { continue; } @@ -2123,16 +2123,18 @@ static void personal_attach(mcu_layer_t *layer, conference_member_t *member) conference_api_sub_position(member, NULL, layer->geometry.audio_position); } - var = NULL; - if (member->video_banner_text || - (var = switch_channel_get_variable_dup(member->channel, "video_banner_text", SWITCH_FALSE, -1))) { - conference_video_layer_set_banner(member, layer, var); - } - - var = NULL; - if (member->video_logo || - (var = switch_channel_get_variable_dup(member->channel, "video_logo_path", SWITCH_FALSE, -1))) { - conference_video_layer_set_logo(member, layer, var); + if (member->channel) { + var = NULL; + if (member->video_banner_text || + (var = switch_channel_get_variable_dup(member->channel, "video_banner_text", SWITCH_FALSE, -1))) { + conference_video_layer_set_banner(member, layer, var); + } + + var = NULL; + if (member->video_logo || + (var = switch_channel_get_variable_dup(member->channel, "video_logo_path", SWITCH_FALSE, -1))) { + conference_video_layer_set_logo(member, layer, var); + } } } @@ -2163,6 +2165,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr int layout_applied = 0; int files_playing = 0; int last_personal = conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) ? 1 : 0; + int last_video_count = 0; canvas->video_timer_reset = 1; canvas->video_layout_group = conference->video_layout_group; @@ -2230,11 +2233,12 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } - if (video_count != canvas->video_count) { + + if (video_count != canvas->video_count || video_count != last_video_count) { count_changed = 1; } - canvas->video_count = video_count; + canvas->video_count = last_video_count = video_count; switch_mutex_unlock(conference->member_mutex); switch_core_timer_next(&canvas->timer); @@ -2562,7 +2566,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr layout_group_t *lg = NULL; video_layout_t *vlayout = NULL; conference_member_t *omember; - + if (video_key_freq && (now - last_key_time) > video_key_freq) { send_keyframe = SWITCH_TRUE; last_key_time = now; @@ -2571,9 +2575,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_mutex_lock(conference->member_mutex); for (imember = conference->members; imember; imember = imember->next) { - - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || - switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { + + if (!imember->rec && + (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || + switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { continue; } @@ -2591,13 +2596,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr layout_applied++; } - if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { + if (imember->channel && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); send_keyframe = SWITCH_TRUE; } if (count_changed) { - int total = conference->members_with_video; + int total = last_video_count; int kps; switch_vid_params_t vid_params = { 0 }; @@ -2605,7 +2610,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr total += conference->members_with_avatar; } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (total > 0 && + (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) || + conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN)) && + imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { total--; } @@ -2621,7 +2629,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - if (!switch_channel_test_flag(imember->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && + if (imember->channel && !switch_channel_test_flag(imember->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && conference_utils_test_flag(conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE)) { switch_core_media_get_vid_params(imember->session, &vid_params); kps = switch_calc_bitrate(vid_params.width, vid_params.height, conference->video_quality, (int)(imember->conference->video_fps.fps)); @@ -2629,11 +2637,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { conference_video_pop_next_image(imember, &imember->pcanvas_img); } - switch_core_session_rwunlock(imember->session); + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } } if (conference->new_personal_vlayout && layout_applied) { @@ -2671,9 +2681,10 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr int i = 0; mcu_layer_t *floor_layer = NULL; - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || !imember->canvas || - (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) || - (switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { + if (!imember->rec && + (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || !imember->canvas || + (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) || + (switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS))) { continue; } @@ -2762,7 +2773,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (layer) { if (conference_utils_member_test_flag(omember, MFLAG_CAN_BE_SEEN)) { layer->mute_patched = 0; - } else { + } else if (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) { if (!layer->mute_patched) { switch_image_t *tmp; conference_video_scale_and_patch(layer, omember->video_mute_img ? omember->video_mute_img : omember->pcanvas_img, SWITCH_FALSE); @@ -2795,7 +2806,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - switch_core_session_rwunlock(imember->session); + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } } if (files_playing && !file_count) { @@ -2807,33 +2820,41 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (imember = conference->members; imember; imember = imember->next) { switch_frame_t *dupframe; - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || - switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { + if (!imember->rec && + (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || + switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { continue; } - if (need_refresh) { + if (need_refresh && imember->session) { switch_core_session_request_video_refresh(imember->session); } - if (send_keyframe) { + if (send_keyframe && imember->session) { switch_core_media_gen_key_frame(imember->session); } - switch_set_flag(&write_frame, SFF_RAW_RTP); write_frame.img = imember->canvas->img; - write_frame.packet = packet; - write_frame.data = ((uint8_t *)packet) + 12; - write_frame.datalen = 0; - write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12; - write_frame.packetlen = 0; + + if (imember->rec) { + switch_core_file_write_video(&imember->rec->fh, &write_frame); + } else { + switch_set_flag(&write_frame, SFF_RAW_RTP); + write_frame.packet = packet; + write_frame.data = ((uint8_t *)packet) + 12; + write_frame.datalen = 0; + write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12; + write_frame.packetlen = 0; - if (switch_frame_buffer_dup(imember->fb, &write_frame, &dupframe) == SWITCH_STATUS_SUCCESS) { - switch_queue_push(imember->mux_out_queue, dupframe); - dupframe = NULL; + if (switch_frame_buffer_dup(imember->fb, &write_frame, &dupframe) == SWITCH_STATUS_SUCCESS) { + switch_queue_push(imember->mux_out_queue, dupframe); + dupframe = NULL; + } } - switch_core_session_rwunlock(imember->session); + if (imember->session) { + switch_core_session_rwunlock(imember->session); + } } switch_mutex_unlock(conference->member_mutex); From e7758cb724feb629e4ebc104d10b78748c372b53 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 9 Jun 2016 13:33:31 -0500 Subject: [PATCH 65/72] FS-9247 #resolve [Table with message type names not updated when enum was updated by sangoma patch] --- src/switch_core_session.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_core_session.c b/src/switch_core_session.c index a4a64d96e5..aa0f92f222 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -719,6 +719,7 @@ static const char *message_names[] = { "UNBRIDGE", "TRANSFER", "RINGING", + "ALERTING", "MEDIA", "3P_MEDIA", "NOMEDIA", From 0f3204feb3ec1044333803031367b8a45cfa850d Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Thu, 9 Jun 2016 16:53:21 -0300 Subject: [PATCH 66/72] FS-9248 [mod_callcenter] Adding truncate-tiers-on-load and truncate-agents-on-load options. --- .../mod_callcenter/mod_callcenter.c | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index d626eb2ed0..14e5d67b99 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -417,6 +417,8 @@ static struct { char *odbc_dsn; char *dbname; switch_bool_t reserve_agents; + switch_bool_t truncate_tiers; + switch_bool_t truncate_agents; int32_t threads; int32_t running; switch_mutex_t *mutex; @@ -1428,8 +1430,12 @@ static switch_status_t load_config(void) globals.dbname = strdup(val); } else if (!strcasecmp(var, "odbc-dsn")) { globals.odbc_dsn = strdup(val); - } else if(!strcasecmp(var, "reserve-agents")) { + } else if (!strcasecmp(var, "reserve-agents")) { globals.reserve_agents = switch_true(val); + } else if (!strcasecmp(var, "truncate-tiers-on-load")) { + globals.truncate_tiers = switch_true(val); + } else if (!strcasecmp(var, "truncate-agents-on-load")) { + globals.truncate_agents = switch_true(val); } } } @@ -1465,6 +1471,20 @@ static switch_status_t load_config(void) cc_execute_sql(NULL, sql, NULL); switch_safe_free(sql); + /* Truncating tiers if needed */ + if (globals.truncate_tiers) { + sql = switch_mprintf("delete from tiers;"); + cc_execute_sql(NULL, sql, NULL); + switch_safe_free(sql); + } + + /* Truncating agents if needed */ + if (globals.truncate_agents) { + sql = switch_mprintf("delete from agents;"); + cc_execute_sql(NULL, sql, NULL); + switch_safe_free(sql); + } + /* Loading queue into memory struct */ if ((x_queues = switch_xml_child(cfg, "queues"))) { for (x_queue = switch_xml_child(x_queues, "queue"); x_queue; x_queue = x_queue->next) { From 6a54a606022560aeedff5891fc0e85af06f803de Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Thu, 9 Jun 2016 17:13:18 -0300 Subject: [PATCH 67/72] FS-9249 [verto_communicator] Closing settings panel if the user clicks outside the element --- html5/verto/verto_communicator/bower.json | 3 ++- html5/verto/verto_communicator/src/index.html | 1 + html5/verto/verto_communicator/src/partials/settings.html | 2 +- html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/html5/verto/verto_communicator/bower.json b/html5/verto/verto_communicator/bower.json index 975807de00..9722da6eb8 100644 --- a/html5/verto/verto_communicator/bower.json +++ b/html5/verto/verto_communicator/bower.json @@ -45,7 +45,8 @@ "angular-bootstrap": "~0.14.3", "bootstrap-material-design": "~0.3.0", "angular-translate": "~2.10.0", - "angular-translate-loader-static-files": "~2.10.0" + "angular-translate-loader-static-files": "~2.10.0", + "angular-click-outside": "^2.8.3" }, "resolutions": { "angular": "~1.3.15", diff --git a/html5/verto/verto_communicator/src/index.html b/html5/verto/verto_communicator/src/index.html index 736ab14974..e886875756 100644 --- a/html5/verto/verto_communicator/src/index.html +++ b/html5/verto/verto_communicator/src/index.html @@ -99,6 +99,7 @@ + diff --git a/html5/verto/verto_communicator/src/partials/settings.html b/html5/verto/verto_communicator/src/partials/settings.html index 96d19db0b7..d806f3e2b0 100644 --- a/html5/verto/verto_communicator/src/partials/settings.html +++ b/html5/verto/verto_communicator/src/partials/settings.html @@ -1,4 +1,4 @@ -
+
diff --git a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js index 80b81236da..dc3ce4a181 100644 --- a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js +++ b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js @@ -18,6 +18,7 @@ 'ui.bootstrap', 'directive.g+signin', 'pascalprecht.translate', + 'angular-click-outside', ]); vertoApp.constant('configLanguages', { From 082be73f315863d94a0db4b4a377b6885a504c05 Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Thu, 9 Jun 2016 17:26:48 -0300 Subject: [PATCH 68/72] FS-9249 [verto_communicator] dedicated function to close settings --- html5/verto/verto_communicator/src/partials/settings.html | 2 +- .../src/vertoControllers/controllers/MainController.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/html5/verto/verto_communicator/src/partials/settings.html b/html5/verto/verto_communicator/src/partials/settings.html index d806f3e2b0..51b80dda16 100644 --- a/html5/verto/verto_communicator/src/partials/settings.html +++ b/html5/verto/verto_communicator/src/partials/settings.html @@ -1,4 +1,4 @@ -
+
diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index b1a3794c12..6f61816c82 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -290,6 +290,11 @@ $rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled')); }; + $scope.closeSettings = function() { + var settingsEl = angular.element(document.querySelector('#settings')); + settingsEl.removeClass('toggled'); + }; + $scope.goFullscreen = function() { if (storage.data.userStatus !== 'connected') { return; From 2425cd53a484b8c0597a91ea6812d8f5e7efbcba Mon Sep 17 00:00:00 2001 From: Italo Rossi Date: Thu, 9 Jun 2016 17:41:07 -0300 Subject: [PATCH 69/72] FS-9250 [verto_communicator] Putting factory reset button back --- html5/verto/verto_communicator/src/locales/locale-en.json | 3 ++- html5/verto/verto_communicator/src/locales/locale-pt.json | 3 ++- html5/verto/verto_communicator/src/partials/settings.html | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/html5/verto/verto_communicator/src/locales/locale-en.json b/html5/verto/verto_communicator/src/locales/locale-en.json index c8c59ace10..ade59cc7d4 100644 --- a/html5/verto/verto_communicator/src/locales/locale-en.json +++ b/html5/verto/verto_communicator/src/locales/locale-en.json @@ -149,5 +149,6 @@ "CHAT_GAIN_MINUS": "Gain -", "CHAT_GAIN_PLUS": "Gain +", "LANGUAGE": "Language:", - "BROWSER_LANGUAGE": "Browser Language" + "BROWSER_LANGUAGE": "Browser Language", + "FACTORY_RESET_SETTINGS": "Factory Reset Settings" } diff --git a/html5/verto/verto_communicator/src/locales/locale-pt.json b/html5/verto/verto_communicator/src/locales/locale-pt.json index 4bd236f855..19f04512ba 100644 --- a/html5/verto/verto_communicator/src/locales/locale-pt.json +++ b/html5/verto/verto_communicator/src/locales/locale-pt.json @@ -147,5 +147,6 @@ "CHAT_VOL_MINUS": "Vol -", "CHAT_VOL_PLUS": "Vol +", "CHAT_GAIN_MINUS": "Ganho -", - "CHAT_GAIN_PLUS": "Ganho +" + "CHAT_GAIN_PLUS": "Ganho +", + "FACTORY_RESET_SETTINGS": "Redefinir configurações" } diff --git a/html5/verto/verto_communicator/src/partials/settings.html b/html5/verto/verto_communicator/src/partials/settings.html index 51b80dda16..7e15a24e3b 100644 --- a/html5/verto/verto_communicator/src/partials/settings.html +++ b/html5/verto/verto_communicator/src/partials/settings.html @@ -162,6 +162,7 @@ ng-options="item.id as item.label for item in verto.bandwidth">
+
From d4daa8a0519a7834210b7cd1aa0fa151df148c6e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Jun 2016 15:01:37 -0500 Subject: [PATCH 70/72] FS-9246 #resolve [No Audio after Call transfer ] --- src/switch_rtp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index f30d82f5b7..0649be6c2d 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5175,7 +5175,11 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval) { switch_core_timer_sync(&rtp_session->timer); } - + + if (rtp_session->session) { + switch_ivr_parse_all_messages(rtp_session->session); + } + block = 0; } From 27e4615c8c8198ad07c872e207e996cbd4bb6c44 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 10 Jun 2016 15:48:01 -0500 Subject: [PATCH 71/72] FS-9244 #resolve [RFC2833 payload_type offered is ignored] --- src/switch_core_media.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 93bc8f4fb0..f1295b0ee5 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -4668,8 +4668,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (best_te) { smh->mparams->te_rate = best_te_rate; - - if (smh->mparams->dtmf_type == DTMF_AUTO) { + + if (smh->mparams->dtmf_type == DTMF_AUTO || smh->mparams->dtmf_type == DTMF_2833 || + switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF)) { if (sdp_type == SDP_TYPE_REQUEST) { smh->mparams->te = smh->mparams->recv_te = (switch_payload_t) best_te; switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833"); From ee4c01b05e00268dc13c7e4add9bac2120442509 Mon Sep 17 00:00:00 2001 From: Piotr Gregor Date: Fri, 10 Jun 2016 23:13:15 +0200 Subject: [PATCH 72/72] FS-9254: [avmd] fix windows build Fix int-to-uint8_t conversion warnings due to usage of switch_true when parsing config --- src/mod/applications/mod_avmd/mod_avmd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index f7caa15fc9..19f0ed71b0 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -822,13 +822,13 @@ avmd_parse_cmd_data_one_entry(char *candidate, struct avmd_settings *settings) /* candidate string has "=" somewhere in the middle and some value, * try to find what option it is by comparing at most given number of bytes */ if (!strcmp(key, "debug")) { - settings->debug = switch_true(val); + settings->debug = (uint8_t) switch_true(val); } else if (!strcmp(key, "report_status")) { - settings->report_status = switch_true(val); + settings->report_status = (uint8_t) switch_true(val); } else if (!strcmp(key, "fast_math")) { - settings->fast_math = switch_true(val); + settings->fast_math = (uint8_t) switch_true(val); } else if (!strcmp(key, "require_continuous_streak")) { - settings->require_continuous_streak = switch_true(val); + settings->require_continuous_streak = (uint8_t) switch_true(val); } else if (!strcmp(key, "sample_n_continuous_streak")) { if(avmd_parse_u16_user_input(val, &settings->sample_n_continuous_streak, 0, UINT16_MAX) == -1) { return SWITCH_STATUS_FALSE; @@ -838,11 +838,11 @@ avmd_parse_cmd_data_one_entry(char *candidate, struct avmd_settings *settings) return SWITCH_STATUS_FALSE; } } else if (!strcmp(key, "simplified_estimation")) { - settings->simplified_estimation = switch_true(val); + settings->simplified_estimation = (uint8_t) switch_true(val); } else if (!strcmp(key, "inbound_channel")) { - settings->inbound_channnel = switch_true(val); + settings->inbound_channnel = (uint8_t) switch_true(val); } else if (!strcmp(key, "outbound_channel")) { - settings->outbound_channnel = switch_true(val); + settings->outbound_channnel = (uint8_t) switch_true(val); } else { return SWITCH_STATUS_NOTFOUND; }