From f917a72c8451416ed992d798cabddee0de5b9b5b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 21 Sep 2015 18:55:21 -0500 Subject: [PATCH 001/127] FS-8188 add park_after_early_bridge transfer_after_early_bridge variables --- src/include/switch_types.h | 2 ++ src/switch_ivr_bridge.c | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 126f722ce2..5805d5d039 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -215,7 +215,9 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_LOCAL_VIDEO_PORT_VARIABLE "local_video_port" #define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE "hangup_after_bridge" #define SWITCH_PARK_AFTER_BRIDGE_VARIABLE "park_after_bridge" +#define SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE "park_after_early_bridge" #define SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE "transfer_after_bridge" +#define SWITCH_TRANSFER_AFTER_EARLY_BRIDGE_VARIABLE "transfer_after_early_bridge" #define SWITCH_EXEC_AFTER_BRIDGE_APP_VARIABLE "exec_after_bridge_app" #define SWITCH_EXEC_AFTER_BRIDGE_ARG_VARIABLE "exec_after_bridge_arg" #define SWITCH_MAX_FORWARDS_VARIABLE "max_forwards" diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index e25fff1bf5..917021005b 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -1696,6 +1696,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_call_cause_t cause = switch_channel_get_cause(peer_channel); const char *hup = switch_channel_get_variable(caller_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE); int explicit = 0; + int answered = 0; + int early = 0; if (cause == SWITCH_CAUSE_NONE) { cause = SWITCH_CAUSE_NORMAL_CLEARING; @@ -1716,16 +1718,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses switch_channel_hangup(caller_channel, cause); } - if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) || - (switch_channel_test_flag(peer_channel, CF_ANSWERED) && state < CS_HANGUP)) { + answered = switch_channel_test_flag(peer_channel, CF_ANSWERED); + early = switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA); + + if ((state != CS_EXECUTE && state != CS_SOFT_EXECUTE && state != CS_PARK && state != CS_ROUTING) || ((answered || early) && state < CS_HANGUP)) { if (!switch_channel_test_flag(caller_channel, CF_TRANSFER)) { - if (switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) { + + if ((answered && switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE))) || + switch_true(switch_channel_get_variable(caller_channel, SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE))) { switch_ivr_park_session(session); - } else if ((var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) { + } else if ((answered && (var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_BRIDGE_VARIABLE))) || + (var = switch_channel_get_variable(caller_channel, SWITCH_TRANSFER_AFTER_EARLY_BRIDGE_VARIABLE))) { transfer_after_bridge(session, var); - } else { - if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) && switch_true(hup))) { + } else if (answered) { + if (switch_true(hup)) { if (switch_channel_test_flag(peer_channel, CF_INTERCEPTED)) { switch_channel_set_flag(peer_channel, CF_INTERCEPT); } From b6831996881a6646aa56170b62496facde4ae7bd Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 8 Nov 2015 16:26:46 +0100 Subject: [PATCH 002/127] switch_xml_set_attr: fix inconsistent state on error paths Partially rewrite switch_xml_set_attr to fix memory leaks, uninitialized argument values and use-after free warnings from Clang static analyzer. Fixes these problems: - Add some comments and a new variable such that the code can more easily be audited / understood. - Always clear SWITCH_XML_DUP flag even if an error occurred to prevent free()'ing static strings on future invocations. - Keep the attribute list in a consistent state even if one of the memory allocation fails. - Keep allocation metadata in a consistent state when shrinking of the attribute lists fails. Previously the metadata was not updated, resulting in a wrong mapping from attributes to allocation flags. - Fix memory leaks when allocations fail. Previous behavior: invalid memory accesses are possible after a memory allocation failure, previous attributes may be lost. New behavior: attributes list is always valid, a new attribute is either set (or not), attributes can always be removed. --- src/switch_xml.c | 103 +++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 35 deletions(-) diff --git a/src/switch_xml.c b/src/switch_xml.c index 43ffabfcc7..1173eb0155 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -2944,58 +2944,91 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_set_txt(switch_xml_t xml, const char *tx of NULL will remove the specified attribute. Returns the tag given */ SWITCH_DECLARE(switch_xml_t) switch_xml_set_attr(switch_xml_t xml, const char *name, const char *value) { - int l = 0, c; + int l = 0, attr_number, c; + /* After adding the first attribute, xml->attr = { name1, val1, name2, val2, + * ..., nameN, valN, NULL, alloc_flags }. alloc_flags tracks how the memory + * for each attr and value is managed. */ + char *alloc_flags; if (!xml) return NULL; while (xml->attr[l] && strcmp(xml->attr[l], name)) l += 2; + attr_number = l / 2; + if (!xml->attr[l]) { /* not found, add as new attribute */ if (!value) - return xml; /* nothing to do */ + goto cleanup; /* not found, no need to remove attribute */ if (xml->attr == SWITCH_XML_NIL) { /* first attribute */ - xml->attr = (char **) malloc(4 * sizeof(char *)); - if (!xml->attr) - return NULL; - xml->attr[1] = strdup(""); /* empty list of malloced names/vals */ + char ** tmp = (char **) malloc(4 * sizeof(char *)); + if (!tmp) + goto cleanup; + xml->attr = tmp; + assert(l == 0); /* name of SWITCH_XML_NIL is assumed to be empty */ + xml->attr[0] = NULL; /* terminator */ + xml->attr[1] = NULL; /* empty list of malloced names/vals */ } else { char **tmp = (char **) realloc(xml->attr, (l + 4) * sizeof(char *)); if (!tmp) - return xml; + goto cleanup; xml->attr = tmp; } + /* Extend list of allocation flags for the new attribute */ + alloc_flags = (char *)realloc(xml->attr[l + 1], attr_number + 1); + if (!alloc_flags) + goto cleanup; + alloc_flags[attr_number + 1] = '\0'; /* terminate list */ + /* Add new attribute, the value will be set further below. */ xml->attr[l] = (char *) name; /* set attribute name */ - xml->attr[l + 2] = NULL; /* null terminate attribute list */ - xml->attr[l + 3] = (char *) realloc(xml->attr[l + 1], (c = (int) strlen(xml->attr[l + 1])) + 2); - strcpy(xml->attr[l + 3] + c, " "); /* set name/value as not malloced */ + name = NULL; /* control of memory is transferred */ + l += 2; + + xml->attr[l] = NULL; /* null terminate attribute list */ + xml->attr[l + 1] = alloc_flags; if (xml->flags & SWITCH_XML_DUP) - xml->attr[l + 3][c] = SWITCH_XML_NAMEM; - } else if (xml->flags & SWITCH_XML_DUP) - free((char *) name); /* name was strduped */ - - for (c = l; xml->attr[c]; c += 2); /* find end of attribute list */ - if (xml->attr[c + 1][l / 2] & SWITCH_XML_TXTM) - free(xml->attr[l + 1]); /* old val */ - if (xml->flags & SWITCH_XML_DUP) - xml->attr[c + 1][l / 2] |= SWITCH_XML_TXTM; - else - xml->attr[c + 1][l / 2] &= ~SWITCH_XML_TXTM; - - if (value) - xml->attr[l + 1] = (char *) value; /* set attribute value */ - else { /* remove attribute */ - char **tmp; - if (xml->attr[c + 1][l / 2] & SWITCH_XML_NAMEM) - free(xml->attr[l]); - memmove(xml->attr + l, xml->attr + l + 2, (c - l + 2) * sizeof(char *)); - tmp = (char **) realloc(xml->attr, (c + 2) * sizeof(char *)); - if (!tmp) - return xml; - xml->attr = tmp; - memmove(xml->attr[c + 1] + (l / 2), xml->attr[c + 1] + (l / 2) + 1, (c / 2) - (l / 2)); /* fix list of which name/vals are malloced */ + alloc_flags[attr_number] = SWITCH_XML_NAMEM; + else + alloc_flags[attr_number] = ' '; /* dummy value */ + } else { + while (xml->attr[l]) l += 2; + alloc_flags = xml->attr[l + 1]; + } + + c = 2 * attr_number; /* index of the current attribute name */ + /* l points to the index of the terminator name */ + + if (alloc_flags[attr_number] & SWITCH_XML_TXTM) + free(xml->attr[c + 1]); /* old val */ + if (xml->flags & SWITCH_XML_DUP) + alloc_flags[attr_number] |= SWITCH_XML_TXTM; + else + alloc_flags[attr_number] &= ~SWITCH_XML_TXTM; + + if (value) { + xml->attr[c + 1] = (char *) value; /* set attribute value */ + value = NULL; /* control of memory is transferred */ + } else { /* remove attribute */ + char **tmp; + /* free name if it was dynamically allocated (value is handled above) */ + if (alloc_flags[attr_number] & SWITCH_XML_NAMEM) + free(xml->attr[c]); + + /* drop (name, value) pair from attribute list */ + memmove(xml->attr + c, xml->attr + c + 2, (l - c) * sizeof(char *)); + tmp = (char **) realloc(xml->attr, l * sizeof(char *)); + if (tmp) /* try to shrink when possible */ + xml->attr = tmp; + + memmove(alloc_flags + attr_number, alloc_flags + attr_number + 1, (l - c) / 2); /* shrink allocation info */ + } + +cleanup: + if (xml->flags & SWITCH_XML_DUP) { + free((char *) name); /* name was strduped */ + free((char *) value); /* name was strduped, but an error occurred */ + xml->flags &= ~SWITCH_XML_DUP; /* clear strdup() flag */ } - xml->flags &= ~SWITCH_XML_DUP; /* clear strdup() flag */ return xml; } From 48d6a5f6a8fb21a7e20302cfdd4ff012288b3892 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 8 Nov 2015 18:12:54 +0100 Subject: [PATCH 003/127] switch_xml_decode: avoid NUL injection strtol can parse negative values which opens the hole for a NUL injection. The (invalid) entity "&#-256;" is parsed as 0xFFFFFF00 which (when casted to a char) becomes 0. Avoid this attack by using unsigned long integers. To avoid undefined behavior due to negative shifts, restrict the upper bound of the code points to the UTF-8 limits. (Add an assertion to make the Clang static analyzer happy.) Note: due to the specification of strtol, leading spaces and minus/plus signs are also allowed, explicitly check for an integer. "�x1;" is still accepted, but that is considered a minor issue. --- src/switch_xml.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/switch_xml.c b/src/switch_xml.c index 1173eb0155..50118720e0 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -538,7 +538,7 @@ static switch_xml_t switch_xml_err(switch_xml_root_t root, char *s, const char * static char *switch_xml_decode(char *s, char **ent, char t) { char *e, *r = s, *m = s; - long b, c, d, l; + unsigned long b, c, d, l; for (; *s; s++) { /* normalize line endings */ while (*s == '\r') { @@ -555,10 +555,17 @@ static char *switch_xml_decode(char *s, char **ent, char t) if (!*s) break; else if (t != 'c' && !strncmp(s, "&#", 2)) { /* character reference */ - if (s[2] == 'x') - c = strtol(s + 3, &e, 16); /* base 16 */ - else - c = strtol(s + 2, &e, 10); /* base 10 */ + char *code = s + 2; + int base = 10; + if (*code == 'x') { + code++; + base = 16; + } + if (!isxdigit((int)*code)) { /* "&# 1;" and "&#-1;" are invalid */ + s++; + continue; + } + c = strtoul(code, &e, base); if (!c || *e != ';') { s++; continue; @@ -566,10 +573,14 @@ static char *switch_xml_decode(char *s, char **ent, char t) /* not a character ref */ if (c < 0x80) *(s++) = (char) c; /* US-ASCII subset */ - else { /* multi-byte UTF-8 sequence */ + else if (c > 0x7FFFFFFF) { /* out of UTF-8 range */ + s++; + continue; + } else { /* multi-byte UTF-8 sequence */ for (b = 0, d = c; d; d /= 2) b++; /* number of bits in c */ b = (b - 2) / 5; /* number of bytes in payload */ + assert(b < 7); /* because c <= 0x7FFFFFFF */ *(s++) = (char) ((0xFF << (7 - b)) | (c >> (6 * b))); /* head */ while (b) *(s++) = (char) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */ @@ -580,8 +591,8 @@ static char *switch_xml_decode(char *s, char **ent, char t) for (b = 0; ent[b] && strncmp(s + 1, ent[b], strlen(ent[b])); b += 2); /* find entity in entity list */ if (ent[b++]) { /* found a match */ - if ((c = (long) strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) { - l = (d = (long) (s - r)) + c + (long) strlen(e); /* new length */ + if ((c = (unsigned long) strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) { + l = (d = (unsigned long) (s - r)) + c + (unsigned long) strlen(e); /* new length */ if (l) { if (r == m) { char *tmp = (char *) malloc(l); @@ -618,7 +629,7 @@ static char *switch_xml_decode(char *s, char **ent, char t) if (t == '*') { /* normalize spaces for non-cdata attributes */ for (s = r; *s; s++) { - if ((l = (long) strspn(s, " "))) + if ((l = (unsigned long) strspn(s, " "))) memmove(s, s + l, strlen(s + l) + 1); while (*s && *s != ' ') s++; From 8c540c6632fc083b551c7e4966d72ad79b2ed0b4 Mon Sep 17 00:00:00 2001 From: Andrew Cassidy Date: Tue, 10 Nov 2015 21:03:03 +0000 Subject: [PATCH 004/127] FS-8432 fixes timestamp type resolution, adds new header of type uint64 to carry microsecond resolution timestamp --- src/mod/event_handlers/mod_amqp/mod_amqp_producer.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c b/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c index 3c82aa6225..980cad8a05 100644 --- a/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c +++ b/src/mod/event_handlers/mod_amqp/mod_amqp_producer.c @@ -391,9 +391,10 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg) /* This should only be called in a single threaded context from the producer profile send thread */ switch_status_t mod_amqp_producer_send(mod_amqp_producer_profile_t *profile, mod_amqp_message_t *msg) { - amqp_table_entry_t messageTableEntries[1]; + amqp_table_entry_t messageTableEntries[2]; amqp_basic_properties_t props; int status; + uint64_t timestamp; if (! profile->conn_active) { /* No connection, so we can not send the message. */ @@ -415,9 +416,13 @@ switch_status_t mod_amqp_producer_send(mod_amqp_producer_profile_t *profile, mod props.timestamp = (uint64_t)time(NULL); props.headers.num_entries = 1; props.headers.entries = messageTableEntries; + timestamp = (uint64_t)switch_micro_time_now(); messageTableEntries[0].key = amqp_cstring_bytes("x_Liquid_MessageSentTimeStamp"); messageTableEntries[0].value.kind = AMQP_FIELD_KIND_TIMESTAMP; - messageTableEntries[0].value.value.u64 = (uint64_t)switch_micro_time_now(); + messageTableEntries[0].value.value.u64 = (uint64_t)(timestamp / 1000000); + messageTableEntries[1].key = amqp_cstring_bytes("x_Liquid_MessageSentTimeStampMicro"); + messageTableEntries[1].value.kind = AMQP_FIELD_KIND_U64; + messageTableEntries[1].value.value.u64 = timestamp; } status = amqp_basic_publish( From accc6206dd3fd355e029837dd7a079b70fea87f6 Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Tue, 17 Nov 2015 16:30:17 -0300 Subject: [PATCH 005/127] FS-8550 [verto_communicator] - Now setting testSpeedJoin to false when 'auto' is disabled and changed instruction for closing modal in resetSettings() --- .../vertoControllers/controllers/ModalSettingsController.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js index 7bc9aa7452..6688f92842 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js @@ -43,7 +43,7 @@ if (confirm('Factory Reset Settings?')) { storage.factoryReset(); $scope.logout(); - $scope.ok(); + $modalInstance.close('Ok.'); window.location.reload(); }; }; @@ -54,6 +54,7 @@ $scope.mydata.outgoingBandwidth = 'default'; $scope.mydata.incomingBandwidth = 'default'; $scope.mydata.vidQual = 'hd'; + $scope.mydata.testSpeedJoin = false; } else { $scope.mydata.testSpeedJoin = true; } From 9e0f30c58b267278db1437b67b266d365a684770 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Thu, 19 Nov 2015 17:10:15 -0500 Subject: [PATCH 006/127] FS-8560 [mod_http_cache] add new parameter, connect-timeout This is the maximum time to wait, in seconds, for the HTTP GET or PUT to connect. If this value is not set or is set to 0, the default setting of 300 seconds is used. --- .../conf/autoload_configs/http_cache.conf.xml | 2 ++ .../mod_http_cache/mod_http_cache.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/mod/applications/mod_http_cache/conf/autoload_configs/http_cache.conf.xml b/src/mod/applications/mod_http_cache/conf/autoload_configs/http_cache.conf.xml index a5c3f46c76..3cb24348c6 100644 --- a/src/mod/applications/mod_http_cache/conf/autoload_configs/http_cache.conf.xml +++ b/src/mod/applications/mod_http_cache/conf/autoload_configs/http_cache.conf.xml @@ -8,6 +8,8 @@ + +

-
{{ member.name }}
+
{{ member.name }}
({{ member.number }})
Floor
-
Presenter
+
{{ member.status.video.reservationID }}
Screen Share

@@ -57,12 +57,6 @@ Mute/Unmute Video -
  • - - - Presenter - -
  • @@ -103,6 +97,21 @@ + + diff --git a/html5/verto/verto_communicator/src/partials/video_call.html b/html5/verto/verto_communicator/src/partials/video_call.html index 9633149c77..7fcb9b71b2 100644 --- a/html5/verto/verto_communicator/src/partials/video_call.html +++ b/html5/verto/verto_communicator/src/partials/video_call.html @@ -31,7 +31,7 @@ diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js index 3129db87c7..c990e0d5c2 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js @@ -49,6 +49,39 @@ }); }); + + $rootScope.$on('changedVideoLayout', function(event, layout) { + $scope.resIDs = getResByLayout(layout); + + // remove resIDs param to clear every members resID. + // passing $scope.resIDs results in preserving resIDs compatible + // with the current layout + clearMembersResID($scope.resIDs); + }); + + $rootScope.$on('conference.canvasInfo', function(event, data) { + $scope.currentLayout = data[0].layoutName; + $scope.resIDs = getResByLayout($scope.currentLayout); + }); + + function getResByLayout(layout) { + var layoutsData = verto.data.confLayoutsData; + for (var i = 0; i < layoutsData.length; i++) { + if (layoutsData[i].name === layout) { + return layoutsData[i].resIDS; + } + } + } + + // @preserve - a array of values to be preserved + function clearMembersResID(preserve) { + $scope.members.forEach(function(member) { + var resID = member.status.video.reservationID; + if (preserve && preserve.indexOf(resID) !== -1) return; + $scope.confResID(member.id, resID); + }); + }; + function findMemberByUUID(uuid) { var found = false; for (var idx in $scope.members) { @@ -171,6 +204,11 @@ verto.data.conf.presenter(memberID); }; + $scope.confResID = function(memberID, resID) { + console.log('Set', memberID, 'to', resID); + verto.setResevartionId(memberID, resID); + }; + $scope.confVideoFloor = function(memberID) { console.log('$scope.confVideoFloor'); verto.data.conf.videoFloor(memberID); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js index 93e510d5e3..4285ace586 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js @@ -73,6 +73,8 @@ $scope.confChangeVideoLayout = function(layout) { verto.data.conf.setVideoLayout(layout); + $scope.videoLayout = layout; + $rootScope.$emit('changedVideoLayout', layout); }; $scope.confChangeSpeaker = function(speakerId) { diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 9bf54c3cbd..4a46b09066 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -391,7 +391,27 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora if (message.action == 'response') { // This is a response with the video layouts list. if (message['conf-command'] == 'list-videoLayouts') { - data.confLayouts = message.responseData.sort(); + var rdata = []; + + for (var i in message.responseData) { + rdata.push(message.responseData[i].name); + } + + var options = rdata.sort(function(a, b) { + var ga = a.substring(0, 6) == "group:" ? true : false; + var gb = b.substring(0, 6) == "group:" ? true : false; + + if ((ga || gb) && ga != gb) { + return ga ? -1 : 1; + } + + return ( ( a == b ) ? 0 : ( ( a > b ) ? 1 : -1 ) ); + }); + data.confLayoutsData = message.responseData; + data.confLayouts = options; + } else if (message['conf-command'] == 'canvasInfo') { + data.canvasInfo = message.responseData; + $rootScope.$emit('conference.canvasInfo', message.responseData); } else { $rootScope.$emit('conference.broadcast', message); } @@ -402,6 +422,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora if (data.confRole == "moderator") { console.log('>>> conf.listVideoLayouts();'); conf.listVideoLayouts(); + conf.modCommand('canvasInfo'); } data.conf = conf; @@ -913,6 +934,12 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora data.conf.sendChat(message, "message"); }, /* + * Method is used to set a member's resevartion Id. + */ + setResevartionId: function(memberID, resID) { + data.conf.modCommand('vid-res-id', memberID, resID); + }, + /* * Method is used to send user2user chats. * VC does not yet support that. */ From 05ff8ec711d35c9817ef409e0ad2d55b76e898d7 Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Fri, 27 Nov 2015 18:03:13 -0300 Subject: [PATCH 035/127] FS-7800 [verto_communicator] - Added Canvas controls and now opening popup with original (master) dimensions --- .../verto_communicator/src/partials/chat.html | 18 +++++++ .../controllers/ChatController.js | 48 +++++++++++++++++++ .../controllers/InCallController.js | 8 ++-- .../src/vertoService/services/vertoService.js | 9 ++++ 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/html5/verto/verto_communicator/src/partials/chat.html b/html5/verto/verto_communicator/src/partials/chat.html index 23797d0b51..81eaf12912 100644 --- a/html5/verto/verto_communicator/src/partials/chat.html +++ b/html5/verto/verto_communicator/src/partials/chat.html @@ -99,6 +99,24 @@ Transfer
  • +
  • + + + Canvas In + +
  • +
  • + + + Canvas Out + +
  • +
  • + + + Layer + +
  • diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js index 99c6359c96..1e725857d2 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js @@ -196,6 +196,41 @@ }); }; + $scope.confCanvasIn = function(memberID, canvasID) { + if (canvasID) { + verto.setCanvasIn(memberID, canvasID); + return; + } + + shortPrompt('Please insert the Canvas Id', function(canvasID) { + console.log(memberID, canvasID); + verto.setCanvasIn(memberID, canvasID); + }); + + }; + + $scope.confCanvasOut = function(memberID, canvasID) { + if (canvasID) { + verto.setCanvasOut(memberID, canvasID); + return; + } + + shortPrompt('Please insert the Canvas Id', function(canvasID) { + verto.setCanvasOut(memberID, canvasID); + }); + }; + + $scope.confLayer = function(memberID, canvasID) { + if (canvasID) { + verto.setLayer(memberID, canvasID); + return; + } + + shortPrompt('Please insert the Layer', function(canvasID) { + verto.setLayer(memberID, canvasID); + }); + }; + $scope.confResetBanner = function(memberID) { console.log('$scope.confResetBanner'); var text = 'reset'; @@ -226,6 +261,19 @@ } }); }; + + function shortPrompt(text, cb) { + prompt({ + title: text, + input: true, + label: '', + value: '', + }).then(function(val) { + if (val && cb) { + cb(val); + } + }); + } } ]); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js index 10887d3195..ab59171d85 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js @@ -81,12 +81,14 @@ }; $scope.confPopup = function(canvas_id) { + var video = document.getElementById('webcam'); var s = window.location.href; var curCall = verto.data.call.callID; var extension = verto.data.call.params.remote_caller_id_number; - var width = 465, height = 360; - var x = screen.width/2 - width/2 - var y = screen.height/2 - height/2 + var width = webcam.offsetWidth; + var height = webcam.offsetHeight + 100; + var x = (screen.width - width)/2 + var y = (screen.height - height)/2 s = s.replace(/\#.*/, ''); s += "#/?sessid=random&master=" + curCall + "&watcher=true&extension=" + extension+ "&canvas_id=" + canvas_id; diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 68ed52c4bc..480ccb13ac 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -919,6 +919,15 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora sendConferenceChat: function(message) { data.conf.sendChat(message, "message"); }, + setCanvasIn: function(memberID, canvasID) { + data.conf.modCommand('vid-canvas', memberID, canvasID); + }, + setCanvasOut: function(memberID, canvasID) { + data.conf.modCommand('vid-watching-canvas', memberID, canvasID); + }, + setLayer: function(memberID, canvasID) { + data.conf.modCommand('vid-layer', memberID, canvasID); + }, /* * Method is used to send user2user chats. * VC does not yet support that. From fabca410010b48b20854fe78343b6d31207b88bb Mon Sep 17 00:00:00 2001 From: Rob Wu Date: Sat, 28 Nov 2015 19:17:56 +0100 Subject: [PATCH 036/127] FS-8585: [mod_commands] group_call: expand {} and <> to [] for each dial string Channel variables in dial strings can be set through <>, {} or []. applies to every channel. {foo=bar} applies to every channel, excluding channels delimited by :_:. [foo=bar] only applies to the channel that follows [foo=bar]. Before this patch, group_call looked up users in the directory and replaced {} with []. This logic does not work if the user has more than one dial string, e.g. if multiple-registrations is set to true, and more than two devices register under the same user. This patch fixes the issue by stripping <> and {}, and inserting the dial string before each individual dial string for each user. The semantics of the "local_clobber" variable and the '|', ',' and ':_:' delimiters are fully supported. --- .../applications/mod_commands/mod_commands.c | 153 ++++++++++++++---- 1 file changed, 123 insertions(+), 30 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 26f895e8a4..abcd79490f 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -299,6 +299,117 @@ end: return; } +char *find_channel_brackets(char *data, char start, char end, char **front, int *local_clobber) +{ + char *p; + char *last_end = NULL; + + *front = NULL; + p = data; + while ((p = switch_strchr_strict(p, start, " "))) { + char *next_end = switch_find_end_paren(p, start, end); + if (!next_end) { + break; + } + if (!*front) { + *front = p; + } + *p = '['; + last_end = next_end; + *last_end = ']'; + p = last_end + 1; + } + if (!last_end) { + if (local_clobber) { + *local_clobber = 0; + } + return data; + } + + *last_end = '\0'; + if (local_clobber) { + /* Would be nice to use switch_true to account for other valid boolean + representations, but this is better than nothing: */ + *local_clobber = strstr(data, "local_var_clobber=true") != NULL; + } + return last_end + 1; +} + +char *find_channel_delim(char *p, const char **out) +{ + *out = ""; + for (; *p; p++) { + if (*p == ',') { + *out = ","; + break; + } + if (*p == '|') { + *out = "|"; + break; + } + if (!strncmp(p, SWITCH_ENT_ORIGINATE_DELIM, strlen(SWITCH_ENT_ORIGINATE_DELIM))) { + *out = SWITCH_ENT_ORIGINATE_DELIM; + break; + } + } + return p; +} + +/* Read <..> and {..}, and inserts [..] before every leg dial string. */ +void output_flattened_dial_string(char *data, switch_stream_handle_t *stream) +{ + char *p; + char *vars_start_ent; + char *vars_start_all; + char *vars_start_leg; + int local_clobber_ent; + int local_clobber_all; + const char *delim; + char *leg_dial_string; + + /* -3 because ":_:" is the longest delimiter, of length 3. */ + p = find_channel_delim(end_of_p(data) - 3, &delim); + *p = '\0'; + + p = data; + p = find_channel_brackets(p, '<', '>', &vars_start_ent, &local_clobber_ent); + p = find_channel_brackets(p, '{', '}', &vars_start_all, &local_clobber_all); + + while (*p) { + p = find_channel_brackets(p, '[', ']', &vars_start_leg, NULL); + if (vars_start_leg) { + if (vars_start_ent && !local_clobber_ent) { + stream->write_function(stream, "%s]", vars_start_ent); + } + if (vars_start_all && !local_clobber_all) { + stream->write_function(stream, "%s]", vars_start_all); + } + stream->write_function(stream, "%s]", vars_start_leg); + } + + while (*p == ' ') p++; + + if (*p) { + if (vars_start_all && (!vars_start_leg || local_clobber_all)) { + stream->write_function(stream, "%s]", vars_start_all); + } + if (vars_start_ent && (!vars_start_leg || local_clobber_ent)) { + stream->write_function(stream, "%s]", vars_start_ent); + } + leg_dial_string = p; + p = find_channel_delim(p, &delim); + if (*p) { + *p = '\0'; + p += strlen(delim); + if (!strcmp(delim, SWITCH_ENT_ORIGINATE_DELIM)) { + p = find_channel_brackets(p, '{', '}', &vars_start_all, &local_clobber_all); + } + } + stream->write_function(stream, "%s%s", leg_dial_string, delim); + } + } +} + #define LIST_USERS_SYNTAX "[group ] [domain ] [user ] [context ]" SWITCH_STANDARD_API(list_users_function) { @@ -904,9 +1015,6 @@ SWITCH_STANDARD_API(group_call_function) if (!zstr(domain)) { switch_xml_t xml, x_domain, x_group; switch_event_t *params; - switch_stream_handle_t dstream = { 0 }; - - SWITCH_STANDARD_STREAM(dstream); switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group", group_name); @@ -917,8 +1025,6 @@ SWITCH_STANDARD_API(group_call_function) switch_xml_t x_user, x_users, x_param, x_params, my_x_user; if ((x_users = switch_xml_child(x_group, "users"))) { - ok++; - for (x_user = switch_xml_child(x_users, "user"); x_user; x_user = x_user->next) { const char *id = switch_xml_attr_soft(x_user, "id"); const char *x_user_type = switch_xml_attr_soft(x_user, "type"); @@ -1006,11 +1112,22 @@ SWITCH_STANDARD_API(group_call_function) } if (d_dest) { - dstream.write_function(&dstream, "%s%s", d_dest, call_delim); + switch_stream_handle_t dstream = { 0 }; + SWITCH_STANDARD_STREAM(dstream); + dstream.write_function(&dstream, "%s", d_dest); if (d_dest != dest) { free(d_dest); } + if (dstream.data) { + if (++ok > 1) { + stream->write_function(stream, "%s", call_delim); + } + + output_flattened_dial_string((char*)dstream.data, stream); + + free(dstream.data); + } } done_x_user: @@ -1019,30 +1136,6 @@ SWITCH_STANDARD_API(group_call_function) xml_for_pointer = NULL; } } - - if (ok && dstream.data) { - char *data = (char *) dstream.data; - char *p; - - if ((p = strstr(end_of_p(data) - 3, call_delim))) { - *p = '\0'; - } - - for (p = data; p && *p; p++) { - if (*p == '{') { - *p = '['; - } else if (*p == '}') { - *p = ']'; - } - } - - - stream->write_function(stream, "%s", data); - free(dstream.data); - } else { - ok = 0; - } - } } switch_xml_free(xml); From b0b715c9c37fb454de45bdff14c3a821d5ebf011 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 30 Nov 2015 16:54:04 -0600 Subject: [PATCH 037/127] FS-8589 #resolve [Using conference playback with full-screen=true is not working correctly] --- .../mod_conference/conference_video.c | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index ad22ca74f6..617330e0ae 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -2058,9 +2058,8 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr canvas->send_keyframe = 1; } - if (!conference->playing_video_file) { - switch_core_timer_next(&canvas->timer); - } + + switch_core_timer_next(&canvas->timer); now = switch_micro_time_now(); @@ -2211,11 +2210,6 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr continue; } - if (conference->playing_video_file) { - switch_core_session_rwunlock(imember->session); - continue; - } - //VIDFLOOR if (canvas->layout_floor_id > -1 && imember->id == conference->video_floor_holder && imember->video_layer_id != canvas->layout_floor_id) { @@ -2226,6 +2220,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr layer = NULL; + if (conference->playing_video_file) { + switch_img_free(&img); + switch_core_session_rwunlock(imember->session); + continue; + } + + switch_mutex_lock(canvas->mutex); @@ -2595,7 +2596,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_mutex_unlock(conference->member_mutex); } else { - + if (conference->async_fnode && (conference->async_fnode->canvas_id == canvas->canvas_id || conference->async_fnode->canvas_id == -1)) { if (conference->async_fnode->layer_id > -1) { conference_video_patch_fnode(canvas, conference->async_fnode); @@ -2686,20 +2687,20 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (canvas->play_file) { canvas->send_keyframe = 1; canvas->play_file = 0; - - canvas->timer.interval = 1; - canvas->timer.samples = 90; } - write_img = file_img = write_frame.img; + switch_img_free(&file_img); + file_img = write_img = write_frame.img; switch_core_timer_sync(&canvas->timer); timestamp = canvas->timer.samplecount; + } else if (file_img) { + write_img = file_img; } } else if (file_img) { switch_img_free(&file_img); } - + write_frame.img = write_img; wait_for_canvas(canvas); @@ -2893,9 +2894,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ canvas->send_keyframe = 1; } - if (!conference->playing_video_file) { - switch_core_timer_next(&canvas->timer); - } + switch_core_timer_next(&canvas->timer); now = switch_micro_time_now(); From cbc09c62e549988cdedd69428df39e92b38b02f2 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 30 Nov 2015 17:03:58 -0600 Subject: [PATCH 038/127] FS-8590 #resolve [Verto Communicator sends malformed vid-res-id command when changing layouts] --- .../src/vertoControllers/controllers/ChatController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js index 0e4d821288..75947db607 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js @@ -77,7 +77,7 @@ function clearMembersResID(preserve) { $scope.members.forEach(function(member) { var resID = member.status.video.reservationID; - if (preserve && preserve.indexOf(resID) !== -1) return; + if (resID && preserve && preserve.indexOf(resID) !== -1) return; $scope.confResID(member.id, resID); }); }; From 5f2dc448ce505dd929b946deb60f9a0affbcc7a6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Dec 2015 11:36:23 -0600 Subject: [PATCH 039/127] FS-8529 more improvment on same goal --- .../mod_conference/conference_video.c | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 617330e0ae..451b6143d1 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -2024,7 +2024,8 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr int do_refresh = 0; int last_file_count = 0; int layout_applied = 0; - + int files_playing = 0; + canvas->video_timer_reset = 1; packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN); @@ -2104,11 +2105,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (conference->async_fnode && switch_core_file_has_video(&conference->async_fnode->fh)) { check_async_file = 1; file_count++; + files_playing = 1; } if (conference->fnode && switch_core_file_has_video(&conference->fnode->fh)) { check_file = 1; file_count++; + files_playing = 1; } if (file_count != last_file_count) { @@ -2417,18 +2420,28 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } if (check_async_file) { - if (switch_core_file_read_video(&conference->async_fnode->fh, &file_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) { + switch_status_t st = switch_core_file_read_video(&conference->async_fnode->fh, &file_frame, SVR_FLUSH); + + if (st == SWITCH_STATUS_SUCCESS) { if ((async_file_img = file_frame.img)) { + switch_img_free(&file_imgs[j]); file_imgs[j++] = async_file_img; } + } else if (st == SWITCH_STATUS_BREAK) { + j++; } } if (check_file) { - if (switch_core_file_read_video(&conference->fnode->fh, &file_frame, SVR_FLUSH) == SWITCH_STATUS_SUCCESS) { + switch_status_t st = switch_core_file_read_video(&conference->fnode->fh, &file_frame, SVR_FLUSH); + + if (st == SWITCH_STATUS_SUCCESS) { if ((normal_file_img = file_frame.img)) { + switch_img_free(&file_imgs[j]); file_imgs[j++] = normal_file_img; } + } else if (st == SWITCH_STATUS_BREAK) { + j++; } } @@ -2441,13 +2454,15 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr continue; } - i = 0; - while (i < imember->canvas->total_layers) { - layer = &imember->canvas->layers[i++]; - switch_img_fill(layer->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &layer->canvas->bgcolor); + if (files_playing && !file_count) { + i = 0; + while (i < imember->canvas->total_layers) { + layer = &imember->canvas->layers[i++]; + switch_img_fill(layer->canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &layer->canvas->bgcolor); + } + i = 0; } - i = 0; - + if (!file_count && imember->canvas->layout_floor_id > -1 && imember->conference->video_floor_holder && imember->id != imember->conference->video_floor_holder) { @@ -2478,7 +2493,6 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (file_count && (conference->members_with_video + conference->members_with_avatar == 1)) { floor_layer = NULL; - continue; } if (!file_count && floor_layer && omember->id == conference->video_floor_holder) { @@ -2559,8 +2573,11 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_session_rwunlock(imember->session); } - switch_img_free(&normal_file_img); - switch_img_free(&async_file_img); + if (files_playing && !file_count) { + switch_img_free(&file_imgs[0]); + switch_img_free(&file_imgs[1]); + files_playing = 0; + } for (imember = conference->members; imember; imember = imember->next) { switch_frame_t *dupframe; From ca61d45412f9cf4c6186aadfb07a3454af390894 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Dec 2015 12:24:57 -0600 Subject: [PATCH 040/127] FS-8595 #resolve [Improve auto bitrate in personal canvas mode and do not let auto bitrate exceed native picture size] --- .../mod_conference/conference_video.c | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 451b6143d1..60b8f4a6cb 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1921,6 +1921,14 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_ switch_channel_get_name(member->channel), kps); } else { int max = 0; + switch_vid_params_t vid_params = { 0 }; + + switch_core_media_get_vid_params(imember->session, &vid_params); + + if (w > vid_params.width || h > vid_params.height) { + w = vid_params.width; + h = vid_params.height; + } if (layer) { kps = switch_calc_bitrate(w, h, member->conference->video_quality, (int)(member->conference->video_fps.fps)); @@ -2385,7 +2393,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (count_changed) { int total = conference->members_with_video; - + int kps; + switch_vid_params_t vid_params = { 0 }; + if (!conference_utils_test_flag(conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS)) { total += conference->members_with_avatar; } @@ -2405,6 +2415,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr conference_video_init_canvas_layers(conference, imember->canvas, vlayout); } } + + if (!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)); + conference_video_set_incoming_bitrate(imember, kps); + } } if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { @@ -2554,8 +2571,6 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr conference_video_scale_and_patch(layer, use_img, SWITCH_FALSE); } } - - conference_video_check_auto_bitrate(omember, layer); } for (j = 0; j < file_count; j++) { From 079040e4e7a349a442ec83eca5a0af9e15faa808 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Dec 2015 12:27:23 -0600 Subject: [PATCH 041/127] FS-8595 typo --- src/mod/applications/mod_conference/conference_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 60b8f4a6cb..e973f352fa 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1923,7 +1923,7 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_ int max = 0; switch_vid_params_t vid_params = { 0 }; - switch_core_media_get_vid_params(imember->session, &vid_params); + switch_core_media_get_vid_params(member->session, &vid_params); if (w > vid_params.width || h > vid_params.height) { w = vid_params.width; From f563760604f2bfa9225e9c8325aa8fca26e53491 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Dec 2015 13:21:34 -0600 Subject: [PATCH 042/127] FS-8588 #resolve [Unreliable digit collection] --- src/switch_ivr_async.c | 10 ++++++++++ src/switch_ivr_play_say.c | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index eaf68ec636..595ca3517b 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -79,6 +79,7 @@ struct switch_ivr_dmachine { void *user_data; switch_mutex_t *mutex; switch_status_t last_return; + uint8_t pinging; }; @@ -487,6 +488,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t * return SWITCH_STATUS_SUCCESS; } + if (dmachine->pinging) { + printf("doh\n"); + return SWITCH_STATUS_BREAK; + } + + dmachine->pinging = 1; + if (zstr(dmachine->digits) && !is_timeout) { r = SWITCH_STATUS_SUCCESS; } else if (dmachine->cur_digit_len > dmachine->max_digit_len) { @@ -579,6 +587,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t * dmachine->last_return = r; + dmachine->pinging = 0; + switch_mutex_unlock(dmachine->mutex); return r; diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 968c7d031d..89325b2c83 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1490,12 +1490,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { + switch_channel_dequeue_dtmf(channel, &dtmf); + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; done = 1; break; } - switch_channel_dequeue_dtmf(channel, &dtmf); + if (args->dmachine) { char ds[2] = {dtmf.digit, '\0'}; From 95a4bbc152b80e136086991c12e834b39cfaaca6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Dec 2015 13:54:20 -0600 Subject: [PATCH 043/127] FS-8588 fix deadlock in error condition --- src/switch_ivr_async.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 595ca3517b..456defaa3e 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -618,6 +618,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t * status = istatus; } } else { + switch_mutex_unlock(dmachine->mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "dmachine overflow error!\n"); status = SWITCH_STATUS_FALSE; } From ba9a480912b9c8afff1ea08dd7d5067e312d2b04 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 1 Dec 2015 14:22:52 -0600 Subject: [PATCH 044/127] FS-8588 remove debug --- src/switch_ivr_async.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 456defaa3e..bd6cb6f34f 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -489,7 +489,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t * } if (dmachine->pinging) { - printf("doh\n"); return SWITCH_STATUS_BREAK; } From 51d402dfdd3705063c70b0bff50a07182d500d52 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Dec 2015 10:23:25 -0600 Subject: [PATCH 045/127] FS-8599 #resolve [Workaround for Mozilla is no longer needed for video size] --- html5/verto/js/src/jquery.FSRTC.js | 22 ++++------------------ html5/verto/video_demo/js/verto-min.js | 5 ++--- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index 7d3e0ad2ec..b63a57e4e9 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -542,17 +542,10 @@ var bestFrameRate = obj.options.videoParams.vertoBestFrameRate; delete obj.options.videoParams.vertoBestFrameRate; - if (window.moz) { - video = obj.options.videoParams; - if (!video.width) video.width = video.minWidth; - if (!video.height) video.height = video.minHeight; - if (!video.frameRate) video.frameRate = video.minFrameRate; - } else { - video = { - mandatory: obj.options.videoParams, - optional: [] - } - } + video = { + mandatory: obj.options.videoParams, + optional: [] + } var useVideo = obj.options.useVideo; @@ -1124,13 +1117,6 @@ "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, diff --git a/html5/verto/video_demo/js/verto-min.js b/html5/verto/video_demo/js/verto-min.js index 0e5580299f..4a9e5a5c98 100644 --- a/html5/verto/video_demo/js/verto-min.js +++ b/html5/verto/video_demo/js/verto-min.js @@ -47,7 +47,7 @@ function onError(e){onStreamError(self,e);} var mediaParams=getMediaParams(self);console.log("Audio constraints",mediaParams.audio);console.log("Video constraints",mediaParams.video);if(self.options.useVideo&&self.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:self.options.videoParams,optional:[]},},localVideo:self.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});} getUserMedia({constraints:{audio:mediaParams.audio,video:mediaParams.video},video:mediaParams.useVideo,onsuccess:onSuccess,onerror:onError});};function getMediaParams(obj){var audio;if(obj.options.useMic&&obj.options.useMic==="none"){console.log("Microphone Disabled");audio=false;}else if(obj.options.videoParams&&obj.options.screenShare){console.error("SCREEN SHARE");audio=false;}else{audio={mandatory:obj.options.audioParams,optional:[]};if(obj.options.useMic!=="any"){audio.optional=[{sourceId:obj.options.useMic}]}} if(obj.options.useVideo&&obj.options.localVideo){getUserMedia({constraints:{audio:false,video:{mandatory:obj.options.videoParams,optional:[]},},localVideo:obj.options.localVideo,onsuccess:function(e){self.options.localVideoStream=e;console.log("local video ready");},onerror:function(e){console.error("local video error!");}});} -var video={};var bestFrameRate=obj.options.videoParams.vertoBestFrameRate;delete obj.options.videoParams.vertoBestFrameRate;if(window.moz){video=obj.options.videoParams;if(!video.width)video.width=video.minWidth;if(!video.height)video.height=video.minHeight;if(!video.frameRate)video.frameRate=video.minFrameRate;}else{video={mandatory:obj.options.videoParams,optional:[]}} +var video={};var bestFrameRate=obj.options.videoParams.vertoBestFrameRate;delete obj.options.videoParams.vertoBestFrameRate;video={mandatory:obj.options.videoParams,optional:[]} var useVideo=obj.options.useVideo;if(useVideo&&obj.options.useCamera&&obj.options.useCamera!=="none"){if(!video.optional){video.optional=[];} if(obj.options.useCamera!=="any"){video.optional.push({sourceId:obj.options.useCamera});} if(bestFrameRate&&!window.moz){video.optional.push({minFrameRate:bestFrameRate});}}else{console.log("Camera Disabled");video=false;useVideo=false;} @@ -93,8 +93,7 @@ return[w,h];} var resList=[[320,180],[320,240],[640,360],[640,480],[1280,720],[1920,1080]];var resI=0;var ttl=0;var checkRes=function(cam,func){if(resI>=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.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);}});} +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);} From 3400fac2f8243cca5f24c84839293eca6f5de8f6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Dec 2015 11:03:00 -0600 Subject: [PATCH 046/127] FS-8354 #resolve [G722 audio issues with mod_conference after fab435479ada61f2f9d726bad53ec31d002acd2f] --- .../applications/mod_conference/conference_member.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index 16d49e481a..36344a815d 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -1629,7 +1629,13 @@ int conference_member_setup_media(conference_member_t *member, conference_obj_t switch_mutex_lock(member->audio_out_mutex); - switch_core_session_get_read_impl(member->session, &read_impl); + if (!member->orig_read_impl.samples_per_second) { + switch_core_session_get_read_impl(member->session, &member->orig_read_impl); + member->native_rate = read_impl.samples_per_second; + } + + read_impl = member->orig_read_impl; + if (switch_core_codec_ready(&member->read_codec)) { switch_core_codec_destroy(&member->read_codec); @@ -1645,9 +1651,6 @@ int conference_member_setup_media(conference_member_t *member, conference_obj_t switch_resample_destroy(&member->read_resampler); } - switch_core_session_get_read_impl(member->session, &member->orig_read_impl); - member->native_rate = read_impl.samples_per_second; - /* Setup a Signed Linear codec for reading audio. */ if (switch_core_codec_init(&member->read_codec, "L16", From cebfc8158377c00d248796b182a26a93271984c8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Dec 2015 12:02:43 -0600 Subject: [PATCH 047/127] FS-8590 treat no res-id the same as clear --- src/mod/applications/mod_conference/conference_api.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 041591910c..dc9d683e7e 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1577,12 +1577,7 @@ switch_status_t conference_api_sub_vid_res_id(conference_member_t *member, switc return SWITCH_STATUS_SUCCESS; } - if (zstr(text)) { - stream->write_function(stream, "-ERR missing arg\n"); - return SWITCH_STATUS_SUCCESS; - } - - if (!strcasecmp(text, "clear") || (member->video_reservation_id && !strcasecmp(text, member->video_reservation_id))) { + if (zstr(text) || !strcasecmp(text, "clear") || (member->video_reservation_id && !strcasecmp(text, member->video_reservation_id))) { member->video_reservation_id = NULL; stream->write_function(stream, "+OK reservation_id cleared\n"); } else { From c021d22ea66e10fd33527fed2ef623834bb0af13 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 2 Dec 2015 15:08:53 -0600 Subject: [PATCH 048/127] FS-8602 #resolve [conference does not auto-generate layouts properly when callers with no camera are present] --- src/mod/applications/mod_conference/conference_video.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index e973f352fa..6a16604226 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -2088,8 +2088,9 @@ 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->channel && switch_channel_ready(imember->channel) && conference_utils_member_test_flag(imember, MFLAG_RUNNING) - && imember->canvas_id == canvas->canvas_id) { + if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO) && + conference_utils_member_test_flag(imember, MFLAG_RUNNING) + && imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) { canvas_count++; } } From ad696ccabfe6973689f91a13f2da107610868eaa Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Dec 2015 10:33:34 -0600 Subject: [PATCH 049/127] FS-8612 #resolve [rare ivr originated calls crash due to read codec leak] --- src/switch_ivr_originate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index c65b80b7d4..6b03c1739d 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1863,6 +1863,7 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * if (!session) continue; if (switch_core_codec_ready((&read_codecs[i]))) { + switch_core_session_set_read_codec(session, NULL); switch_core_codec_destroy(&read_codecs[i]); } From 568ecb8bf458efd8c2f187875e51b1fc03055eb9 Mon Sep 17 00:00:00 2001 From: Steve Underwood Date: Sat, 5 Dec 2015 01:15:54 +0800 Subject: [PATCH 050/127] Tweaks for platforms which require string.h for memxxx functions. --- libs/spandsp/src/g722.c | 1 + libs/spandsp/src/gsm0610_lpc.c | 1 + libs/spandsp/src/v8.c | 1 + 3 files changed, 3 insertions(+) diff --git a/libs/spandsp/src/g722.c b/libs/spandsp/src/g722.c index aebe9a575e..f3126e8aa1 100644 --- a/libs/spandsp/src/g722.c +++ b/libs/spandsp/src/g722.c @@ -32,6 +32,7 @@ #include #include #include +#include #if defined(HAVE_TGMATH_H) #include #endif diff --git a/libs/spandsp/src/gsm0610_lpc.c b/libs/spandsp/src/gsm0610_lpc.c index 70e06d4122..c1341882d8 100644 --- a/libs/spandsp/src/gsm0610_lpc.c +++ b/libs/spandsp/src/gsm0610_lpc.c @@ -43,6 +43,7 @@ #include "floating_fudge.h" #include #include +#include #include "spandsp/telephony.h" #include "spandsp/fast_convert.h" diff --git a/libs/spandsp/src/v8.c b/libs/spandsp/src/v8.c index 4c5dd43244..4dbe338f72 100644 --- a/libs/spandsp/src/v8.c +++ b/libs/spandsp/src/v8.c @@ -33,6 +33,7 @@ #include #include #include +#include #if defined(HAVE_TGMATH_H) #include #endif From f0d502711120d416ee6aa80aef2a436d37b9ba67 Mon Sep 17 00:00:00 2001 From: Ken Rice Date: Thu, 3 Dec 2015 18:23:17 -0600 Subject: [PATCH 051/127] FS-8614 #resolve Add debian developers install script and update README.md to reference it --- html5/verto/verto_communicator/README.md | 7 ++++++- html5/verto/verto_communicator/debian8-install.sh | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100755 html5/verto/verto_communicator/debian8-install.sh diff --git a/html5/verto/verto_communicator/README.md b/html5/verto/verto_communicator/README.md index 707783501f..eafe65075f 100644 --- a/html5/verto/verto_communicator/README.md +++ b/html5/verto/verto_communicator/README.md @@ -1,3 +1,5 @@ +To install on Mac + brew install npm npm install -g grunt grunt-cli bower @@ -5,4 +7,7 @@ npm install -g grunt grunt-cli bower cd verto_communicator npm install bower install -grunt serve \ No newline at end of file +grunt serve + +to Install on Debian 8 +./debian8_install.sh diff --git a/html5/verto/verto_communicator/debian8-install.sh b/html5/verto/verto_communicator/debian8-install.sh new file mode 100755 index 0000000000..cf992b0906 --- /dev/null +++ b/html5/verto/verto_communicator/debian8-install.sh @@ -0,0 +1,7 @@ +#!/bin/bash +apt-get update +apt-get install npm nodejs-legacy +npm install -g grunt grunt-cli bower +npm install +bower --allow-root install +grunt build From 28bd6e2e38d3e13f32ac43d08222a2d6953edabe Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Dec 2015 13:07:50 -0600 Subject: [PATCH 052/127] FS-8615 #resolve [Crash when quickly changing layouts and setting reservation ids.] --- src/mod/applications/mod_conference/conference_api.c | 3 +-- src/mod/applications/mod_conference/conference_video.c | 9 +++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index dc9d683e7e..93ca89baa9 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -1583,10 +1583,9 @@ switch_status_t conference_api_sub_vid_res_id(conference_member_t *member, switc } else { member->video_reservation_id = switch_core_strdup(member->pool, text); stream->write_function(stream, "+OK reservation_id %s\n", text); + conference_video_detach_video_layer(member); } - conference_video_detach_video_layer(member); - return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 6a16604226..dfece45d97 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -615,14 +615,19 @@ void conference_video_detach_video_layer(conference_member_t *member) mcu_layer_t *layer = NULL; mcu_canvas_t *canvas = NULL; - if (member->canvas_id < 0 || member->video_layer_id < 0) return; - + if (member->canvas_id < 0) return; + if (!(canvas = conference_video_get_canvas_locked(member))) { return; } switch_mutex_lock(canvas->mutex); + if (member->video_layer_id < 0) { + switch_mutex_unlock(canvas->mutex); + return; + } + layer = &canvas->layers[member->video_layer_id]; if (layer->geometry.audio_position) { From 3f7d1a5674b85c3155034f296c4314401b70afca Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 4 Dec 2015 13:55:43 -0600 Subject: [PATCH 053/127] FS-8617 #resolve [Add gain and vol seperate to verto] --- html5/verto/js/src/jquery.verto.js | 39 +++++++++++++++++--------- html5/verto/video_demo/js/verto-min.js | 9 ++---- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/html5/verto/js/src/jquery.verto.js b/html5/verto/js/src/jquery.verto.js index 792331f18a..0fd9fb846a 100644 --- a/html5/verto/js/src/jquery.verto.js +++ b/html5/verto/js/src/jquery.verto.js @@ -1352,23 +1352,22 @@ }; $.verto.conf.prototype.volumeDown = function(memberID) { - if (!this.params.hasVid) { - throw 'Conference has no video'; - } - this.modCommand("volume_in", parseInt(memberID), "down"); + this.modCommand("volume_out", parseInt(memberID), "down"); }; $.verto.conf.prototype.volumeUp = function(memberID) { - if (!this.params.hasVid) { - throw 'Conference has no video'; - } + 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) { - if (!this.params.hasVid) { - throw 'Conference has no video'; - } this.modCommand("transfer", parseInt(memberID), exten); }; @@ -1498,8 +1497,10 @@ 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 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; @@ -1509,6 +1510,8 @@ html += "" + "" + + "" + + "" + "" + "" + ""; @@ -1640,14 +1643,22 @@ }); } - $("#" + volup_id).click(function() { + $("#" + gainup_id).click(function() { confMan.modCommand("volume_in", x, "up"); }); - $("#" + voldn_id).click(function() { + $("#" + 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; } diff --git a/html5/verto/video_demo/js/verto-min.js b/html5/verto/video_demo/js/verto-min.js index 4a9e5a5c98..633be557c4 100644 --- a/html5/verto/video_demo/js/verto-min.js +++ b/html5/verto/video_demo/js/verto-min.js @@ -222,19 +222,16 @@ this.modCommand("vid-layout",null,layout);};$.verto.conf.prototype.kick=function 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);} $("#"+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;j Date: Fri, 4 Dec 2015 17:44:53 -0500 Subject: [PATCH 054/127] FS-8619 [mod_rayo] reply with conflict stanza error if bind is attempted with duplicate JID. Improve error handling when 'ready' callback fails. --- src/mod/event_handlers/mod_rayo/mod_rayo.c | 35 ++++--- .../event_handlers/mod_rayo/xmpp_streams.c | 95 +++++++++++-------- .../event_handlers/mod_rayo/xmpp_streams.h | 7 +- 3 files changed, 84 insertions(+), 53 deletions(-) diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 11828ce328..c865dd5070 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -4199,11 +4199,31 @@ static struct rayo_actor *xmpp_stream_client_locate(struct xmpp_stream *stream, return actor; } +/** + * Handle stream resource binding + * @param stream the new stream + */ +static int on_xmpp_stream_bind(struct xmpp_stream *stream) +{ + if (!xmpp_stream_is_s2s(stream)) { + /* client belongs to stream */ + struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL); + if (client) { + xmpp_stream_set_private(stream, client); + } else { + /* this went really bad... */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n"); + return 0; + } + } + return 1; +} + /** * Handle new stream creation * @param stream the new stream */ -static void on_xmpp_stream_ready(struct xmpp_stream *stream) +static int on_xmpp_stream_ready(struct xmpp_stream *stream) { if (xmpp_stream_is_s2s(stream)) { if (xmpp_stream_is_incoming(stream)) { @@ -4214,6 +4234,7 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream) } else { /* this went really bad... */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create peer server entity!\n"); + return 0; } } else { /* send directed presence to domain */ @@ -4227,16 +4248,8 @@ static void on_xmpp_stream_ready(struct xmpp_stream *stream) iks_insert_cdata(x, "chat", 4); RAYO_SEND_MESSAGE(globals.server, xmpp_stream_get_jid(stream), presence); } - } else { - /* client belongs to stream */ - struct rayo_client *client = rayo_client_create(xmpp_stream_get_jid(stream), xmpp_stream_get_jid(stream), PS_OFFLINE, rayo_client_send, NULL); - if (client) { - xmpp_stream_set_private(stream, client); - } else { - /* this went really bad... */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "failed to create client entity!\n"); - } } + return 1; } /** @@ -4486,7 +4499,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Missing shared secret for %s domain. Server dialback will not work\n", name); } - globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy); + globals.xmpp_context = xmpp_stream_context_create(name, shared_secret, on_xmpp_stream_bind, on_xmpp_stream_ready, on_xmpp_stream_recv, on_xmpp_stream_destroy); globals.server = rayo_server_create(name); /* set up TLS */ diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.c b/src/mod/event_handlers/mod_rayo/xmpp_streams.c index 23a7387db6..fcc3c76213 100644 --- a/src/mod/event_handlers/mod_rayo/xmpp_streams.c +++ b/src/mod/event_handlers/mod_rayo/xmpp_streams.c @@ -1,6 +1,6 @@ /* * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013, Grasshopper + * Copyright (C) 2013-2015, Grasshopper * * Version: MPL 1.1 * @@ -55,6 +55,8 @@ struct xmpp_stream_context { switch_hash_t *users; /** shared secret for server dialback */ const char *dialback_secret; + /** callback when a new resource is bound */ + xmpp_stream_bind_callback bind_callback; /** callback when a new stream is ready */ xmpp_stream_ready_callback ready_callback; /** callback when a stream is destroyed */ @@ -539,17 +541,19 @@ static iks *on_iq_set_xmpp_session(struct xmpp_stream *stream, iks *node) switch(stream->state) { case XSS_RESOURCE_BOUND: { - reply = iks_new_iq_result(node); - stream->state = XSS_READY; + if (context->ready_callback && !context->ready_callback(stream)) { + reply = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR); + stream->state = XSS_ERROR; + } else { + reply = iks_new_iq_result(node); + stream->state = XSS_READY; - /* add to available streams */ - switch_mutex_lock(context->streams_mutex); - switch_core_hash_insert(context->routes, stream->jid, stream); - switch_mutex_unlock(context->streams_mutex); - - if (context->ready_callback) { - context->ready_callback(stream); + /* add to available streams */ + switch_mutex_lock(context->streams_mutex); + switch_core_hash_insert(context->routes, stream->jid, stream); + switch_mutex_unlock(context->streams_mutex); } + break; } case XSS_AUTHENTICATED: @@ -574,6 +578,7 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node) switch(stream->state) { case XSS_AUTHENTICATED: { + struct xmpp_stream_context *context = stream->context; iks *bind = iks_find(node, "bind"); iks *x; /* get optional client resource ID */ @@ -585,14 +590,19 @@ static iks *on_iq_set_xmpp_bind(struct xmpp_stream *stream, iks *node) switch_uuid_str(resource_id_buf, sizeof(resource_id_buf)); resource_id = switch_core_strdup(stream->pool, resource_id_buf); } - stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id); - stream->state = XSS_RESOURCE_BOUND; - /* create reply */ - reply = iks_new_iq_result(node); - x = iks_insert(reply, "bind"); - iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND); - iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid)); + stream->jid = switch_core_sprintf(stream->pool, "%s/%s", stream->jid, resource_id); + if (context->bind_callback && !context->bind_callback(stream)) { + stream->jid = NULL; + reply = iks_new_error(node, STANZA_ERROR_CONFLICT); + } else { + stream->state = XSS_RESOURCE_BOUND; + + reply = iks_new_iq_result(node); + x = iks_insert(reply, "bind"); + iks_insert_attrib(x, "xmlns", IKS_NS_XMPP_BIND); + iks_insert_cdata(iks_insert(x, "jid"), stream->jid, strlen(stream->jid)); + } break; } default: @@ -732,16 +742,16 @@ static void on_stream_dialback_result_valid(struct xmpp_stream *stream, iks *nod /* TODO check domain pair and allow access if pending request exists */ switch_log_printf(SWITCH_CHANNEL_UUID_LOG(stream->id), SWITCH_LOG_DEBUG, "%s, %s:%i, valid dialback result\n", stream->jid, stream->address, stream->port); - /* this stream is routable */ - stream->state = XSS_READY; + if (context->ready_callback && !context->ready_callback(stream)) { + stream->state = XSS_ERROR; + } else { + /* this stream is routable */ + stream->state = XSS_READY; - /* add to available streams */ - switch_mutex_lock(context->streams_mutex); - switch_core_hash_insert(context->routes, stream->jid, stream); - switch_mutex_unlock(context->streams_mutex); - - if (context->ready_callback) { - context->ready_callback(stream); + /* add to available streams */ + switch_mutex_lock(context->streams_mutex); + switch_core_hash_insert(context->routes, stream->jid, stream); + switch_mutex_unlock(context->streams_mutex); } } @@ -816,6 +826,18 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node) return; } + /* this stream is not routable */ + stream->state = XSS_READY; + stream->jid = switch_core_strdup(stream->pool, from); + + if (context->ready_callback && !context->ready_callback(stream)) { + iks *error = iks_new_error(node, STANZA_ERROR_INTERNAL_SERVER_ERROR); + iks_send(stream->parser, error); + iks_delete(error); + stream->state = XSS_ERROR; + return; + } + /* TODO validate key */ reply = iks_new("db:result"); iks_insert_attrib(reply, "from", to); @@ -823,14 +845,6 @@ static void on_stream_dialback_result_key(struct xmpp_stream *stream, iks *node) iks_insert_attrib(reply, "type", "valid"); iks_send(stream->parser, reply); iks_delete(reply); - - /* this stream is not routable */ - stream->state = XSS_READY; - stream->jid = switch_core_strdup(stream->pool, from); - - if (context->ready_callback) { - context->ready_callback(stream); - } } /** @@ -1014,6 +1028,11 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node case XSS_SECURE: break; case XSS_AUTHENTICATED: { + if (context->ready_callback && !context->ready_callback(stream)) { + stream->state = XSS_ERROR; + break; + } + /* all set */ xmpp_send_server_header_features(stream); stream->state = XSS_READY; @@ -1022,10 +1041,6 @@ static void on_inbound_server_stream_start(struct xmpp_stream *stream, iks *node switch_mutex_lock(context->streams_mutex); switch_core_hash_insert(context->routes, stream->jid, stream); switch_mutex_unlock(context->streams_mutex); - - if (context->ready_callback) { - context->ready_callback(stream); - } break; } case XSS_SHUTDOWN: @@ -1745,12 +1760,13 @@ void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream * Create a new XMPP stream context * @param domain for new streams * @param domain_secret domain shared secret for server dialback + * @param bind_cb callback function when a resource is bound to a new stream * @param ready callback function when new stream is ready * @param recv callback function when a new stanza is received * @param destroy callback function when a stream is destroyed * @return the context */ -struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy) +struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy) { switch_memory_pool_t *pool; struct xmpp_stream_context *context; @@ -1762,6 +1778,7 @@ struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const switch_core_hash_init(&context->routes); switch_core_hash_init(&context->streams); context->dialback_secret = switch_core_strdup(context->pool, domain_secret); + context->bind_callback = bind_cb; context->ready_callback = ready; context->destroy_callback = destroy; context->recv_callback = recv; diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.h b/src/mod/event_handlers/mod_rayo/xmpp_streams.h index a07c75d025..242f392543 100644 --- a/src/mod/event_handlers/mod_rayo/xmpp_streams.h +++ b/src/mod/event_handlers/mod_rayo/xmpp_streams.h @@ -1,6 +1,6 @@ /* * mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2013, Grasshopper + * Copyright (C) 2013-2015, Grasshopper * * Version: MPL 1.1 * @@ -32,11 +32,12 @@ struct xmpp_stream; struct xmpp_stream_context; -typedef void (* xmpp_stream_ready_callback)(struct xmpp_stream *stream); +typedef int (* xmpp_stream_bind_callback)(struct xmpp_stream *stream); +typedef int (* xmpp_stream_ready_callback)(struct xmpp_stream *stream); typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stanza); typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream); -extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy); +extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy); extern void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file); extern void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file); extern void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password); From cd361f6f592917b1da385992868b95e8f7023af8 Mon Sep 17 00:00:00 2001 From: William King Date: Mon, 7 Dec 2015 11:52:43 -0800 Subject: [PATCH 055/127] misc config update for available modules. #noWIR --- conf/vanilla/autoload_configs/modules.conf.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index 78c9a42e8f..5437153660 100644 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -1,6 +1,5 @@ - @@ -17,9 +16,11 @@ + + @@ -27,6 +28,7 @@ + @@ -126,7 +128,7 @@ - + From cce8288c161a8976cf4a18cabbd778fc4fe4bddf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 8 Dec 2015 11:18:07 -0600 Subject: [PATCH 056/127] FS-8625 #resolve [Segmentation fault: 11] --- src/mod/endpoints/mod_dingaling/mod_dingaling.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 9ab1c072f5..9e952f2196 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -1931,6 +1931,8 @@ static switch_status_t channel_on_init(switch_core_session_t *session) struct private_object *tech_pvt = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_channel_set_variable(channel, "jitterbuffer_msec", "1p"); + tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); @@ -2383,12 +2385,6 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s case SWITCH_MESSAGE_INDICATE_ANSWER: channel_answer_channel(session); break; - case SWITCH_MESSAGE_INDICATE_BRIDGE: - rtp_flush_read_buffer(tech_pvt->transports[LDL_TPORT_RTP].rtp_session, SWITCH_RTP_FLUSH_STICK); - break; - case SWITCH_MESSAGE_INDICATE_UNBRIDGE: - rtp_flush_read_buffer(tech_pvt->transports[LDL_TPORT_RTP].rtp_session, SWITCH_RTP_FLUSH_UNSTICK); - break; case SWITCH_MESSAGE_INDICATE_STUN_ERROR: //switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_NORMAL_CLEARING); break; From 22f766c28f12f1a003a5cd5167e8f072c279aa49 Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Tue, 8 Dec 2015 17:20:25 -0300 Subject: [PATCH 057/127] FS-8603 [verto_communicator] - Added Device validation --- .../src/vertoService/services/vertoService.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 3b2c01758a..42979e1d92 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -294,6 +294,28 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora } console.debug('Devices were refreshed, checking that we have cameras.'); + // Verify if selected devices are valid + var videoFlag = data.videoDevices.some(function(device) { + return device.id == storage.data.selectedVideo; + }); + + var shareFlag = data.shareDevices.some(function(device) { + return device.id == storage.data.selectedShare; + }); + + var audioFlag = data.audioDevices.some(function(device) { + return device.id == storage.data.selectedAudio; + }); + + var speakerFlag = data.speakerDevices.some(function(device) { + return device.id == storage.data.selectedSpeaker; + }); + + if (!videoFlag) storage.data.selectedVideo = data.videoDevices[0].id; + if (!shareFlag) storage.data.selectedShare = data.shareDevices[0].id; + if (!audioFlag) storage.data.selectedAudio = data.audioDevices[0].id; + if (!speakerFlag) storage.data.selectedSpeaker = data.speakerDevices[0].id; + // This means that we cannot use video! if (data.videoDevices.length === 0) { console.log('No camera, disabling video.'); From b91a1017e2399b60ed5fbb17e27e1100f6260e9c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 8 Dec 2015 14:35:15 -0600 Subject: [PATCH 058/127] FS-8621 --- src/mod/applications/mod_av/avcodec.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index b4afb7ab40..de6fb8a280 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -850,7 +850,7 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt sane = switch_calc_bitrate(1920, 1080, 2, 30); - if (context->bandwidth > sane) { + if (context->bandwidth / 8 > sane) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BITRATE TRUNCATED TO %d\n", sane); context->bandwidth = sane * 8; } @@ -862,7 +862,7 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt context->encoder_ctx->time_base = (AVRational){1, 90}; context->encoder_ctx->max_b_frames = 0; context->encoder_ctx->pix_fmt = AV_PIX_FMT_YUV420P; - context->encoder_ctx->thread_count = 1;//switch_core_cpu_count() > 4 ? 4 : 1; + context->encoder_ctx->thread_count = 1;//switch_core_cpu_count() > 2 ? 2 : 1; context->encoder_ctx->bit_rate = context->bandwidth * 1024; context->encoder_ctx->rc_max_rate = context->bandwidth * 1024; context->encoder_ctx->rc_buffer_size = context->bandwidth * 1024 * 4; @@ -882,15 +882,20 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt //av_opt_set_int(context->encoder_ctx->priv_data, "slice-max-size", SLICE_SIZE, 0); // libx264-medium.ffpreset preset + context->encoder_ctx->coder_type = 1; // coder = 1 context->encoder_ctx->flags|=CODEC_FLAG_LOOP_FILTER; // flags=+loop context->encoder_ctx->me_cmp|= 1; // cmp=+chroma, where CHROMA = 1 context->encoder_ctx->me_method=ME_HEX; // me_method=hex - context->encoder_ctx->me_subpel_quality = 7; // subq=7 + //context->encoder_ctx->me_subpel_quality = 7; // subq=7 + context->encoder_ctx->me_range = 16; // me_range=16 context->encoder_ctx->max_b_frames = 3; // bf=3 + //context->encoder_ctx->refs = 3; // refs=3 - context->encoder_ctx->trellis = 1; // trellis=1 + + //context->encoder_ctx->trellis = 1; // trellis=1 + } // libx264-medium.ffpreset preset @@ -960,7 +965,6 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "codec: id=%d %s\n", context->decoder->id, context->decoder->long_name); context->decoder_ctx = avcodec_alloc_context3(context->decoder); - if (avcodec_open2(context->decoder_ctx, context->decoder, NULL) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error openning codec\n"); goto error; From 3df5826098176bcc0a36e02c06e68032a61090bf Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Fri, 4 Dec 2015 16:05:58 -0300 Subject: [PATCH 059/127] FS-8616 [verto_communicator] - A new menu for moderator, added Gain buttons and removed the 3-dot-button, moving its behavior to member-name div --- .../verto_communicator/src/css/verto.css | 78 ++++++- .../verto_communicator/src/partials/chat.html | 204 ++++++++++-------- .../controllers/ChatController.js | 21 ++ 3 files changed, 217 insertions(+), 86 deletions(-) diff --git a/html5/verto/verto_communicator/src/css/verto.css b/html5/verto/verto_communicator/src/css/verto.css index 84666c880a..4da5f19cc1 100644 --- a/html5/verto/verto_communicator/src/css/verto.css +++ b/html5/verto/verto_communicator/src/css/verto.css @@ -952,13 +952,18 @@ body .modal-body .btn-group .btn.active { .chat-members .chat-member-item { padding: 8px 16px; - height: 56px; + min-height: 56px; +} + +.chat-members .chat-member-item.opened { + background-color: #F8F8F8; } .chat-members .chat-member-item:hover { - background-color: #E5E5E5; + background-color: #F8F8F8; } + .chat-members .chat-members-avatar { width: 40px; height: 40px; @@ -1609,3 +1614,72 @@ body:-webkit-full-screen #incall .video-footer { .watcher .spinner { top: 20%; } + +.admin-controls { + border: 1px solid rgba(204, 204, 204, 0.48); + background: #F3F3F3; + margin-top: 12px; + margin-bottom: 10px; + overflow: hidden; +} + +.admin-controls .ctrl-section { + padding: 10px 0px; + padding-bottom: 0; +} + +.admin-controls .ctrl-section:nth-child(1) { + border-right: 1px solid rgba(204, 204, 204, 0.48); +} + +.admin-controls h3 { + font-size: 9px; + margin: 0 auto; + color: #AFAFAF; + text-transform: uppercase; + font-weight: 900; + text-align: center; + margin-top: -10px; + width: 100%; + background-color: rgba(224, 224, 224, 0.53); + padding: 5px; +} + +.admin-controls .mdi-fw { + width: auto; + display: block; +} + +.admin-controls .group .btn { + box-shadow: none; + color: #607D8B; + font-size: 8px; +} + +.admin-controls .group .btn:hover { + box-shadow: none !important; +} + +.admin-controls .group .btn:active { + box-shadow: none !important; +} + +.admin-controls.ng-hide-add, .admin-controls.ng-hide-remove { + transition: 0s linear all; +} +.admin-controls.ng-hide-add-active, +.admin-controls.ng-hide-remove-active { + transition: .2s linear all; +} + +.admin-controls.ng-hide { + animation: growY .2s; +} +.admin-controls.ng-hide-remove { + animation: growY .2s reverse; +} + +@keyframes growY { + from { max-height:2000px;} + to { max-height:0px;} +} diff --git a/html5/verto/verto_communicator/src/partials/chat.html b/html5/verto/verto_communicator/src/partials/chat.html index afe85c1af7..c769b70a9f 100644 --- a/html5/verto/verto_communicator/src/partials/chat.html +++ b/html5/verto/verto_communicator/src/partials/chat.html @@ -17,12 +17,12 @@

    There are no members to show.

    -
    +
    -

    +

    {{ member.name }}
    ({{ member.number }}) @@ -33,88 +33,6 @@

    - - diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js index 75947db607..74f21c946e 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js @@ -49,6 +49,11 @@ }); }); + $rootScope.$on('call.conference', function(event, data) { + $timeout(function() { + $scope.conf = verto.data.conf.params.laData; + }); + }); $rootScope.$on('changedVideoLayout', function(event, layout) { $scope.resIDs = getResByLayout(layout); @@ -176,6 +181,12 @@ /** * Public methods. */ + + $scope.toggleModMenu = function(index) { + if (verto.data.confRole != 'moderator') return; + $scope.openId = $scope.openId == index ? null : index; + }; + $scope.send = function() { // Only conferencing chat is supported for now // but still calling method with the conference prefix @@ -285,6 +296,16 @@ verto.data.conf.volumeUp(memberID); }; + $scope.confGainDown = function(memberID) { + console.log('$scope.confGainDown'); + verto.data.conf.gainDown(memberID); + }; + + $scope.confGainUp = function(memberID) { + console.log('$scope.confGainUp'); + verto.data.conf.gainUp(memberID); + }; + $scope.confTransfer = function(memberID) { console.log('$scope.confTransfer'); prompt({ From 2bddbf972e30933e8280227238d04a8cbf7cd004 Mon Sep 17 00:00:00 2001 From: William Henry Date: Tue, 8 Dec 2015 18:51:29 -0500 Subject: [PATCH 060/127] FS-8631 [update regex to allow DSN to match rest of FS code] --- src/mod/applications/mod_db/mod_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index 8df5686896..f5682000df 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -272,7 +272,7 @@ SWITCH_LIMIT_STATUS(limit_status_db) /* INIT / Config */ -static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql|^odbc|^sqlite|[^:]+:[^:]+:.+" }; +static switch_xml_config_string_options_t limit_config_dsn = { NULL, 0, "^pgsql|^odbc|^sqlite|[^:]+:[^:]*:.*" }; static switch_xml_config_item_t config_settings[] = { SWITCH_CONFIG_ITEM("odbc-dsn", SWITCH_CONFIG_STRING, 0, &globals.odbc_dsn, NULL, &limit_config_dsn, From 2cb7188c1733a6524e5852f95bb71f12e0ffcc18 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 8 Dec 2015 18:30:48 -0600 Subject: [PATCH 061/127] FS-8632 #resolve [Add origination_audio_mode originate variable] --- src/switch_core_media.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index c7a7efacd4..2456925ce9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -7475,11 +7475,16 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess sr = "sendrecv"; } - //if ((var_val = switch_channel_get_variable(session->channel, "media_audio_mode"))) { - // sr = var_val; - //} else { - // sr = "sendrecv"; - //} + if ((var_val = switch_channel_get_variable(session->channel, "origination_audio_mode"))) { + if (!strcasecmp(sr, "sendonly") || !strcasecmp(sr, "recvonly") || !strcasecmp(sr, "sendrecv")) { + sr = var_val; + } + switch_channel_set_variable(session->channel, "origination_audio_mode", NULL); + } + + if (zstr(sr)) { + sr = "sendrecv"; + } } if (!smh->owner_id) { From d35d7344be5b28cf8b8a3337f34c0f3e490c95d7 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 9 Dec 2015 14:18:37 -0600 Subject: [PATCH 062/127] FS-8640 #resolve Dont clear conference member reservation id on members that dont have a reservation ID --- .../src/vertoControllers/controllers/ChatController.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js index 74f21c946e..f04529193a 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ChatController.js @@ -82,8 +82,12 @@ function clearMembersResID(preserve) { $scope.members.forEach(function(member) { var resID = member.status.video.reservationID; + console.debug("resID to clear: " + resID); if (resID && preserve && preserve.indexOf(resID) !== -1) return; + if (resID){ + console.debug("clearing resid [" + resID + "] from [" + member.id + "]"); $scope.confResID(member.id, resID); + } }); }; From 6cd796a9bcbcf549c18e19f0fd507d67901ab418 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Dec 2015 15:33:18 -0600 Subject: [PATCH 063/127] FS-8293 add quality level 0 to conference (default is 1) and fix some logic in auto bw --- src/include/switch_utils.h | 12 +++- src/mod/applications/mod_av/avcodec.c | 2 +- .../mod_conference/conference_video.c | 66 ++++++++++--------- .../mod_conference/mod_conference.c | 6 +- src/mod/codecs/mod_openh264/mod_openh264.cpp | 2 +- src/mod/codecs/mod_vpx/mod_vpx.c | 2 +- 6 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 3ff7c286c4..9b47911e10 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -995,14 +995,20 @@ SWITCH_DECLARE(char *) switch_util_quote_shell_arg_pool(const char *string, swit #define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE) -static inline int32_t switch_calc_bitrate(int w, int h, int quality, int fps) +static inline int32_t switch_calc_bitrate(int w, int h, int quality, double fps) { + int r; + /* KUSH GAUGE*/ if (!fps) fps = 15; - if (!quality) quality = 2; - return (int32_t)((float)(w * h * fps * quality) * 0.07) / 1000; + r = (int32_t)((double)(w * h * fps * (quality ? quality : 1)) * 0.07) / 1000; + + if (!quality) r /= 2; + + return r; + } static inline int32_t switch_parse_bandwidth_string(const char *bwv) diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index de6fb8a280..5349e11708 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -845,7 +845,7 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt if (context->codec_settings.video.bandwidth) { context->bandwidth = context->codec_settings.video.bandwidth * 8; } else { - context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 0, 0) * 8; + context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 1, 15) * 8; } sane = switch_calc_bitrate(1920, 1080, 2, 30); diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index dfece45d97..45ca7c41c7 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -894,7 +894,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member, channel = switch_core_session_get_channel(member->session); - if (!switch_channel_test_flag(channel, CF_VIDEO) && !member->avatar_png_img) { + if (!switch_channel_test_flag(channel, CF_VIDEO_READY) && !member->avatar_png_img) { return SWITCH_STATUS_FALSE; } @@ -1267,7 +1267,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer continue; } - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || + if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -1590,7 +1590,7 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo canvas = conference_video_get_canvas_locked(member); if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) && - (!switch_channel_test_flag(member->channel, CF_VIDEO) || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY)) { + (!switch_channel_test_flag(member->channel, CF_VIDEO_READY) || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY)) { if (canvas) { conference_video_release_canvas(&canvas); } @@ -1603,7 +1603,7 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo member->avatar_patched = 0; - if (!force && switch_channel_test_flag(member->channel, CF_VIDEO) && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { + if (!force && switch_channel_test_flag(member->channel, CF_VIDEO_READY) && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO); } else { if (member->conference->no_video_avatar) { @@ -1639,7 +1639,7 @@ void conference_video_check_flush(conference_member_t *member) { int flushed; - if (!member->channel || !switch_channel_test_flag(member->channel, CF_VIDEO)) { + if (!member->channel || !switch_channel_test_flag(member->channel, CF_VIDEO_READY)) { return; } @@ -1798,7 +1798,7 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t int size = 0; void *pop; - if (!member->avatar_png_img && switch_channel_test_flag(member->channel, CF_VIDEO)) { + if (!member->avatar_png_img && switch_channel_test_flag(member->channel, CF_VIDEO_READY)) { do { if (switch_queue_trypop(member->video_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { switch_img_free(&img); @@ -1870,7 +1870,7 @@ void conference_video_set_absolute_incoming_bitrate_member(conference_member_t * member->max_bw_in = 0; member->force_bw_in = kps; member->managed_kps = 0; - if (!conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && switch_channel_test_flag(member->channel, CF_VIDEO)) { + if (!conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && switch_channel_test_flag(member->channel, CF_VIDEO_READY)) { conference_video_set_incoming_bitrate(member, kps); } } @@ -1903,6 +1903,13 @@ void conference_video_set_absolute_incoming_bitrate(conference_obj_t *conference void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_t *layer) { + switch_vid_params_t vid_params = { 0 }; + + switch_core_media_get_vid_params(member->session, &vid_params); + + if (!switch_channel_test_flag(member->channel, CF_VIDEO_READY) || !vid_params.width || !vid_params.height) { + return; + } if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) { member->managed_kps = 0; @@ -1926,15 +1933,12 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_ switch_channel_get_name(member->channel), kps); } else { int max = 0; - switch_vid_params_t vid_params = { 0 }; - switch_core_media_get_vid_params(member->session, &vid_params); - if (w > vid_params.width || h > vid_params.height) { w = vid_params.width; h = vid_params.height; } - + if (layer) { kps = switch_calc_bitrate(w, h, member->conference->video_quality, (int)(member->conference->video_fps.fps)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n", @@ -1953,7 +1957,9 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_ switch_channel_get_name(member->channel), kps); } } - conference_video_set_incoming_bitrate(member, kps); + if (kps) { + conference_video_set_incoming_bitrate(member, kps); + } } } @@ -2093,7 +2099,7 @@ 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->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO) && + if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && conference_utils_member_test_flag(imember, MFLAG_RUNNING) && imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) { canvas_count++; @@ -2141,7 +2147,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (imember = conference->members; imember; imember = imember->next) { if (imember->canvas_id != canvas->canvas_id) continue; - if (imember->session && switch_channel_test_flag(imember->channel, CF_VIDEO)) { + if (imember->session && switch_channel_test_flag(imember->channel, CF_VIDEO_READY)) { switch_core_session_request_video_refresh(imember->session); switch_core_media_gen_key_frame(imember->session); } @@ -2167,7 +2173,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_image_t *img = NULL; int i; - if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) || + if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && !imember->avatar_png_img) || conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -2182,7 +2188,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr !conference_utils_member_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) { min_members++; - if (switch_channel_test_flag(imember->channel, CF_VIDEO)) { + if (switch_channel_test_flag(imember->channel, CF_VIDEO_READY)) { if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) { for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { if (check_codec->implementation->codec_id == write_codecs[i]->codec.implementation->codec_id) { @@ -2272,7 +2278,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_img_free(&img); } - if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)))) { + if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)))) { if (conference_video_find_layer(conference, canvas, imember, &layer) == SWITCH_STATUS_SUCCESS) { imember->layer_timeout = 0; } else { @@ -2382,7 +2388,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (imember = conference->members; imember; imember = imember->next) { - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || + if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -2505,7 +2511,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr mcu_layer_t *layer = NULL; switch_image_t *use_img = NULL; - if (!omember->session || !switch_channel_test_flag(omember->channel, CF_VIDEO) || + if (!omember->session || !switch_channel_test_flag(omember->channel, CF_VIDEO_READY) || switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { continue; } @@ -2603,7 +2609,7 @@ 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) || + if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -2782,7 +2788,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr continue; } - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || + if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -2982,7 +2988,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ for (imember = conference->members; imember; imember = imember->next) { int i; - if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) || + if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && !imember->avatar_png_img) || conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -2997,7 +3003,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ !conference_utils_member_test_flag(imember, MFLAG_NO_MINIMIZE_ENCODING)) { min_members++; - if (switch_channel_test_flag(imember->channel, CF_VIDEO)) { + if (switch_channel_test_flag(imember->channel, CF_VIDEO_READY)) { if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) { for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { if (check_codec->implementation->codec_id == write_codecs[i]->codec.implementation->codec_id) { @@ -3130,7 +3136,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ } - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || + if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -3228,7 +3234,7 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente continue; } - if (!switch_channel_test_flag(imember->channel, CF_VIDEO) && !imember->avatar_png_img) { + if (!switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && !imember->avatar_png_img) { continue; } @@ -3316,7 +3322,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_ if (!member) { switch_mutex_lock(conference->member_mutex); for (imember = conference->members; imember; imember = imember->next) { - if (imember->id != conference->video_floor_holder && imember->channel && switch_channel_test_flag(imember->channel, CF_VIDEO)) { + if (imember->id != conference->video_floor_holder && imember->channel && switch_channel_test_flag(imember->channel, CF_VIDEO_READY)) { member = imember; break; } @@ -3359,7 +3365,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_ switch_mutex_lock(conference->member_mutex); for (imember = conference->members; imember; imember = imember->next) { - if (!imember->channel || !switch_channel_test_flag(imember->channel, CF_VIDEO)) { + if (!imember->channel || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY)) { continue; } @@ -3436,11 +3442,11 @@ void conference_video_write_frame(conference_obj_t *conference, conference_membe switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); } - if (isession && switch_channel_test_flag(imember->channel, CF_VIDEO)) { + if (isession && switch_channel_test_flag(imember->channel, CF_VIDEO_READY)) { int send_frame = 0; if (conference->canvases[0] && conference_utils_test_flag(imember->conference, CFLAG_VIDEO_BRIDGE_FIRST_TWO)) { - if (switch_channel_test_flag(imember->channel, CF_VIDEO) && (conference->members_with_video == 1 || imember != floor_holder)) { + if (switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && (conference->members_with_video == 1 || imember != floor_holder)) { send_frame = 1; } } else if (!conference_utils_member_test_flag(imember, MFLAG_RECEIVING_VIDEO) && @@ -3483,7 +3489,7 @@ void conference_video_write_frame(conference_obj_t *conference, conference_membe continue; } - if (switch_channel_test_flag(imember->channel, CF_VIDEO) ) { + if (switch_channel_test_flag(imember->channel, CF_VIDEO_READY) ) { switch_core_session_request_video_refresh(imember->session); } diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index f9c9fc68c9..6a4df4a6a1 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2725,10 +2725,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co } else if (!strcasecmp(var, "video-quality") && !zstr(val)) { int tmp = atoi(val); - if (tmp > 0 && tmp < 5) { + if (tmp > -1 && tmp < 5) { conference_video_quality = tmp; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video quality must be between 1 and 4\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video quality must be between 0 and 4\n"); } } else if (!strcasecmp(var, "video-mode") && !zstr(val)) { @@ -2874,7 +2874,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co if (video_codec_bandwidth) { if (!strcasecmp(video_codec_bandwidth, "auto")) { - conference->video_codec_settings.video.bandwidth = switch_calc_bitrate(canvas_w, canvas_h, conference->video_quality, (int)conference->video_fps.fps); + conference->video_codec_settings.video.bandwidth = switch_calc_bitrate(canvas_w, canvas_h, conference->video_quality, conference->video_fps.fps); } else { conference->video_codec_settings.video.bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth); } diff --git a/src/mod/codecs/mod_openh264/mod_openh264.cpp b/src/mod/codecs/mod_openh264/mod_openh264.cpp index 723462b1f2..0e8beaf100 100644 --- a/src/mod/codecs/mod_openh264/mod_openh264.cpp +++ b/src/mod/codecs/mod_openh264/mod_openh264.cpp @@ -95,7 +95,7 @@ int FillSpecificParameters(h264_codec_context_t *context) { if (context->codec_settings.video.bandwidth) { context->bandwidth = context->codec_settings.video.bandwidth; } else { - context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 0, 0); + context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 1, 15); } if (context->bandwidth > 5120) { diff --git a/src/mod/codecs/mod_vpx/mod_vpx.c b/src/mod/codecs/mod_vpx/mod_vpx.c index 2826cb8866..4b70ad2809 100644 --- a/src/mod/codecs/mod_vpx/mod_vpx.c +++ b/src/mod/codecs/mod_vpx/mod_vpx.c @@ -317,7 +317,7 @@ static switch_status_t init_encoder(switch_codec_t *codec) if (context->codec_settings.video.bandwidth) { context->bandwidth = context->codec_settings.video.bandwidth; } else { - context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 0, 0); + context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 1, 15); } From 2f04c5e16d11f9dc4a80aea3da02cf0a6760effd Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Dec 2015 16:16:16 -0600 Subject: [PATCH 064/127] FS-8633 #resolve [ first verto to join a conference does not get "conference-livearray-join" event] --- .../mod_conference/mod_conference.c | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 6a4df4a6a1..4ba5a23f51 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -230,37 +230,6 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob conference->auto_recording = 0; conference->record_count = 0; - - - switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT); - conference_event_add_data(conference, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create"); - switch_event_fire(&event); - - if (conference_utils_test_flag(conference, CFLAG_LIVEARRAY_SYNC)) { - char *p; - - if (strchr(conference->name, '@')) { - conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s", conference->name); - conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s", conference->name); - conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s", conference->name); - } else { - conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s@%s", conference->name, conference->domain); - conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s@%s", conference->name, conference->domain); - conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s@%s", conference->name, conference->domain); - } - - conference->la_name = switch_core_strdup(conference->pool, conference->name); - if ((p = strchr(conference->la_name, '@'))) { - *p = '\0'; - } - - switch_live_array_create(conference->la_event_channel, conference->la_name, conference_globals.event_channel_id, &conference->la); - switch_live_array_set_user_data(conference->la, conference); - switch_live_array_set_command_handler(conference->la, conference_event_la_command_handler); - } - - while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT)) { switch_size_t file_sample_len = samples; switch_size_t file_data_len = samples * 2 * conference->channels; @@ -2440,7 +2409,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co switch_channel_t *channel = NULL; const char *force_rate = NULL, *force_interval = NULL, *force_channels = NULL, *presence_id = NULL; uint32_t force_rate_i = 0, force_interval_i = 0, force_channels_i = 0, video_auto_floor_msec = 0; - + switch_event_t *event; + /* Validate the conference name */ if (zstr(name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Record! no name.\n"); @@ -3195,6 +3165,36 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co } } + + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT); + conference_event_add_data(conference, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "conference-create"); + switch_event_fire(&event); + + if (conference_utils_test_flag(conference, CFLAG_LIVEARRAY_SYNC)) { + char *p; + + if (strchr(conference->name, '@')) { + conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s", conference->name); + conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s", conference->name); + conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s", conference->name); + } else { + conference->la_event_channel = switch_core_sprintf(conference->pool, "conference-liveArray.%s@%s", conference->name, conference->domain); + conference->chat_event_channel = switch_core_sprintf(conference->pool, "conference-chat.%s@%s", conference->name, conference->domain); + conference->mod_event_channel = switch_core_sprintf(conference->pool, "conference-mod.%s@%s", conference->name, conference->domain); + } + + conference->la_name = switch_core_strdup(conference->pool, conference->name); + if ((p = strchr(conference->la_name, '@'))) { + *p = '\0'; + } + + switch_live_array_create(conference->la_event_channel, conference->la_name, conference_globals.event_channel_id, &conference->la); + switch_live_array_set_user_data(conference->la, conference); + switch_live_array_set_command_handler(conference->la, conference_event_la_command_handler); + } + + end: switch_mutex_unlock(conference_globals.hash_mutex); From 83c529442772e533eeadd8249920a22f69a83c2f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Dec 2015 18:22:10 -0600 Subject: [PATCH 065/127] FS-8641 hard code to 15 for now until this is complete --- .../src/vertoService/services/vertoService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 3b2c01758a..6b3629b32f 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -342,7 +342,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora maxWidth: w, maxHeight: h, minFrameRate: 15, - vertoBestFrameRate: 30 + vertoBestFrameRate: 15 }); videoQuality.forEach(function(qual){ if (w === qual.width && h === qual.height) { From 2c7d53030c145d0072560928c3f73615b6ecd8b4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Dec 2015 18:38:25 -0600 Subject: [PATCH 066/127] FS-8641 need to set min and max for less than 30 but if you set min and max to 30 and it doesn't support it it will fail, (maybe design these FPS params a little better webrtc politicians) --- html5/verto/js/src/jquery.FSRTC.js | 7 +++++-- html5/verto/video_demo/js/verto-min.js | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index b63a57e4e9..7aa8f7bda7 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -558,8 +558,11 @@ video.optional.push({sourceId: obj.options.useCamera}); } - if (bestFrameRate && !window.moz) { - video.optional.push({minFrameRate: bestFrameRate}); + if (bestFrameRate) { + video.optional.push({minFrameRate: bestFrameRate}); + if (bestFrameRate < 30) { + video.optional.push({maxFrameRate: bestFrameRate}); + } } } else { diff --git a/html5/verto/video_demo/js/verto-min.js b/html5/verto/video_demo/js/verto-min.js index 633be557c4..a204cf2285 100644 --- a/html5/verto/video_demo/js/verto-min.js +++ b/html5/verto/video_demo/js/verto-min.js @@ -50,7 +50,7 @@ if(obj.options.useVideo&&obj.options.localVideo){getUserMedia({constraints:{audi var video={};var bestFrameRate=obj.options.videoParams.vertoBestFrameRate;delete obj.options.videoParams.vertoBestFrameRate;video={mandatory:obj.options.videoParams,optional:[]} var useVideo=obj.options.useVideo;if(useVideo&&obj.options.useCamera&&obj.options.useCamera!=="none"){if(!video.optional){video.optional=[];} if(obj.options.useCamera!=="any"){video.optional.push({sourceId:obj.options.useCamera});} -if(bestFrameRate&&!window.moz){video.optional.push({minFrameRate:bestFrameRate});}}else{console.log("Camera Disabled");video=false;useVideo=false;} +if(bestFrameRate){video.optional.push({minFrameRate:bestFrameRate});if(bestFrameRate<30){video.optional.push({maxFrameRate:bestFrameRate});}}}else{console.log("Camera Disabled");video=false;useVideo=false;} return{audio:audio,video:video,useVideo:useVideo};} $.FSRTC.prototype.call=function(profile){checkCompat();var self=this;var screen=false;self.type="offer";if(self.options.videoParams&&self.options.screenShare){screen=true;} function onSuccess(stream){self.localStream=stream;if(screen){if(moz){self.constraints.OfferToReceiveVideo=false;}else{self.constraints.mandatory.OfferToReceiveVideo=false;}} From 85f8bca62869beb6cf380e2e81874a6d97569852 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 9 Dec 2015 19:02:23 -0600 Subject: [PATCH 067/127] FS-8642 #resolve [CF_VIDEO_READY set on non-video calls] --- src/switch_channel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/switch_channel.c b/src/switch_channel.c index b6e282ced5..a62a39a388 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1995,8 +1995,9 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch ACTIVE = 1; } - if (flag == CF_VIDEO_PASSIVE) { + if (flag == CF_VIDEO_PASSIVE && channel->flags[CF_VIDEO]) { channel->flags[CF_VIDEO_READY] = 1; + if (channel->flags[flag]) { CLEAR = 1; } From 682850c02f749714fc6f51d023f329daaacca264 Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Thu, 10 Dec 2015 17:08:35 -0300 Subject: [PATCH 068/127] FS-8641 [verto-communicator] - Added Frame Rate setting --- .../src/partials/modal_settings.html | 9 +++++++-- .../src/storageService/services/storage.js | 3 ++- .../src/vertoService/services/vertoService.js | 14 +++++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/html5/verto/verto_communicator/src/partials/modal_settings.html b/html5/verto/verto_communicator/src/partials/modal_settings.html index f4775c0e36..4cb666fbbb 100644 --- a/html5/verto/verto_communicator/src/partials/modal_settings.html +++ b/html5/verto/verto_communicator/src/partials/modal_settings.html @@ -2,7 +2,6 @@
    - -
    diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index 5f965a2a74..6094e5052f 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -54,10 +54,9 @@ }); $rootScope.$on('changedSpeaker', function(event, speakerId) { - // This should provide feedback - //setAudioPlaybackDevice([,[,]]); - // if callback is set it will be called as callback(, , ) - verto.data.call.setAudioPlaybackDevice(speakerId); + if (verto.data.call) { + verto.data.call.setAudioPlaybackDevice(speakerId, sinkIdCallback); + } }); /** @@ -527,6 +526,13 @@ }); }; + function sinkIdCallback(success, deviceName) { + if (success) { + toastr.info('Speaker is now ' + deviceName + '', 'Success', { allowHtml: true }); + } else { + toastr.error('Your browser doesn\'t seem to support this feature', 'Error'); + } + } } ); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js index a8259ddc95..c1665eacca 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js @@ -12,6 +12,8 @@ $scope.verto = verto; $scope.mydata = angular.copy(storage.data); + $scope.speakerFeature = typeof document.getElementById('webcam').sinkId !== 'undefined'; + $scope.ok = function() { if ($scope.mydata.selectedSpeaker != storage.data.selectedSpeaker) { $rootScope.$emit('changedSpeaker', $scope.mydata.selectedSpeaker); From aede42e8bd4d24fff12314908b58b723ffa96011 Mon Sep 17 00:00:00 2001 From: Jaon EarlWolf Date: Mon, 21 Dec 2015 15:48:53 -0300 Subject: [PATCH 098/127] FS-8591 [verto_communicator] - Changed ng-keyup to ng-keydown --- html5/verto/verto_communicator/src/partials/chat.html | 2 +- .../src/vertoControllers/controllers/ChatController.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/html5/verto/verto_communicator/src/partials/chat.html b/html5/verto/verto_communicator/src/partials/chat.html index c769b70a9f..04ef1963ee 100644 --- a/html5/verto/verto_communicator/src/partials/chat.html +++ b/html5/verto/verto_communicator/src/partials/chat.html @@ -188,7 +188,7 @@
    - +