Merge branch 'master' into v1.6

This commit is contained in:
Ken Rice 2016-01-11 14:14:51 -06:00
commit c0707c84ab
92 changed files with 2486 additions and 2211 deletions

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,7 @@
<start application="spandsp_start_tone_detect" data="1"/>
<stop application="spandsp_stop_tone_detect" data=""/>
<!-- map tone events to Rayo CPA signal type -->
<event class="CUSTOM" subclass="DETECTED_TONE" type-header="Detected-Tone">
<event class="DETECTED_TONE" type-header="Detected-Tone">
<signal-type header-value="SIT" value="sit"/>
<signal-type header-value="BUSY_TONE" value="busy"/>
<signal-type header-value="REORDER_TONE" value="congestion"/>

View File

@ -6,7 +6,7 @@
<param name="hostname" value="localhost"/>
<param name="virtualhost" value="/"/>
<param name="username" value="guest"/>
<param name="password" value="guest"/>
<param name="password" value="guest"/>
<param name="port" value="5673"/>
<param name="heartbeat" value="0"/>
</connection>
@ -26,7 +26,7 @@
<param name="reconnect_interval_ms" value="1000"/>
<param name="send_queue_size" value="5000"/>
<param name="enable_fallback_format_fields" value="1"/>
<!-- The routing key is made from the format string, using the header values in the event specified in the format_fields.-->
<!-- Fields that are prefixed with a # are treated as literals rather than doing a header lookup -->
<param name="format_fields" value="#FreeSWITCH,FreeSWITCH-Hostname,Event-Name,Event-Subclass,Unique-ID"/>
@ -35,8 +35,8 @@
then the system will check additional configured header values.
-->
<!-- <param name="format_fields" value="#FreeSWITCH,FreeSWITCH-Hostname|#Unknown,Event-Name,Event-Subclass,Unique-ID"/> -->
<!-- <param name="eventFilter" value="SWITCH_EVENT_ALL"/> -->
<!-- <param name="event_filter" value="SWITCH_EVENT_ALL"/> -->
<param name="event_filter" value="SWITCH_EVENT_CHANNEL_CREATE,SWITCH_EVENT_CHANNEL_DESTROY,SWITCH_EVENT_HEARTBEAT,SWITCH_EVENT_DTMF"/>
</params>
</profile>
@ -48,7 +48,7 @@
<param name="hostname" value="localhost"/>
<param name="virtualhost" value="/"/>
<param name="username" value="guest"/>
<param name="password" value="guest"/>
<param name="password" value="guest"/>
<param name="port" value="5672"/>
<param name="heartbeat" value="0"/>
</connection>

View File

@ -1,6 +1,5 @@
<configuration name="modules.conf" description="Modules">
<modules>
<!-- Loggers (I'd load these first) -->
<load module="mod_console"/>
<!-- <load module="mod_graylog2"/> -->
@ -17,9 +16,11 @@
<!-- <load module="mod_xml_rpc"/> -->
<!-- <load module="mod_xml_curl"/> -->
<!-- <load module="mod_xml_cdr"/> -->
<!-- <load module="mod_xml_radius"/> -->
<!-- <load module="mod_xml_scgi"/> -->
<!-- Event Handlers -->
<!-- <load module="mod_amqp"/> -->
<load module="mod_cdr_csv"/>
<!-- <load module="mod_cdr_sqlite"/> -->
<!-- <load module="mod_event_multicast"/> -->
@ -27,6 +28,7 @@
<!-- <load module="mod_event_zmq"/> -->
<!-- <load module="mod_zeroconf"/> -->
<!-- <load module="mod_erlang_event"/> -->
<!-- <load module="mod_smpp"/> -->
<!-- <load module="mod_snmp"/> -->
<!-- Directory Interfaces -->
@ -126,7 +128,7 @@
<!-- <load module="mod_cepstral"/> -->
<!-- <load module="mod_tts_commandline"/> -->
<!-- <load module="mod_rss"/> -->
<!-- Say -->
<load module="mod_say_en"/>
<!-- <load module="mod_say_ru"/> -->

View File

@ -51,6 +51,9 @@ if test "${enable_64}" = "yes"; then
esac
fi
# use mtmalloc on Solaris SPARC if available
AS_CASE([$host], [sparc-*-solaris2*], [AC_CHECK_LIB(mtmalloc, malloc)])
# Whether to follow FHS
AC_ARG_ENABLE([fhs],[AS_HELP_STRING([--disable-fhs],
[Do Not follow the FHS when placing files and directories (default only when not specifying prefix])],[enable_fhs="$enableval"],[enable_fhs="yes"])

7
debian/bootstrap.sh vendored
View File

@ -851,7 +851,7 @@ Depends: \${misc:Depends}
Description: documentation for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This package contains Doxygen-produce documentation for FreeSWITCH.
This package contains Doxygen-produced documentation for FreeSWITCH.
It may be an empty package at the moment.
## misc
@ -1008,7 +1008,6 @@ EOF
print_conf_install () {
cat <<EOF
conf/${conf} /usr/share/freeswitch/conf
/usr/share/freeswitch/fonts
EOF
}
@ -1345,6 +1344,10 @@ grep -e '^Package:' control | grep -v '^freeswitch-all$' | while xread l; do
m="${l#*: }"
conf_merge freeswitch-all.install $m.install
done
echo "/usr/share/freeswitch/fonts" >> freeswitch-all.install
echo "/var/lib/freeswitch/images" >> freeswitch-all.install
for x in postinst postrm preinst prerm; do
cp -a freeswitch.$x freeswitch-all.$x
done

16
debian/util.sh vendored
View File

@ -454,26 +454,26 @@ build_all () {
dsc_opts="$dsc_opts -f${modtmp}"; fi
[ -n "$orig" ] || orig="$(create_orig $orig_opts HEAD | tail -n1)"
mkdir -p ../log
> ../log/changes
> ../log/changes.txt
echo; echo; echo; echo
trap 'echo "Killing children...">&2; for x in $(jobs -p); do kill $x; done' EXIT
if [ "${orig:0:2}" = ".." ]; then
echo "true" > ../log/builds-ok
echo "true" > ../log/builds-ok.txt
for distro in $distros; do
echo "Creating $distro dsc..." >&2
local dsc="$(create_dsc $dsc_opts $distro $orig 2>../log/$distro | tail -n1)"
local dsc="$(create_dsc $dsc_opts $distro $orig 2>../log/$distro.txt | tail -n1)"
echo "Done creating $distro dsc." >&2
if [ "${dsc:0:2}" = ".." ]; then
local lopts="-b"
for arch in $archs; do
{
echo "Building $distro-$arch debs..." >&2
local changes="$(build_debs $lopts $deb_opts $distro $dsc $arch 2>../log/$distro-$arch | tail -n1)"
local changes="$(build_debs $lopts $deb_opts $distro $dsc $arch 2>../log/$distro-$arch.txt | tail -n1)"
echo "Done building $distro-$arch debs." >&2
if [ "${changes:0:2}" = ".." ]; then
echo "$changes" >> ../log/changes
echo "$changes" >> ../log/changes.txt
else
echo "false" > ../log/builds-ok
echo "false" > ../log/builds-ok.txt
fi
} &
$par || wait
@ -485,8 +485,8 @@ build_all () {
fi
[ -z "$modlist" ] || rm -f $modtmp
trap - EXIT
cat ../log/changes
test "$(cat ../log/builds-ok)" = true || exit 1
cat ../log/changes.txt
test "$(cat ../log/builds-ok.txt)" = true || exit 1
}
usage () {

View File

@ -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;
@ -565,8 +558,9 @@
video.optional.push({sourceId: obj.options.useCamera});
}
if (bestFrameRate && !window.moz) {
video.optional.push({minFrameRate: bestFrameRate});
if (bestFrameRate) {
video.optional.push({minFrameRate: bestFrameRate});
video.optional.push({maxFrameRate: bestFrameRate});
}
} else {
@ -1124,13 +1118,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,

View File

@ -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 += "<button class='ctlbtn' id='" + kick_id + "'>Kick</button>" +
"<button class='ctlbtn' id='" + tmute_id + "'>Mute</button>" +
"<button class='ctlbtn' id='" + gainup_id + "'>Gain -</button>" +
"<button class='ctlbtn' id='" + gaindn_id + "'>Gain +</button>" +
"<button class='ctlbtn' id='" + voldn_id + "'>Vol -</button>" +
"<button class='ctlbtn' id='" + volup_id + "'>Vol +</button>" +
"<button class='ctlbtn' id='" + transfer_id + "'>Transfer</button>";
@ -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;
}
@ -1697,7 +1708,22 @@
$(vlselect_id).append(new Option("Choose a Layout", "none"));
if (e.data.responseData) {
options = e.data.responseData.sort();
var rdata = [];
for (var i in e.data.responseData) {
rdata.push(e.data.responseData[i].name);
}
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 ) );
});
for (var i in options) {
$(vlselect_id).append(new Option(options[i], options[i]));

View File

@ -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
grunt serve
to Install on Debian 8
./debian8_install.sh

View File

@ -47,7 +47,7 @@
},
"resolutions": {
"angular": "~1.3.15",
"angular-bootstrap": "~0.13.3"
"angular-bootstrap": "~0.14.3"
},
"overrides": {
"bootstrap": {

View File

@ -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

View File

@ -21,7 +21,6 @@ body {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 160px;
display: inline-block;
}
@ -604,12 +603,24 @@ body .modal-body .btn-group .btn.active {
transition-delay:0s;
}
#incall .dropdown-menu .selected {
background-color: #ccc;
color: white;
}
#incall .dropdown-menu .selected:hover {
background-color: #ccc;
color: white;
cursor: pointer;
}
#incall .video-hover-buttons .btn-group .dropdown-menu {
max-height: 200px;
overflow: auto;
}
#incall .video-hover-buttons .btn-group ul li a:hover {
#incall .video-hover-buttons .btn-group ul li a:not(.selected):hover {
background-color: #EEE;
cursor: pointer;
}
@ -850,6 +861,10 @@ body .modal-body .btn-group .btn.active {
padding-right: 360px;
}
.watcher #wrapper {
padding-right: 0;
}
#wrapper.toggled {
padding-right: 0;
}
@ -906,13 +921,11 @@ body .modal-body .btn-group .btn.active {
}
.members-name {
width: 160px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 140px;
}
.members-number {
width: 140px;
font-size: 10px;
}
@ -939,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;
@ -970,6 +988,7 @@ body .modal-body .btn-group .btn.active {
display: inline-block;
line-height: 16px;
margin-top: -3px;
width: 140px;
}
.chat-members .chat-members-status i {
@ -1018,6 +1037,17 @@ body .modal-body .btn-group .btn.active {
vertical-align: -2px;
}
.chat-members .resevartion-menu .icon {
color: #C5C5C5;
}
.chat-members .resevartion-menu .dropdown-menu {
min-width: 0;
}
.chat-members .resevartion-menu .dropdown-menu .selected {
font-weight: bold;
}
/*.chat-messages {*/
/*border-top: 1px solid #E5E5E5;*/
@ -1545,3 +1575,116 @@ body:-webkit-full-screen #incall .video-footer {
#preview .refresh {
margin: 15px 0px 0px 0px;
}
.watcher {
padding: 0;
background-color: #333333;
}
.watcher .navbar, .watcher #sidebar-wrapper, .watcher #dialpad {
display: none;
}
.watcher #wrapper.toggled {
padding-right: 0;
}
.watcher #incall .panel {
margin: 0;
}
.watcher #video-tag-wrapper {
background: linear-gradient(to bottom, #272627, #27252A);
background-color: #27252A;
}
.watcher #incall .video-call {
width: 100%;
height: 100%;
padding: 0;
max-width: none;
max-height: none;
}
.watcher #webcam {
max-width: 160.78vh;
margin: auto;
}
.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;
}
.unsupported {
color: grey;
font-size: 10px;
}
@keyframes growY {
from { max-height:2000px;}
to { max-height:0px;}
}

View File

@ -33,6 +33,18 @@
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<script>
if (location.search) {
var tmp = location.search;
location.search = '';
location.href = getPathFromUrl(location.href) + (location.hash ? location.hash : '#/') + tmp;
}
function getPathFromUrl(url) {
return url.split(/[?#]/)[0];
}
</script>
</head>
<body>

View File

@ -17,86 +17,31 @@
<p class="text-center text-muted">There are no members to show.</p>
</div>
<div ng-repeat="member in members" class="chat-member-item">
<div ng-repeat="member in members" class="chat-member-item" ng-class="{ opened: $index == openId }">
<span class="chat-members-avatar">
<img gravatar-size="40" gravatar-src="::member.email" class="img-circle" ng-class="{'chat-member-talking': member.status.audio.talking, 'chat-member-muted': member.status.audio.muted}" />
</span>
<!-- FIXME(italo): Put this whole block in a flex box to avoid defining fixed width.-->
<h4 class="chat-members-name">
<div class="members-name">{{ member.name }}</div>
<h4 class="chat-members-name" ng-class="{ 'clickable': verto.data.confRole == 'moderator' }" ng-click="toggleModMenu($index)">
<div class="ellipsis members-name">{{ member.name }}</div>
<small class="ellipsis members-number">({{ member.number }})</small>
<div class="members-badges">
<div ng-if="member.status.video.floor" class="label badge-floor" ng-class="{'label-danger': member.status.video.floorLocked, 'label-info': !member.status.video.floorLocked}"><i class="mdi mdi-action-https lock-floor" ng-if="member.status.video.floorLocked"></i> <span>Floor</span></div>
<div ng-if="member.status.video.reservationID == 'presenter'" class="label label-info">Presenter</div>
<div class="label label-info text-capitalize">{{ member.status.video.reservationID }}</div>
<div ng-if="member.status.video.screenShare" class="label label-info">Screen Share</div>
</div>
</h4>
<div class="pull-right action-buttons chat-members-action" ng-show="verto.data.confRole == 'moderator'">
<div class="pull-right resevartion-menu chat-members-action" ng-show="verto.data.confRole == 'moderator' && resIDs.length > 0">
<div class="btn-group">
<button type="button" class="btn btn-xs dropdown-toggle" data-toggle="dropdown">
<i class="mdi-navigation-more-vert dark" style="margin-right: 0px;"></i>
<i class="mdi-action-picture-in-picture icon" style="margin-right: 0px;"></i>
</button>
<ul class="dropdown-menu slidedown pull-right">
<li>
<a href="" ng-click="confKick(member.id)">
<span class="mdi-fw mdi-av-not-interested"></span>
Kick
</a>
</li>
<li>
<a href="" ng-click="confMuteMic(member.id)">
<span class="mdi-fw mdi-av-mic-off"></span>
Mute/Unmute Mic
</a>
</li>
<li>
<a href="" ng-click="confMuteVideo(member.id)">
<span class="mdi-fw mdi-av-videocam-off"></span>
Mute/Unmute Video
</a>
</li>
<li>
<a href="" ng-click="confPresenter(member.id)">
<span class="mdi-fw mdi-action-picture-in-picture"></span>
Presenter
</a>
</li>
<li>
<a href="" ng-click="confVideoFloor(member.id)">
<span class="mdi-fw mdi-action-aspect-ratio"></span>
Video Floor
</a>
</li>
<li>
<a href="" ng-click="confBanner(member.id)">
<span class="mdi-fw mdi-av-subtitles"></span>
Banner
</a>
</li>
<li>
<a href="" ng-click="confResetBanner(member.id)">
<span class="mdi-fw mdi-content-clear"></span>
Reset Banner
</a>
</li>
<li>
<a href="" ng-click="confVolumeDown(member.id)">
<span class="mdi-fw mdi-av-volume-down"></span>
Vol
</a>
</li>
<li>
<a href="" ng-click="confVolumeUp(member.id)">
<span class="mdi-fw mdi-av-volume-up"></span>
Vol +
</a>
</li>
<li>
<a href="" ng-click="confTransfer(member.id)">
<span class="mdi-fw mdi-communication-call-made"></span>
Transfer
<li ng-repeat="resID in resIDs">
<a href="" class="text-capitalize" ng-class="{ 'selected': resID == member.status.video.reservationID }" ng-click="confResID(member.id, resID)">
{{ resID }}
</a>
</li>
</ul>
@ -107,6 +52,124 @@
<i ng-click="confMuteMic(member.id)" class="in-use" ng-class="{'clickable': verto.data.confRole == 'moderator', 'mdi-av-mic': !member.status.audio.muted, 'mdi-av-mic-off': member.status.audio.muted, 'mic_talking': member.status.audio.talking}"></i>
<i ng-click="confMuteVideo(member.id)" ng-class="{'clickable': verto.data.confRole == 'moderator', 'mdi-av-videocam': !member.status.video.muted, 'mdi-av-videocam-off': member.status.video.muted, 'in-use': (member.status.video && !member.status.video.muted), 'disabled': !member.status.video}"></i>
</span>
<div class="admin-controls" ng-if="verto.data.confRole == 'moderator'" ng-show="$index == $parent.openId">
<div>
<div class="col-md-6 ctrl-section">
<h3>General</h3>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confKick(member.id)" title="Kick">
<i class="mdi-fw mdi-av-not-interested"></i>
Kick
</a>
<a href="" class="btn btn-xs" ng-click="confVideoFloor(member.id)" title="Video Floor">
<i class="mdi-fw mdi-action-aspect-ratio"></i>
Floor
</a>
<a href="" class="btn btn-xs" ng-click="confTransfer(member.id)" title="Transfer">
<i class="mdi-fw mdi-communication-call-made"></i>
<span style="margin-left: -9px">Transfer</span>
</a>
</div>
</div>
<div class="col-md-6 ctrl-section">
<h3>Banner</h3>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confBanner(member.id)" title="Set">
<i class="mdi-fw mdi-toggle-radio-button-on"></i>
Set
</a>
<a href="" class="btn btn-xs" ng-click="confResetBanner(member.id)" title="Reset">
<i class="mdi-fw mdi-content-clear"></i>
Reset
</a>
</div>
</div>
</div>
<div>
<div class="col-md-6 ctrl-section" ng-if="conf.canvasCount > 1">
<h3>Canvas</h3>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confCanvasIn(member.id, 'prev')" title="Canvas In">
<i class="mdi-fw mdi-action-open-in-browser"></i>
Prev
</a>
<a href="" class="btn btn-xs" ng-click="confCanvasIn(member.id)" title="Canvas In">
<i class="mdi-fw mdi-action-open-in-browser"></i>
Id
</a>
<a href="" class="btn btn-xs" ng-click="confCanvasIn(member.id, 'next')" title="Canvas In">
<i class="mdi-fw mdi-action-open-in-browser"></i>
Next
</a>
</div>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confCanvasOut(member.id, 'prev')" title="Canvas Out">
<i class="mdi-fw mdi-fw mdi-action-system-update-tv"></i>
Prev
</a>
<a href="" class="btn btn-xs" ng-click="confCanvasOut(member.id)" title="Canvas Out">
<i class="mdi-fw mdi-fw mdi-action-system-update-tv"></i>
Id
</a>
<a href="" class="btn btn-xs" ng-click="confCanvasOut(member.id, 'next')" title="Canvas Out">
<i class="mdi-fw mdi-fw mdi-action-system-update-tv"></i>
Next
</a>
</div>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confLayer(member.id, 'prev')" title="Layer">
<i class="mdi-fw mdi-action-view-carousel"></i>
Prev
</a>
<a href="" class="btn btn-xs" ng-click="confLayer(member.id)" title="Layer">
<i class="mdi-fw mdi-action-view-carousel"></i>
Id
</a>
<a href="" class="btn btn-xs" ng-click="confLayer(member.id, 'next')" title="Layer">
<i class="mdi-fw mdi-action-view-carousel"></i>
Next
</a>
</div>
</div>
<div class="col-md-6 ctrl-section">
<h3>Audio/Video</h3>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confMuteMic(member.id)" title="Mute/Unmute Mic">
<i class="mdi-fw" ng-class="member.status.audio.muted ? 'mdi-av-mic-off' : 'mdi-av-mic'"></i>
{{ member.status.audio.muted ? 'Unmute' : 'Mute' }}
</a>
<a href="" ng-class="{ 'disabled': !member.status.video }" class="btn btn-xs" ng-click="confMuteVideo(member.id)" title="Mute/Unmute Video">
<i class="mdi-fw" ng-class="member.status.video.muted ? 'mdi-av-videocam-off' : 'mdi-av-videocam'"></i>
{{ member.status.video.muted ? 'Unmute' : 'Mute' }}
</a>
</div>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confVolumeDown(member.id)" title="Vol ">
<i class="mdi-fw mdi-av-volume-down"></i>
Vol
</a>
<a href="" class="btn btn-xs" ng-click="confVolumeUp(member.id)" title="Vol +">
<i class="mdi-fw mdi-av-volume-up"></i>
Vol +
</a>
</div>
<div class="group btn-group-justified">
<a href="" class="btn btn-xs" ng-click="confGainDown(member.id)" title="Gain ">
<i class="mdi-fw mdi-av-volume-down"></i>
Gain
</a>
<a href="" class="btn btn-xs" ng-click="confGainUp(member.id)" title="Gain +">
<i class="mdi-fw mdi-av-volume-up"></i>
Gain +
</a>
</div>
</div>
</div>
</div>
</div>
</div>
@ -125,7 +188,7 @@
<div class="chat-message-input">
<form ng-submit="send()" >
<div class="chat-message-input-group">
<textarea ng-model="message" ng-keyup="($event.keyCode == 13 && $event.shiftKey !== true) && send()" required="required" class="form-control input-sm" placeholder="Type your message here..."></textarea>
<textarea ng-model="message" ng-keydown="($event.keyCode == 13 && $event.shiftKey !== true) && send($event)" required="required" class="form-control input-sm" placeholder="Type your message here..."></textarea>
<button class="btn btn-success btn-sm" type="submit">
Send
<span class="mdi-navigation-arrow-forward chat-message-input-group-icon-button"></span>

View File

@ -1,5 +1,5 @@
<div class="centered-block-frame" id="incall">
<div class="col-md-12 centered-block" ng-class="{'video-call': storage.data.videoCall, 'phone-call': !storage.data.videoCall}">
<div class="col-md-12 centered-block" ng-class="storage.data.videoCall || watcher ? 'video-call' : 'phone-call'">
<div class="slide-animate height100" ng-include="callTemplate"></div>
</div>
</div>

View File

@ -63,6 +63,7 @@
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="#/?sessid=random" target="_blank">Open New Window</a></li>
<li><a href="" ng-click="openModal('partials/modal_logininfo.html', 'ModalLoginInformationController')">Change Login Information</a></li>
<!--<li><a href="#">View Device Settings</a></li>-->
<li><a href="" ng-click="logout()">Logout</a></li>

View File

@ -2,7 +2,6 @@
<h3 class="modal-title">Device Settings</h3>
</div>
<div class="modal-body">
<div class="form-group" ng-show="mydata.useVideo">
<label for="settings-camera">Camera:</label>
<select name="camera" id="settings-camera" class="form-control"
@ -25,8 +24,13 @@
</div>
<div class="form-group">
<label for="settings-microphone">Speaker:</label>
<select name="microphone" id="settings-microphone" class="form-control"
<label for="settings-microphone">
Speaker:
<span ng-show="!speakerFeature" class="unsupported">
Your browser doesn't seem to support this feature
</span>
</label>
<select name="microphone" id="settings-microphone" class="form-control" ng-disabled="!speakerFeature"
ng-model="mydata.selectedSpeaker" ng-options="item.id as item.label for item in verto.data.speakerDevices">
</select>
</div>
@ -68,6 +72,13 @@
</div>
<div class="form-group">
<label for="settings-framerate">Best frame rate:</label>
<select name="settings-framerate" id="settings-framerate" class="form-control"
ng-model="mydata.bestFrameRate"
ng-options="item.id as item.label for item in verto.framerate"></select>
</div>
<div class="form-group">
<label for="settings-microphone">Audio settings:</label>
<div class="checkbox">
@ -138,7 +149,6 @@
ng-options="item.id as item.label for item in verto.bandwidth"></select>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger pull-left btn-pull-left" ng-click="resetSettings()">Factory reset</button>

View File

@ -1,6 +1,6 @@
<div class="panel panel-default shadow-z-0">
<div class="video-wrapper">
<div class="video-hover-buttons" ng-show="verto.data.callState == 'active'">
<div class="video-hover-buttons" ng-show="verto.data.callState == 'active' && !watcher">
<div id="moderator-tools" ng-show="verto.data.confRole == 'moderator'">
<button tooltip-placement="bottom" tooltip-title="Play" uib-tooltip="Play"
class="btn btn-material-blue-900" ng-click="play()">
@ -31,7 +31,7 @@
</button>
<ul class="dropdown-menu">
<li ng-repeat="layout in verto.data.confLayouts">
<a ng-click="confChangeVideoLayout(layout)">{{ layout }}</a>
<a ng-click="confChangeVideoLayout(layout)" ng-class="{ 'selected': layout == videoLayout }">{{ layout }}</a>
</li>
</ul>
</div>
@ -68,6 +68,17 @@
</li>
</ul>
</div>
<div class="btn-group" ng-show="conf.canvasCount > 1">
<button tooltip-placement="bottom" tooltip-title="Popup" uib-tooltips="Popup" type="button" class="btn btn-material-blue-900 dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="mdi-image-filter-none"></i>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="canvas in canvases">
<a ng-click="confPopup(canvas.id)">{{ canvas.name }}</a>
</li>
</ul>
</div>
</div>
</div>
<div class="video-tag-wrapper" id="video-tag-wrapper" ng-dblclick="goFullscreen()" show-controls>
@ -80,13 +91,14 @@
<div class="row">
<div class="col-md-6 col-xs-6 text-left">
<div class="video-timer">
<timer start-time="start_time" autostart="false" interval="1000">{{hhours}}:{{mminutes}}:{{sseconds}}</timer>
<span ng-show="watcher" style="font-size: 18px">Room {{ extension }} - Canvas {{ canvasID }}</span>
<timer start-time="start_time" autostart="false" interval="1000" ng-if="!watcher">{{hhours}}:{{mminutes}}:{{sseconds}}</timer>
</div>
</div>
<div class="col-md-6 col-xs-6 text-right">
<button class="btn btn-danger" ng-click="hangup()">
<i class="mdi-communication-call-end"></i>
End Call
{{ watcher ? 'Close' : 'End Call' }}
</button>
</div>
</div>

View File

@ -38,7 +38,8 @@
googHighpassFilter: true,
googEchoCancellation: true,
autoBand: true,
testSpeedJoin: true
testSpeedJoin: true,
bestFrameRate: "15"
};
data.$default(defaultSettings);

View File

@ -1,3 +1,4 @@
(function() {
'use strict';
@ -49,6 +50,48 @@
});
});
$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);
// 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;
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);
}
});
};
function findMemberByUUID(uuid) {
var found = false;
for (var idx in $scope.members) {
@ -81,6 +124,10 @@
$scope.members.push(translateMember(member));
}
$rootScope.$on('hangupCall', function() {
$scope.openId = null;
});
$rootScope.$on('members.boot', function(event, members) {
$scope.$apply(function() {
clearConferenceChat();
@ -98,6 +145,11 @@
});
$rootScope.$on('members.del', function(event, uuid) {
if ($rootScope.watcher && $rootScope.master === uuid) {
verto.hangup();
window.close();
}
$scope.$apply(function() {
var memberIdx = findMemberByUUID(uuid);
if (memberIdx != -1) {
@ -138,10 +190,19 @@
/**
* Public methods.
*/
$scope.send = function() {
$scope.toggleModMenu = function(index) {
if (verto.data.confRole != 'moderator') return;
$scope.openId = $scope.openId == index ? null : index;
};
$scope.send = function(event) {
// Only conferencing chat is supported for now
// but still calling method with the conference prefix
// so we know that explicitly.
if (event && event.type == 'keydown') {
event.preventDefault();
}
verto.sendConferenceChat($scope.message);
$scope.message = CLEAN_MESSAGE;
};
@ -171,6 +232,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);
@ -191,6 +257,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';
@ -207,6 +308,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({
@ -221,6 +332,19 @@
}
});
};
function shortPrompt(text, cb) {
prompt({
title: text,
input: true,
label: '',
value: '',
}).then(function(val) {
if (val && cb) {
cb(val);
}
});
}
}
]);

View File

@ -10,6 +10,15 @@
eventQueue.process();
if ($location.search().autocall) {
$rootScope.dialpadNumber = $location.search().autocall;
delete $location.search().autocall;
call($rootScope.dialpadNumber);
if($rootScope.watcher) {
return;
}
}
$scope.call_history = CallHistory.all();
$scope.history_control = CallHistory.all_control();
$scope.has_history = Object.keys($scope.call_history).length;
@ -32,11 +41,6 @@
/**
* fill dialpad via querystring [?autocall=\d+]
*/
if ($location.search().autocall) {
$rootScope.dialpadNumber = $location.search().autocall;
delete $location.search().autocall;
call($rootScope.dialpadNumber);
}
/**
* fill in dialpad via config.json
@ -83,6 +87,13 @@
return false;
}
if (extension.indexOf('-canvas-') != -1) {
$rootScope.watcher = true;
verto.call($rootScope.dialpadNumber, null, { useCamera: false, useMic: false, caller_id_name: null, userVariables: {}, caller_id_number: null, mirrorInput: false });
$location.path('/incall');
return;
}
storage.data.mutedVideo = false;
storage.data.mutedMic = false;

View File

@ -15,7 +15,6 @@
$scope.dialpadTemplate = '';
$scope.incall = true;
if (storage.data.videoCall) {
$scope.callTemplate = 'partials/video_call.html';
}
@ -25,6 +24,7 @@
if($scope.chatStatus) {
$scope.openChat();
}
buildCanvasesData();
});
});
@ -73,6 +73,8 @@
$scope.confChangeVideoLayout = function(layout) {
verto.data.conf.setVideoLayout(layout);
$scope.videoLayout = layout;
$rootScope.$emit('changedVideoLayout', layout);
};
$scope.confChangeSpeaker = function(speakerId) {
@ -80,6 +82,24 @@
$rootScope.$emit('changedSpeaker', speakerId);
};
$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 = 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;
console.log("opening new window to " + s);
var popup = window.open(s, "canvas_window_" + canvas_id, "toolbar=0,location=0,menubar=0,directories=0,width=" + width + ",height=" + height, + ',left=' + x + ',top=' + y);
popup.moveTo(x, y);
};
$scope.screenshare = function() {
if(verto.data.shareCall) {
verto.screenshareHangup();
@ -88,6 +108,14 @@
verto.screenshare(storage.data.called_number);
};
function buildCanvasesData() {
$scope.conf = verto.data.conf.params.laData;
$scope.canvases = [{ id: 1, name: 'Super Canvas' }];
for (var i = 1; i < $scope.conf.canvasCount; i++) {
$scope.canvases.push({ id: i+1, name: 'Canvas ' + (i+1) });
}
}
$scope.muteMic = verto.muteMic;
$scope.muteVideo = verto.muteVideo;

View File

@ -8,6 +8,24 @@
console.debug('Executing MainController.');
$rootScope.master = $location.search().master;
if ($location.search().watcher === 'true') {
$rootScope.watcher = true;
angular.element(document.body).addClass('watcher');
var dialpad;
var extension = dialpad = $location.search().extension;
var canvasID = $location.search().canvas_id;
if (dialpad) {
if (canvasID) {
dialpad += '-canvas-' + canvasID;
}
$rootScope.extension = extension;
$rootScope.canvasID = canvasID;
$location.search().autocall = dialpad;
}
}
var myVideo = document.getElementById("webcam");
$scope.verto = verto;
$scope.storage = storage;
@ -36,10 +54,9 @@
});
$rootScope.$on('changedSpeaker', function(event, speakerId) {
// This should provide feedback
//setAudioPlaybackDevice(<id>[,<callback>[,<callback arg>]]);
// if callback is set it will be called as callback(<bool success/fail>, <device name>, <arg if you supplied it>)
verto.data.call.setAudioPlaybackDevice(speakerId);
if (verto.data.call) {
verto.data.call.setAudioPlaybackDevice(speakerId, sinkIdCallback);
}
});
/**
@ -432,6 +449,11 @@
return;
}
if ($rootScope.watcher) {
window.close();
return;
}
//var hangupCallback = function(v, hangup) {
// if (hangup) {
// $location.path('/dialpad');
@ -447,6 +469,7 @@
verto.hangup();
$rootScope.$emit('hangupCall');
$location.path('/dialpad');
};
@ -504,6 +527,13 @@
});
};
function sinkIdCallback(success, deviceName) {
if (success) {
toastr.info('Speaker is now <span class="install">' + deviceName + '</a>', 'Success', { allowHtml: true });
} else {
toastr.error('Your browser doesn\'t seem to support this feature', 'Error');
}
}
}
);

View File

@ -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);
@ -47,7 +49,7 @@
if (confirm('Factory Reset Settings?')) {
storage.factoryReset();
$scope.logout();
$scope.ok();
$modalInstance.close('Ok.');
window.location.reload();
};
};
@ -58,6 +60,7 @@
$scope.mydata.outgoingBandwidth = 'default';
$scope.mydata.incomingBandwidth = 'default';
$scope.mydata.vidQual = 'hd';
$scope.mydata.testSpeedJoin = false;
} else {
$scope.mydata.testSpeedJoin = true;
}

View File

@ -32,4 +32,4 @@
}
});
})();
})();

View File

@ -93,6 +93,17 @@ var bandwidth = [{
label: 'Server Default'
}, ];
var framerate = [{
id: '15',
label: '15 FPS'
}, {
id: '20',
label: '20 FPS'
}, {
id: '30',
label: '30 FPS'
}, ];
var vertoService = angular.module('vertoService', ['ngCookies']);
vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'storage',
@ -203,6 +214,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
videoQuality: videoQuality,
videoResolution: videoResolution,
bandwidth: bandwidth,
framerate: framerate,
refreshDevicesCallback : function refreshDevicesCallback(callback) {
data.videoDevices = [{
@ -294,6 +306,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.');
@ -342,7 +376,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
maxWidth: w,
maxHeight: h,
minFrameRate: 15,
vertoBestFrameRate: 30
vertoBestFrameRate: storage.data.bestFrameRate
});
videoQuality.forEach(function(qual){
if (w === qual.width && h === qual.height) {
@ -391,7 +425,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 +456,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
if (data.confRole == "moderator") {
console.log('>>> conf.listVideoLayouts();');
conf.listVideoLayouts();
conf.modCommand('canvasInfo');
}
data.conf = conf;
@ -584,6 +639,11 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
var that = this;
function ourBootstrap() {
var sessid = $location.search().sessid;
if (sessid === 'random') {
sessid = $.verto.genUUID();
$location.search().sessid = sessid;
}
// Checking if we have a failed connection attempt before
// connecting again.
if (data.instance && !data.instance.rpcClient.socketReady()) {
@ -604,6 +664,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
googNoiseSuppression: storage.data.googNoiseSuppression || true,
googHighpassFilter: storage.data.googHighpassFilter || true
},
sessid: sessid,
iceServers: storage.data.useSTUN
}, callbacks);
@ -614,6 +675,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
jQuery.verto.unloadJobs.push(function() {
that.reloaded = true;
});
data.instance.deviceParams({
useCamera: storage.data.selectedVideo,
useSpeak: storage.data.selectedSpeaker,
@ -674,10 +736,10 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
*
* @param callback
*/
call: function(destination, callback) {
call: function(destination, callback, custom) {
console.debug('Attempting to call destination ' + destination + '.');
var call = data.instance.newCall({
var call = data.instance.newCall(angular.extend({
destination_number: destination,
caller_id_name: data.name,
caller_id_number: data.callerid ? data.callerid : data.email,
@ -694,7 +756,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
email : storage.data.email,
avatar: "http://gravatar.com/avatar/" + md5(storage.data.email) + ".png?s=600"
}
});
}, custom));
data.call = call;
@ -912,6 +974,21 @@ 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 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.

View File

@ -47,10 +47,10 @@ 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;}
if(bestFrameRate){video.optional.push({minFrameRate:bestFrameRate});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;}}
@ -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);}
@ -223,22 +222,21 @@ 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="<div id='"+div_id+"'><br>"+"<button class='ctlbtn' id='"+play_id+"'>Play</button>"+"<button class='ctlbtn' id='"+stop_id+"'>Stop</button>"+"<button class='ctlbtn' id='"+recording_id+"'>Record</button>"+"<button class='ctlbtn' id='"+rec_stop_id+"'>Record Stop</button>"+
(confMan.params.hasVid?"<button class='ctlbtn' id='"+snapshot_id+"'>PNG Snapshot</button>":"")+"<br><br></div>";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<confMan.canvasCount;j++){var vlayout_id="confman_vid_layout_"+j+"_"+confMan.serno;var vlselect_id="confman_vl_select_"+j+"_"+confMan.serno;var vlhtml="<div id='"+vlayout_id+"'><br>"+"<b>Video Layout Canvas "+(j+1)+"</b> <select onChange='$.verto.modfuncs.change_video_layout(\""+vlayout_id+"\", \""+j+"\")' id='"+vlselect_id+"'></select> "+"<br><br></div>";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="<div id='"+box_id+"'>";html+="<b>General Controls</b><hr noshade>";html+="<button class='ctlbtn' id='"+kick_id+"'>Kick</button>"+"<button class='ctlbtn' id='"+tmute_id+"'>Mute</button>"+"<button class='ctlbtn' id='"+voldn_id+"'>Vol -</button>"+"<button class='ctlbtn' id='"+volup_id+"'>Vol +</button>"+"<button class='ctlbtn' id='"+transfer_id+"'>Transfer</button>";if(confMan.params.hasVid){html+="<br><br><b>Video Controls</b><hr noshade>";html+="<button class='ctlbtn' id='"+tvmute_id+"'>VMute</button>"+"<button class='ctlbtn' id='"+tvpresenter_id+"'>Presenter</button>"+"<button class='ctlbtn' id='"+tvfloor_id+"'>Vid Floor</button>"+"<button class='ctlbtn' id='"+vbanner_id+"'>Banner</button>";if(confMan.canvasCount>1){html+="<br><br><b>Canvas Controls</b><hr noshade>"+"<button class='ctlbtn' id='"+canvas_in_set_id+"'>Set Input Canvas</button>"+"<button class='ctlbtn' id='"+canvas_in_prev_id+"'>Prev Input Canvas</button>"+"<button class='ctlbtn' id='"+canvas_in_next_id+"'>Next Input Canvas</button>"+"<br>"+"<button class='ctlbtn' id='"+canvas_out_set_id+"'>Set Watching Canvas</button>"+"<button class='ctlbtn' id='"+canvas_out_prev_id+"'>Prev Watching Canvas</button>"+"<button class='ctlbtn' id='"+canvas_out_next_id+"'>Next Watching Canvas</button>";}
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="<div id='"+box_id+"'>";html+="<b>General Controls</b><hr noshade>";html+="<button class='ctlbtn' id='"+kick_id+"'>Kick</button>"+"<button class='ctlbtn' id='"+tmute_id+"'>Mute</button>"+"<button class='ctlbtn' id='"+gainup_id+"'>Gain -</button>"+"<button class='ctlbtn' id='"+gaindn_id+"'>Gain +</button>"+"<button class='ctlbtn' id='"+voldn_id+"'>Vol -</button>"+"<button class='ctlbtn' id='"+volup_id+"'>Vol +</button>"+"<button class='ctlbtn' id='"+transfer_id+"'>Transfer</button>";if(confMan.params.hasVid){html+="<br><br><b>Video Controls</b><hr noshade>";html+="<button class='ctlbtn' id='"+tvmute_id+"'>VMute</button>"+"<button class='ctlbtn' id='"+tvpresenter_id+"'>Presenter</button>"+"<button class='ctlbtn' id='"+tvfloor_id+"'>Vid Floor</button>"+"<button class='ctlbtn' id='"+vbanner_id+"'>Banner</button>";if(confMan.canvasCount>1){html+="<br><br><b>Canvas Controls</b><hr noshade>"+"<button class='ctlbtn' id='"+canvas_in_set_id+"'>Set Input Canvas</button>"+"<button class='ctlbtn' id='"+canvas_in_prev_id+"'>Prev Input Canvas</button>"+"<button class='ctlbtn' id='"+canvas_in_next_id+"'>Next Input Canvas</button>"+"<br>"+"<button class='ctlbtn' id='"+canvas_out_set_id+"'>Set Watching Canvas</button>"+"<button class='ctlbtn' id='"+canvas_out_prev_id+"'>Prev Watching Canvas</button>"+"<button class='ctlbtn' id='"+canvas_out_next_id+"'>Next Watching Canvas</button>";}
html+="<br>"+"<button class='ctlbtn' id='"+layer_set_id+"'>Set Layer</button>"+"<button class='ctlbtn' id='"+layer_prev_id+"'>Prev Layer</button>"+"<button class='ctlbtn' id='"+layer_next_id+"'>Next Layer</button>"+"</div>";}
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<br><br>");}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<confMan.canvasCount;j++){var vlselect_id="#confman_vl_select_"+j+"_"+confMan.serno;var vlayout_id="#confman_vid_layout_"+j+"_"+confMan.serno;var x=0;var options;$(vlselect_id).selectmenu({});$(vlselect_id).selectmenu("enable");$(vlselect_id).empty();$(vlselect_id).append(new Option("Choose a Layout","none"));if(e.data.responseData){options=e.data.responseData.sort();for(var i in options){$(vlselect_id).append(new Option(options[i],options[i]));x++;}}
if(e.data["conf-command"]==="list-videoLayouts"){for(var j=0;j<confMan.canvasCount;j++){var vlselect_id="#confman_vl_select_"+j+"_"+confMan.serno;var vlayout_id="#confman_vid_layout_"+j+"_"+confMan.serno;var x=0;var options;$(vlselect_id).selectmenu({});$(vlselect_id).selectmenu("enable");$(vlselect_id).empty();$(vlselect_id).append(new Option("Choose a Layout","none"));if(e.data.responseData){var rdata=[];for(var i in e.data.responseData){rdata.push(e.data.responseData[i].name);}
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));});for(var i in options){$(vlselect_id).append(new Option(options[i],options[i]));x++;}}
if(x){$(vlselect_id).selectmenu('refresh',true);}else{$(vlayout_id).hide();}}}else{if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"<br><br>");if(confMan.lastTimeout){clearTimeout(confMan.lastTimeout);confMan.lastTimeout=0;}
confMan.lastTimeout=setTimeout(function(){$(confMan.params.displayID).html(confMan.destroyed?"":"Moderator Controls Ready<br><br>");},4000);}}}});if(confMan.params.hasVid){confMan.modCommand("list-videoLayouts",null,null);}}
var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};}
@ -259,15 +257,15 @@ dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,tr
return false;}
function find_name(id){for(var i in $.verto.audioOutDevices){var source=$.verto.audioOutDevices[i];if(source.id===id){return(source.label);}}
return id;}
$.verto.dialog.prototype.setAudioDevice=function(sinkId,callback,arg){var dialog=this;var element=dialog.audioStream;if(typeof element.sinkId!=='undefined'){console.info("Dialog: "+dialog.callID+" Setting speaker:",element,find_name(sinkId));element.setSinkId(sinkId).then(function(){console.log("Dialog: "+dialog.callID+' Success, audio output device attached: '+sinkId);if(callback){callback(true,arg);}}).catch(function(error){var errorMessage=error;if(error.name==='SecurityError'){errorMessage="Dialog: "+dialog.callID+' You need to use HTTPS for selecting audio output '+'device: '+error;}
if(callback){callback(false,arg);}
console.error(errorMessage);});}else{console.warn("Dialog: "+dialog.callID+' Browser does not support output device selection.');if(callback){callback(false,arg);}}}
$.verto.dialog.prototype.setAudioPlaybackDevice=function(sinkId,callback,arg){var dialog=this;var element=dialog.audioStream;if(typeof element.sinkId!=='undefined'){var devname=find_name(sinkId);console.info("Dialog: "+dialog.callID+" Setting speaker:",element,devname);element.setSinkId(sinkId).then(function(){console.log("Dialog: "+dialog.callID+' Success, audio output device attached: '+sinkId);if(callback){callback(true,devname,arg);}}).catch(function(error){var errorMessage=error;if(error.name==='SecurityError'){errorMessage="Dialog: "+dialog.callID+' You need to use HTTPS for selecting audio output '+'device: '+error;}
if(callback){callback(false,null,arg);}
console.error(errorMessage);});}else{console.warn("Dialog: "+dialog.callID+' Browser does not support output device selection.');if(callback){callback(false,null,arg);}}}
$.verto.dialog.prototype.setState=function(state){var dialog=this;if(dialog.state==$.verto.enum.state.ringing){dialog.stopRinging();}
if(dialog.state==state||!checkStateChange(dialog.state,state)){console.error("Dialog "+dialog.callID+": INVALID state change from "+dialog.state.name+" to "+state.name);dialog.hangup();return false;}
console.log("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;}
if(!dialog.cause){dialog.cause="NORMAL CLEARING";}
if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);}
switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"){setTimeout(function(){dialog.setAudioDevice(speaker);},500);}
switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"){setTimeout(function(){dialog.setAudioPlaybackDevice(speaker);},500);}
break;case $.verto.enum.state.trying:setTimeout(function(){if(dialog.state==$.verto.enum.state.trying){dialog.setState($.verto.enum.state.hangup);}},30000);break;case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});}
dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();}
break;}

View File

@ -151,6 +151,7 @@ AC_ARG_ENABLE(builtin_tiff,
AC_FUNC_ERROR_AT_LINE
AC_FUNC_VPRINTF
AC_FUNC_MEMCMP
AC_FUNC_MEMMOVE
if test "${ax_cv_c_compiler_vendor}" = "gnu"
then
AC_FUNC_REALLOC

View File

@ -32,6 +32,7 @@
#include <inttypes.h>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#if defined(HAVE_TGMATH_H)
#include <tgmath.h>
#endif

View File

@ -43,6 +43,7 @@
#include "floating_fudge.h"
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "spandsp/telephony.h"
#include "spandsp/fast_convert.h"

View File

@ -33,6 +33,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#if defined(HAVE_TGMATH_H)
#include <tgmath.h>
#endif

View File

@ -145,7 +145,8 @@ sub sendmsg($$$) {
for(;;) {
$e = $self->readhash(undef);
last if $e->{socketerror} or $e->{'content-type'} eq 'command/reply';
last if $e->{socketerror} or $e->{'content-type'} eq 'command/reply'
or $e->{'content-type'} eq 'api/response';
push @{$self->{events}}, $e;
}

View File

@ -227,6 +227,29 @@ struct switch_core_session;
struct switch_core_runtime;
struct switch_core_port_allocator;
static inline void *switch_must_malloc(size_t _b)
{
void *m = malloc(_b);
switch_assert(m);
return m;
}
static inline void *switch_must_realloc(void *_b, size_t _z)
{
void *m = realloc(_b, _z);
switch_assert(m);
return m;
}
static inline char *switch_must_strdup(const char *_s)
{
char *s = strdup(_s);
switch_assert(s);
return s;
}
/*!
\defgroup core1 Core Library
\ingroup FREESWITCH

View File

@ -342,7 +342,8 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c
SWITCH_DECLARE(switch_bool_t) switch_core_session_in_video_thread(switch_core_session_t *session);
SWITCH_DECLARE(switch_bool_t) switch_core_media_check_dtls(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(switch_status_t) switch_core_media_set_outgoing_bitrate(switch_core_session_t *session, switch_media_type_t type, uint32_t bitrate);
SWITCH_DECLARE(switch_status_t) switch_core_media_reset_jb(switch_core_session_t *session, switch_media_type_t type);
SWITCH_END_EXTERN_C
#endif
/* For Emacs:

View File

@ -269,6 +269,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, switch_port_t remote_rtcp_port,
switch_bool_t change_adv_addr, const char **err);
SWITCH_DECLARE(void) switch_rtp_reset_jb(switch_rtp_t *rtp_session);
SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session);
SWITCH_DECLARE(switch_port_t) switch_rtp_get_remote_port(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_reset_media_timer(switch_rtp_t *rtp_session);

View File

@ -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"

View File

@ -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)

View File

@ -845,10 +845,12 @@ 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;
}
if (context->bandwidth > sane) {
sane = switch_calc_bitrate(1920, 1080, 2, 30);
if (context->bandwidth / 8 > sane) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BITRATE TRUNCATED TO %d\n", sane);
context->bandwidth = sane * 8;
}
@ -860,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;
@ -880,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
@ -958,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;

View File

@ -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 <group>] [domain <domain>] [user <user>] [context <context>]"
SWITCH_STANDARD_API(list_users_function)
{
@ -307,8 +418,9 @@ SWITCH_STANDARD_API(list_users_function)
int32_t arg = 0;
switch_xml_t xml_root, x_domains, x_domain_tag;
switch_xml_t gts, gt, uts, ut;
char *_user = NULL, *_domain = NULL, *_search_context = NULL, *_group = NULL;
char *_user = NULL, *_search_context = NULL, *_group = NULL, *section = "directory";
char *tag_name = NULL, *key_name = NULL, *key_value = NULL;
char *_domain = NULL;
if ((pdata = strdup(cmd))) {
argc = switch_separate_string(pdata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
@ -333,13 +445,19 @@ SWITCH_STANDARD_API(list_users_function)
}
}
}
if (_domain) {
tag_name = "domain";
key_name = "name";
key_value = _domain;
}
stream->write_function(stream, "userid|context|domain|group|contact|callgroup|effective_caller_id_name|effective_caller_id_number\n");
if (switch_xml_locate("directory", NULL, NULL, NULL, &xml_root, &x_domains, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
if (switch_xml_locate(section, tag_name, key_name, key_value, &xml_root, &x_domains, NULL, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
struct user_struct us = { 0 };
for (x_domain_tag = switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
for (x_domain_tag = _domain ? x_domains : switch_xml_child(x_domains, "domain"); x_domain_tag; x_domain_tag = x_domain_tag->next) {
switch_xml_t x_vars, x_var;
us.dname = (char*)switch_xml_attr_soft(x_domain_tag, "name");
@ -904,9 +1022,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(&params, SWITCH_EVENT_REQUEST_PARAMS);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "group", group_name);
@ -917,8 +1032,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 +1119,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 +1143,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);

View File

@ -103,7 +103,8 @@ api_command_t conference_api_sub_commands[] = {
{"vid-write-png", (void_fn_t) & conference_api_sub_write_png, CONF_API_SUB_ARGS_SPLIT, "vid-write-png", "<path>"},
{"vid-fps", (void_fn_t) & conference_api_sub_vid_fps, CONF_API_SUB_ARGS_SPLIT, "vid-fps", "<fps>"},
{"vid-bgimg", (void_fn_t) & conference_api_sub_canvas_bgimg, CONF_API_SUB_ARGS_SPLIT, "vid-bgimg", "<file> | clear [<canvas-id>]"},
{"vid-bandwidth", (void_fn_t) & conference_api_sub_vid_bandwidth, CONF_API_SUB_ARGS_SPLIT, "vid-bandwidth", "<BW>"}
{"vid-bandwidth", (void_fn_t) & conference_api_sub_vid_bandwidth, CONF_API_SUB_ARGS_SPLIT, "vid-bandwidth", "<BW>"},
{"vid-personal", (void_fn_t) & conference_api_sub_vid_personal, CONF_API_SUB_ARGS_SPLIT, "vid-personal", "[on|off]"}
};
switch_status_t conference_api_sub_pause_play(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
@ -1000,6 +1001,29 @@ switch_status_t conference_api_sub_volume_out(conference_member_t *member, switc
return SWITCH_STATUS_SUCCESS;
}
switch_status_t conference_api_sub_vid_personal(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
int on = 0;
if (!conference->canvases[0]) {
stream->write_function(stream, "-ERR conference is not in mixing mode\n");
return SWITCH_STATUS_SUCCESS;
}
if (argv[2]) {
on = switch_true(argv[2]);
if (on) {
conference_utils_set_flag(conference, CFLAG_PERSONAL_CANVAS);
} else {
conference_utils_clear_flag(conference, CFLAG_PERSONAL_CANVAS);
}
}
stream->write_function(stream, "+OK personal is %s\n", on ? "on" : "off");
return SWITCH_STATUS_SUCCESS;
}
switch_status_t conference_api_sub_vid_bandwidth(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
uint32_t i;
@ -1577,21 +1601,15 @@ 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 {
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;
}

View File

@ -42,7 +42,7 @@
#include <mod_conference.h>
inline switch_bool_t conference_cdr_test_mflag(conference_cdr_node_t *np, member_flag_t mflag)
static inline switch_bool_t conference_cdr_test_mflag(conference_cdr_node_t *np, member_flag_t mflag)
{
return !!np->mflags[mflag];
}

View File

@ -42,6 +42,21 @@
#include <mod_conference.h>
static cJSON *get_canvas_info(mcu_canvas_t *canvas)
{
cJSON *obj = cJSON_CreateObject();
cJSON_AddItemToObject(obj, "canvasID", cJSON_CreateNumber(canvas->canvas_id));
cJSON_AddItemToObject(obj, "totalLayers", cJSON_CreateNumber(canvas->total_layers));
cJSON_AddItemToObject(obj, "layersUsed", cJSON_CreateNumber(canvas->layers_used));
cJSON_AddItemToObject(obj, "layoutFloorID", cJSON_CreateNumber(canvas->layout_floor_id));
if (canvas->vlayout) {
cJSON_AddItemToObject(obj, "layoutName", cJSON_CreateString(canvas->vlayout->name));
}
return obj;
}
void conference_event_mod_channel_handler(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id)
{
cJSON *data, *addobj = NULL;
@ -63,6 +78,7 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
if ((data = cJSON_GetObjectItem(json, "data"))) {
action = cJSON_GetObjectCstr(data, "command");
if ((jid = cJSON_GetObjectItem(data, "id"))) {
if (jid->valueint) {
switch_snprintf(cid, sizeof(cid), "%d", jid->valueint);
@ -151,6 +167,68 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
switch_thread_rwlock_unlock(conference->rwlock);
}
goto end;
} else if (!strcasecmp(action, "canvasInfo")) {
cJSON *j_member_id;
int member_id = 0;
int i = 0;
cJSON *array = cJSON_CreateArray();
conference_obj_t *conference;
if ((conference = conference_find(conference_name, NULL))) {
if ((j_member_id = cJSON_GetObjectItem(data, "memberID"))) {
if (j_member_id->valueint) {
member_id = j_member_id->valueint;
} else if (j_member_id->valuedouble) {
member_id = (int) j_member_id->valuedouble;
} else if (j_member_id->valuestring) {
member_id = atoi(j_member_id->valuestring);
}
if (member_id < 0) member_id = 0;
}
if (member_id > 0) {
conference_member_t *member;
if ((member = conference_member_get(conference, member_id))) {
mcu_canvas_t *canvas;
if ((canvas = conference_video_get_canvas_locked(member))) {
cJSON *obj;
if ((obj = get_canvas_info(canvas))) {
cJSON_AddItemToObject(obj, "layerID", cJSON_CreateNumber(member->video_layer_id));
cJSON_AddItemToArray(array, obj);
}
conference_video_release_canvas(&canvas);
}
switch_thread_rwlock_unlock(member->rwlock);
}
} else {
switch_mutex_lock(conference->canvas_mutex);
for (i = 0; i <= conference->canvas_count; i++) {
mcu_canvas_t *canvas = conference->canvases[i];
if (canvas) {
cJSON *obj;
if ((obj = get_canvas_info(canvas))) {
cJSON_AddItemToArray(array, obj);
}
}
}
switch_mutex_unlock(conference->canvas_mutex);
}
switch_thread_rwlock_unlock(conference->rwlock);
}
addobj = array;
} else if (!strcasecmp(action, "list-videoLayouts")) {
switch_hash_index_t *hi;
void *val;
@ -161,17 +239,49 @@ void conference_event_mod_channel_handler(const char *event_channel, cJSON *json
switch_mutex_lock(conference_globals.setup_mutex);
if (conference->layout_hash) {
for (hi = switch_core_hash_first(conference->layout_hash); hi; hi = switch_core_hash_next(&hi)) {
video_layout_t *vlayout;
cJSON *obj = cJSON_CreateObject();
cJSON *resarray = cJSON_CreateArray();
int i;
switch_core_hash_this(hi, &vvar, NULL, &val);
cJSON_AddItemToArray(array, cJSON_CreateString((char *)vvar));
vlayout = (video_layout_t *)val;
for (i = 0; i < vlayout->layers; i++) {
if (vlayout->images[i].res_id) {
cJSON_AddItemToArray(resarray, cJSON_CreateString((char *)vlayout->images[i].res_id));
}
}
cJSON_AddItemToObject(obj, "type", cJSON_CreateString("layout"));
cJSON_AddItemToObject(obj, "name", cJSON_CreateString((char *)vvar));
cJSON_AddItemToObject(obj, "resIDS", resarray);
cJSON_AddItemToArray(array, obj);
}
}
if (conference->layout_group_hash) {
for (hi = switch_core_hash_first(conference->layout_group_hash); hi; hi = switch_core_hash_next(&hi)) {
char *name;
cJSON *obj = cJSON_CreateObject();
cJSON *grouparray = cJSON_CreateArray();
layout_group_t *lg;
video_layout_node_t *vlnode;
switch_core_hash_this(hi, &vvar, NULL, &val);
lg = (layout_group_t *) val;
name = switch_mprintf("group:%s", (char *)vvar);
cJSON_AddItemToArray(array, cJSON_CreateString(name));
for (vlnode = lg->layouts; vlnode; vlnode = vlnode->next) {
cJSON_AddItemToArray(grouparray, cJSON_CreateString(vlnode->vlayout->name));
}
cJSON_AddItemToObject(obj, "type", cJSON_CreateString("layoutGroup"));
cJSON_AddItemToObject(obj, "name", cJSON_CreateString(name));
cJSON_AddItemToObject(obj, "groupLayouts", grouparray);
cJSON_AddItemToArray(array, obj);
free(name);
}
}
@ -381,7 +491,7 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ);
switch_core_media_gen_key_frame(member->session);
if (conference && conference->la && member->session) {
if (conference && conference->la && member->session && !switch_channel_test_flag(member->channel, CF_VIDEO_ONLY)) {
cJSON *msg, *data;
const char *uuid = switch_core_session_get_uuid(member->session);
const char *cookie = switch_channel_get_variable(member->channel, "event_channel_cookie");
@ -409,14 +519,6 @@ void conference_event_adv_la(conference_obj_t *conference, conference_member_t *
cJSON_AddItemToObject(data, "secondScreen", cJSON_CreateTrue());
}
if (switch_channel_test_flag(member->channel, CF_VIDEO_ONLY)) {
cJSON_AddItemToObject(data, "videoOnly", cJSON_CreateTrue());
}
if (switch_true(switch_channel_get_variable_dup(member->channel, "video_screen_share", SWITCH_FALSE, -1))) {
cJSON_AddItemToObject(data, "screenShare", cJSON_CreateTrue());
}
if (conference_utils_member_test_flag(member, MFLAG_MOD)) {
cJSON_AddItemToObject(data, "modChannel", cJSON_CreateString(conference->mod_event_channel));
}

View File

@ -746,15 +746,24 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
}
if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) {
member->reset_media = 10;
switch_channel_audio_sync(member->channel);
switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA);
member->loop_loop = 1;
}
if (member->reset_media) {
if (--member->reset_media > 0) {
goto do_continue;
}
if (conference_member_setup_media(member, member->conference)) {
switch_mutex_unlock(member->read_mutex);
break;
}
member->loop_loop = 1;
goto do_continue;
goto do_continue;
}
if (switch_test_flag(read_frame, SFF_CNG)) {
@ -1199,10 +1208,10 @@ void conference_loop_output(conference_member_t *member)
uint32_t mux_used = 0;
if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) {
switch_cond_next();
continue;
}
//if (member->reset_media || switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) {
// switch_cond_next();
// continue;
//}
switch_mutex_lock(member->write_mutex);

View File

@ -708,15 +708,6 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m
switch_queue_create(&member->dtmf_queue, 100, member->pool);
if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) {
video_layout_t *vlayout = NULL;
if ((vlayout = conference_video_get_layout(conference, conference->video_layout_name, conference->video_layout_group))) {
conference_video_init_canvas(conference, vlayout, &member->canvas);
conference_video_init_canvas_layers(conference, member->canvas, vlayout);
}
}
conference->members = member;
conference_utils_member_set_flag_locked(member, MFLAG_INTREE);
switch_mutex_unlock(conference->member_mutex);
@ -1646,7 +1637,7 @@ int conference_member_setup_media(conference_member_t *member, conference_obj_t
}
switch_core_session_get_read_impl(member->session, &member->orig_read_impl);
member->native_rate = read_impl.samples_per_second;
member->native_rate = member->orig_read_impl.samples_per_second;
/* Setup a Signed Linear codec for reading audio. */
if (switch_core_codec_init(&member->read_codec,

View File

@ -193,6 +193,8 @@ void conference_utils_set_cflags(const char *flags, conference_flag_t *f)
f[CFLAG_VIDEO_BRIDGE_FIRST_TWO] = 1;
} else if (!strcasecmp(argv[i], "video-required-for-canvas")) {
f[CFLAG_VIDEO_REQUIRED_FOR_CANVAS] = 1;
} else if (!strcasecmp(argv[i], "video-mute-exit-canvas")) {
f[CFLAG_VIDEO_MUTE_EXIT_CANVAS] = 1;
} else if (!strcasecmp(argv[i], "manage-inbound-video-bitrate")) {
f[CFLAG_MANAGE_INBOUND_VIDEO_BITRATE] = 1;
} else if (!strcasecmp(argv[i], "video-muxing-personal-canvas")) {

View File

@ -610,19 +610,31 @@ void conference_video_release_canvas(mcu_canvas_t **canvasP)
*canvasP = NULL;
}
void conference_video_clear_managed_kps(conference_member_t *member)
{
member->managed_kps_set = 0;
member->auto_kps_debounce_ticks = 0;
member->layer_loops = 0;
}
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) {
@ -644,6 +656,7 @@ void conference_video_detach_video_layer(conference_member_t *member)
member->avatar_patched = 0;
conference_video_check_used_layers(canvas);
canvas->send_keyframe = 1;
conference_video_clear_managed_kps(member);
if (conference_utils_test_flag(member->conference, CFLAG_JSON_STATUS)) {
conference_member_update_status_field(member);
@ -871,10 +884,10 @@ void conference_video_layer_set_banner(conference_member_t *member, mcu_layer_t
void conference_video_reset_video_bitrate_counters(conference_member_t *member)
{
member->managed_kps = 0;
member->blackouts = 0;
member->good_img = 0;
member->blanks = 0;
member->layer_loops = 0;
}
switch_status_t conference_video_attach_video_layer(conference_member_t *member, mcu_canvas_t *canvas, int idx)
@ -888,8 +901,13 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
channel = switch_core_session_get_channel(member->session);
if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
!conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
return SWITCH_STATUS_FALSE;
}
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;
}
@ -967,6 +985,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
switch_img_fill(canvas->img, layer->x_pos, layer->y_pos, layer->screen_w, layer->screen_h, &canvas->letterbox_bgcolor);
conference_video_reset_video_bitrate_counters(member);
conference_video_clear_managed_kps(member);
if (conference_utils_test_flag(member->conference, CFLAG_JSON_STATUS)) {
conference_member_update_status_field(member);
@ -1045,6 +1064,7 @@ void conference_video_init_canvas_layers(conference_obj_t *conference, mcu_canva
mcu_layer_t *layer = &canvas->layers[i];
if (layer->member) {
//conference_video_detach_video_layer(layer->member);
conference_video_clear_managed_kps(layer->member);
layer->member->video_layer_id = -1;
layer->member = NULL;
}
@ -1262,7 +1282,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;
}
@ -1585,7 +1605,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);
}
@ -1598,7 +1618,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) {
@ -1634,7 +1654,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;
}
@ -1719,6 +1739,11 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca
mcu_layer_t *layer = NULL;
int i;
if (conference_utils_test_flag(conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
!conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
return SWITCH_STATUS_FALSE;
}
switch_mutex_lock(canvas->mutex);
for (i = 0; i < canvas->total_layers; i++) {
@ -1793,7 +1818,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);
@ -1816,14 +1841,13 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
member->good_img = 0;
if (member->blanks == member->conference->video_fps.fps || (member->blanks % (int)(member->conference->video_fps.fps * 10)) == 0) {
member->managed_kps = 0;
switch_core_session_request_video_refresh(member->session);
}
if (member->blanks == member->conference->video_fps.fps * 5) {
member->blackouts++;
conference_video_check_avatar(member, SWITCH_TRUE);
member->managed_kps = 0;
conference_video_clear_managed_kps(member);
if (member->avatar_png_img) {
//if (layer) {
@ -1842,31 +1866,51 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
*imgP = img;
}
void conference_video_set_incoming_bitrate(conference_member_t *member, int kps)
void conference_video_set_incoming_bitrate(conference_member_t *member, int kps, switch_bool_t force)
{
switch_core_session_message_t msg = { 0 };
if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) {
return;
}
if (kps >= member->managed_kps) {
member->auto_kps_debounce_ticks = 0;
}
if (!force && kps < member->managed_kps && member->conference->auto_kps_debounce) {
member->auto_kps_debounce_ticks = member->conference->auto_kps_debounce / member->conference->video_fps.ms;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s setting bitrate debounce timer to %dms\n",
switch_channel_get_name(member->channel), member->conference->auto_kps_debounce);
member->managed_kps = kps;
member->managed_kps_set = 0;
return;
}
msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ;
msg.numeric_arg = kps * 1024;
msg.from = __FILE__;
switch_core_session_receive_message(member->session, &msg);
member->managed_kps_set = 1;
member->managed_kps = kps;
}
void conference_video_set_max_incoming_bitrate_member(conference_member_t *member, int kps)
{
member->max_bw_in = kps;
member->managed_kps = 0;
conference_video_clear_managed_kps(member);
}
void conference_video_set_absolute_incoming_bitrate_member(conference_member_t *member, int kps)
{
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)) {
conference_video_set_incoming_bitrate(member, kps);
conference_video_clear_managed_kps(member);
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, SWITCH_TRUE);
}
}
@ -1898,49 +1942,104 @@ 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 };
int kps = 0, kps_in = 0;
int max = 0;
int min_layer = 0, min = 0;
if (!conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) ||
switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) {
return;
}
if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) {
member->managed_kps = 0;
} else if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps) {
int kps = 256;
int w = 320;
int h = 240;
switch_core_media_get_vid_params(member->session, &vid_params);
if (layer) {
if (layer->screen_w > 320 && layer->screen_h > 240) {
w = layer->screen_w;
h = layer->screen_h;
}
if (!switch_channel_test_flag(member->channel, CF_VIDEO_READY) || !vid_params.width || !vid_params.height) {
return;
}
if (member->layer_loops < 10) {
return;
}
if (member->auto_kps_debounce_ticks) {
if (--member->auto_kps_debounce_ticks == 0) {
conference_video_set_incoming_bitrate(member, member->managed_kps, SWITCH_TRUE);
}
if (member->conference->force_bw_in || member->force_bw_in) {
if (!(kps = member->conference->force_bw_in)) {
kps = member->force_bw_in;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s setting bitrate to %dkps because it was forced.\n",
switch_channel_get_name(member->channel), kps);
return;
}
if (vid_params.width != member->vid_params.width || vid_params.height != member->vid_params.height) {
switch_core_session_request_video_refresh(member->session);
conference_video_clear_managed_kps(member);
}
member->vid_params = vid_params;
if (member->managed_kps_set) {
return;
}
if ((kps_in = switch_calc_bitrate(vid_params.width, vid_params.height,
member->conference->video_quality, (int)(member->conference->video_fps.fps))) < 512) {
kps_in = 512;
}
if (layer) {
kps = switch_calc_bitrate(layer->screen_w, layer->screen_h, member->conference->video_quality, (int)(member->conference->video_fps.fps));
} else {
kps = kps_in;
}
min_layer = kps / 2;
min = kps_in / 2;
if (min_layer > min) min = min_layer;
if (member->conference->max_bw_in) {
max = member->conference->max_bw_in;
} else {
max = member->max_bw_in;
}
if (member->conference->force_bw_in || member->force_bw_in) {
if (!(kps = member->conference->force_bw_in)) {
kps = member->force_bw_in;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s setting bitrate to %dkps because it was forced.\n",
switch_channel_get_name(member->channel), kps);
} else {
if (layer && conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps to accomodate %dx%d resolution\n",
switch_channel_get_name(member->channel), kps, layer->screen_w, layer->screen_h);
} else {
int max = 0;
if (layer) {
kps = switch_calc_bitrate(w, h, 1, (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",
switch_channel_get_name(member->channel), kps, layer->screen_w, layer->screen_h);
}
if (member->conference->max_bw_in) {
max = member->conference->max_bw_in;
} else {
max = member->max_bw_in;
}
if (max && kps > max) {
kps = max;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s overriding bitrate setting to %dkps because it was the max allowed.\n",
switch_channel_get_name(member->channel), kps);
}
kps = min;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because the user is not visible\n",
switch_channel_get_name(member->channel), kps);
}
conference_video_set_incoming_bitrate(member, kps);
}
if (kps) {
if (min > max) {
min = max;
}
if (max && kps > max) {
kps = max;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s overriding bitrate setting to %dkps because it was the max allowed.\n",
switch_channel_get_name(member->channel), kps);
}
if (min && kps < min) {
kps = min;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s overriding bitrate setting to %dkps because it was the min allowed.\n",
switch_channel_get_name(member->channel), kps);
}
conference_video_set_incoming_bitrate(member, kps, SWITCH_FALSE);
}
}
@ -2024,7 +2123,9 @@ 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;
int last_personal = conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) ? 1 : 0;
canvas->video_timer_reset = 1;
packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN);
@ -2037,9 +2138,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
int file_count = 0, check_async_file = 0, check_file = 0;
switch_image_t *async_file_img = NULL, *normal_file_img = NULL, *file_imgs[2] = { 0 };
switch_frame_t file_frame = { 0 };
int j = 0;
if (!conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) {
int j = 0, personal = conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) ? 1 : 0;
if (!personal) {
switch_mutex_lock(canvas->mutex);
if (canvas->new_vlayout) {
conference_video_init_canvas_layers(conference, canvas, NULL);
@ -2058,12 +2159,22 @@ 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();
if (last_personal != personal) {
do_refresh = 100;
count_changed = 1;
if ((last_personal = personal)) {
switch_mutex_lock(conference->member_mutex);
conference->new_personal_vlayout = canvas->vlayout;
switch_mutex_unlock(conference->member_mutex);
}
conference_utils_set_flag(conference, CFLAG_REFRESH_LAYOUT);
}
if (members_with_video != conference->members_with_video) {
do_refresh = 100;
count_changed = 1;
@ -2073,15 +2184,20 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
count_changed = 1;
}
if (count_changed && !conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) {
if (count_changed && !personal) {
layout_group_t *lg = NULL;
video_layout_t *vlayout = NULL;
int canvas_count = 0;
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) {
int no_muted = conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS);
int no_av = conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS);
int seen = conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN);
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) && (!no_muted || seen) && (!no_av || imember->avatar_png_img)
&& imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
canvas_count++;
}
}
@ -2105,11 +2221,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) {
@ -2125,7 +2243,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);
}
@ -2151,8 +2269,8 @@ 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) ||
conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
if (!imember->session || (!switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && !imember->avatar_png_img) ||
personal || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
continue;
}
@ -2166,7 +2284,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) {
@ -2211,7 +2329,17 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
continue;
}
if (conference->playing_video_file) {
if (conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) &&
!conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) && imember->video_layer_id > -1) {
conference_video_detach_video_layer(imember);
switch_img_free(&imember->video_mute_img);
if (imember->id == imember->conference->video_floor_holder) {
conference_video_set_floor_holder(conference, NULL, SWITCH_FALSE);
} else if (imember->id == imember->conference->last_video_floor_holder) {
conference->last_video_floor_holder = 0;
}
switch_core_session_rwunlock(imember->session);
continue;
}
@ -2226,6 +2354,11 @@ 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);
@ -2254,7 +2387,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 {
@ -2265,6 +2398,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
}
}
imember->layer_loops++;
conference_video_check_auto_bitrate(imember, layer);
if (layer) {
@ -2275,7 +2409,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
// switch_img_free(&layer->cur_img);
//}
if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN)) {
if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
layer->mute_patched = 0;
} else {
switch_image_t *tmp;
@ -2285,13 +2419,19 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
}
if (!layer->mute_patched) {
if (!imember->video_mute_img) {
conference_video_vmute_snap(imember, SWITCH_FALSE);
}
if (imember->video_mute_img || layer->mute_img) {
conference_video_clear_layer(layer);
if (!layer->mute_img && imember->video_mute_img) {
//layer->mute_img = switch_img_read_png(imember->video_mute_png, SWITCH_IMG_FMT_I420);
switch_img_copy(imember->video_mute_img, &layer->mute_img);
if (!layer->mute_img) {
if (imember->video_mute_img) {
//layer->mute_img = switch_img_read_png(imember->video_mute_png, SWITCH_IMG_FMT_I420);
switch_img_copy(imember->video_mute_img, &layer->mute_img);
}
}
if (layer->mute_img) {
@ -2339,7 +2479,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
switch_mutex_unlock(conference->member_mutex);
if (conference_utils_test_flag(conference, CFLAG_PERSONAL_CANVAS)) {
if (personal) {
layout_group_t *lg = NULL;
video_layout_t *vlayout = NULL;
conference_member_t *omember;
@ -2358,7 +2498,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;
}
@ -2367,6 +2507,13 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
conference_video_init_canvas_layers(conference, imember->canvas, conference->new_personal_vlayout);
layout_applied++;
}
if (!imember->canvas) {
if ((vlayout = conference_video_get_layout(conference, conference->video_layout_name, conference->video_layout_group))) {
conference_video_init_canvas(conference, vlayout, &imember->canvas);
conference_video_init_canvas_layers(conference, imember->canvas, vlayout);
}
}
if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) {
switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ);
@ -2375,7 +2522,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;
}
@ -2395,6 +2544,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, SWITCH_TRUE);
}
}
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
@ -2410,18 +2566,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++;
}
}
@ -2429,18 +2595,21 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
int i = 0;
mcu_layer_t *floor_layer = NULL;
if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) ||
switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) ||
(switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) ||
(switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) {
continue;
}
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) {
@ -2460,7 +2629,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;
}
@ -2471,7 +2640,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) {
@ -2533,8 +2701,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++) {
@ -2552,13 +2718,16 @@ 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;
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;
}
@ -2589,7 +2758,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);
@ -2680,20 +2849,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);
@ -2737,7 +2906,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;
}
@ -2887,9 +3056,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();
@ -2939,7 +3106,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;
}
@ -2954,7 +3121,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) {
@ -3087,7 +3254,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;
}
@ -3185,7 +3352,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;
}
@ -3256,7 +3423,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_
if (conference->last_video_floor_holder && (imember = conference_member_get(conference, conference->last_video_floor_holder))) {
switch_core_session_request_video_refresh(imember->session);
conference_video_clear_managed_kps(imember);
if (conference_utils_member_test_flag(imember, MFLAG_VIDEO_BRIDGE)) {
conference_utils_set_flag(conference, CFLAG_VID_FLOOR_LOCK);
}
@ -3273,7 +3440,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;
}
@ -3299,6 +3466,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_
switch_core_session_video_reinit(member->session);
conference->video_floor_holder = member->id;
conference_member_update_status_field(member);
conference_video_clear_managed_kps(member);
} else {
conference->video_floor_holder = 0;
}
@ -3316,7 +3484,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;
}
@ -3393,11 +3561,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) &&
@ -3440,11 +3608,10 @@ void conference_video_write_frame(conference_obj_t *conference, conference_membe
continue;
}
if (!isession || !switch_channel_test_flag(imember->channel, CF_VIDEO) ) {
continue;
if (switch_channel_test_flag(imember->channel, CF_VIDEO_READY) ) {
switch_core_session_request_video_refresh(imember->session);
}
switch_core_session_request_video_refresh(imember->session);
switch_core_session_rwunlock(isession);
}
}

View File

@ -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;
@ -310,7 +279,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
}
}
if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO) && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO_READY) && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY && (!conference_utils_test_flag(conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) || conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN))) {
members_with_video++;
}
@ -2410,6 +2379,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
char *video_codec_bandwidth = NULL;
char *no_video_avatar = NULL;
conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH;
int conference_video_quality = 1;
int auto_kps_debounce = 30000;
float fps = 15.0f;
uint32_t max_members = 0;
uint32_t announce_count = 0;
@ -2439,7 +2410,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");
@ -2721,6 +2693,23 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
terminate_on_silence = val;
} else if (!strcasecmp(var, "endconf-grace-time") && !zstr(val)) {
endconference_grace_time = val;
} else if (!strcasecmp(var, "video-quality") && !zstr(val)) {
int tmp = atoi(val);
if (tmp > -1 && tmp < 5) {
conference_video_quality = tmp;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video quality must be between 0 and 4\n");
}
} else if (!strcasecmp(var, "video-kps-debounce") && !zstr(val)) {
int tmp = atoi(val);
if (tmp >= 0) {
auto_kps_debounce = tmp;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "video-kps-debounce must be 0 or higher\n");
}
} else if (!strcasecmp(var, "video-mode") && !zstr(val)) {
if (!strcasecmp(val, "passthrough")) {
conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH;
@ -2789,7 +2778,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
conference->caller_controls = switch_core_strdup(conference->pool, caller_controls);
conference->moderator_controls = switch_core_strdup(conference->pool, moderator_controls);
conference->broadcast_chat_messages = broadcast_chat_messages;
conference->video_quality = conference_video_quality;
conference->auto_kps_debounce = auto_kps_debounce;
conference->conference_video_mode = conference_video_mode;
@ -2864,7 +2854,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, 1, (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);
}
@ -3185,6 +3175,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);

View File

@ -246,6 +246,7 @@ typedef enum {
CFLAG_VIDEO_REQUIRED_FOR_CANVAS,
CFLAG_PERSONAL_CANVAS,
CFLAG_REFRESH_LAYOUT,
CFLAG_VIDEO_MUTE_EXIT_CANVAS,
/////////////////////////////////
CFLAG_MAX
} conference_flag_t;
@ -560,8 +561,10 @@ typedef struct conference_obj {
char *video_letterbox_bgcolor;
char *no_video_avatar;
conference_video_mode_t conference_video_mode;
int video_quality;
int members_with_video;
int members_with_avatar;
uint32_t auto_kps_debounce;
switch_codec_settings_t video_codec_settings;
uint32_t canvas_width;
uint32_t canvas_height;
@ -746,12 +749,16 @@ struct conference_member {
char *video_logo;
char *video_mute_png;
char *video_reservation_id;
switch_vid_params_t vid_params;
uint32_t auto_kps_debounce_ticks;
uint32_t layer_loops;
switch_frame_buffer_t *fb;
switch_image_t *avatar_png_img;
switch_image_t *video_mute_img;
uint32_t floor_packets;
int blanks;
int managed_kps;
int managed_kps_set;
int blackouts;
int good_img;
int auto_avatar;
@ -762,6 +769,7 @@ struct conference_member {
int max_bw_in;
int force_bw_in;
int max_bw_out;
int reset_media;
};
typedef enum {
@ -1087,6 +1095,7 @@ switch_status_t conference_api_sub_transfer(conference_obj_t *conference, switch
switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_sub_norecord(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_sub_vid_bandwidth(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_sub_vid_personal(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv);
switch_status_t conference_api_dispatch(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv, const char *cmdline, int argn);
switch_status_t conference_api_sub_syntax(char **syntax);
switch_status_t conference_api_main_real(const char *cmd, switch_core_session_t *session, switch_stream_handle_t *stream);

View File

@ -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,

View File

@ -2206,7 +2206,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
var = switch_event_get_header(client->params, "url");
if (client->record.action) {
if (var && client->record.action) {
if (strcmp(var, client->record.action)) {
switch_event_add_header_string(client->one_time_params, SWITCH_STACK_BOTTOM, "url", client->record.action);
httapi_sync(client);

View File

@ -8,6 +8,8 @@
<param name="ssl-cacert" value="$${base_dir}/conf/cacert.pem"/>
<param name="ssl-verifyhost" value="true"/>
<param name="ssl-verifypeer" value="true"/>
<!-- default is 300 seconds, override here -->
<!--param name="connect-timeout" value="300"/>
</settings>
<profiles>

View File

@ -199,6 +199,8 @@ struct url_cache {
int ssl_verifyhost;
/** True if http/https file formats should be loaded */
int enable_file_formats;
/** How long to wait, in seconds, for TCP connection. If 0, use default value of 300 seconds */
long connect_timeout;
};
static url_cache_t gcache;
@ -326,6 +328,9 @@ static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, swi
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
if (cache->connect_timeout > 0) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, cache->connect_timeout);
}
if (!cache->ssl_verifypeer) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
} else {
@ -670,7 +675,7 @@ static char *url_cache_get(url_cache_t *cache, http_profile_t *profile, switch_c
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Failed to download URL %s\n", url);
cache->errors++;
}
} else if (!u) {
} else if (!u || (u->status == CACHED_URL_RX_IN_PROGRESS && !download)) {
filename = DOWNLOAD_NEEDED;
} else {
/* Wait until file is downloaded */
@ -1075,6 +1080,9 @@ static switch_status_t http_get(url_cache_t *cache, http_profile_t *profile, cac
switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, get_header_callback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *) url);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
if (cache->connect_timeout > 0) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, cache->connect_timeout);
}
if (!cache->ssl_verifypeer) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
} else {
@ -1477,6 +1485,7 @@ static switch_status_t do_config(url_cache_t *cache)
cache->ssl_verifyhost = 1;
cache->ssl_verifypeer = 1;
cache->enable_file_formats = 0;
cache->connect_timeout = 0;
/* get params */
settings = switch_xml_child(cfg, "settings");
@ -1513,6 +1522,9 @@ static switch_status_t do_config(url_cache_t *cache)
} else if (!strcasecmp(var, "ssl-verifypeer")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-verifypeer to %s\n", val);
cache->ssl_verifypeer = !switch_false(val); /* only disable if explicitly set to false */
} else if (!strcasecmp(var, "connect-timeout")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting connect-timeout to %s\n", val);
cache->connect_timeout = atoi(val);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var);
}
@ -1623,6 +1635,11 @@ static switch_status_t do_config(url_cache_t *cache)
status = SWITCH_STATUS_TERM;
goto done;
}
if (cache->connect_timeout < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "connect-timeout must be >= 0\n");
status = SWITCH_STATUS_TERM;
goto done;
}
cache->max_url = max_urls;
cache->default_max_age = (default_max_age_sec * 1000 * 1000); /* convert from seconds to nanoseconds */

View File

@ -1237,7 +1237,7 @@ static switch_status_t synth_channel_set_header(speech_channel_t *schannel, int
} else if (!strcasecmp("neutral", val)) {
synth_hdr->voice_param.gender = VOICE_GENDER_NEUTRAL;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(schannel->session_uuid), SWITCH_LOG_WARNING, "(%s) ignoring invalid voice gender, %s\n", schannel->name, val);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(schannel->session_uuid), SWITCH_LOG_WARNING, "(%s) ignoring invalid voice gender, %s\n", schannel->name, val);
break;
}
mrcp_resource_header_property_add(msg, SYNTHESIZER_HEADER_VOICE_GENDER);

View File

@ -23,6 +23,7 @@
*
* Contributor(s):
* Mathieu Rene <mrene@avgs.ca>
* Dragos Oancea <droancea@yahoo.com>
*
* mod_codec2 -- FreeSWITCH CODEC2 Module
*
@ -51,6 +52,10 @@ SWITCH_MODULE_DEFINITION(mod_codec2, mod_codec2_load, NULL, NULL);
struct codec2_context {
void *encoder;
void *decoder;
int mode; /* codec2 operation mode */
int nbit; /* nr of bits per frame */
int nbyte; /* nr of bytes per frame */
int nsam; /* nr of samples per frame */
#ifdef LOG_DATA
FILE *encoder_in;
FILE *encoder_out;
@ -61,6 +66,12 @@ struct codec2_context {
#endif
};
struct {
int mode;
int ptime;
int samples_per_frame;
} codec2_prefs;
#ifdef LOG_DATA
static int c2_count = 0;
#endif
@ -80,15 +91,40 @@ static switch_status_t switch_codec2_init(switch_codec_t *codec, switch_codec_fl
if (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context)))) {
return SWITCH_STATUS_FALSE;
}
if (!codec2_prefs.mode) {
codec2_prefs.mode = CODEC2_MODE_2400;
}
if (codec2_prefs.mode == 3200) {
context->mode = CODEC2_MODE_3200;
} else if (codec2_prefs.mode == 2400) {
context->mode = CODEC2_MODE_2400;
} else if (codec2_prefs.mode == 1400) {
context->mode = CODEC2_MODE_1400;
} else if (codec2_prefs.mode == 1200) {
context->mode = CODEC2_MODE_1200;
} else {
/* 3200 might be better for VOIP, but forcing 2400 for backwards compatibility */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mode not supported, forcing CODEC2_MODE_2400. You can try mode 3200 too!\n");
context->mode = CODEC2_MODE_2400;
}
if (encoding) {
context->encoder = codec2_create(CODEC2_MODE_2400);
context->encoder = codec2_create(context->mode);
}
if (decoding) {
context->decoder = codec2_create(CODEC2_MODE_2400);
context->decoder = codec2_create(context->mode);
}
context->nsam = codec2_samples_per_frame(context->encoder);
if (!context->nsam) {
context->nsam = CODEC2_SAMPLES_PER_FRAME;
}
context->nbit = codec2_bits_per_frame(context->encoder);
context->nbyte = (context->nbit + 7) / 8;
codec->private_info = context;
#ifdef LOG_DATA
@ -136,7 +172,7 @@ static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_
{
struct codec2_context *context = codec->private_info;
codec2_assert(decoded_data_len == CODEC2_SAMPLES_PER_FRAME * 2);
codec2_assert(decoded_data_len == context->nsam * 2);
#ifdef LOG_DATA
fwrite(decoded_data, decoded_data_len, 1, context->encoder_in);
@ -148,11 +184,11 @@ static switch_status_t switch_codec2_encode(switch_codec_t *codec, switch_codec_
#ifdef LOG_DATA
fwrite(encode_buf, sizeof(encode_buf), 1, context->encoder_out_unpacked);
fflush(context->encoder_out_unpacked);
fwrite(encoded_data, 8, 1, context->encoder_out);
fwrite(encoded_data, context->nbyte, 1, context->encoder_out);
fflush(context->encoder_out);
#endif
*encoded_data_len = 6;
*encoded_data_len = context->nbyte;
return SWITCH_STATUS_SUCCESS;
}
@ -169,7 +205,7 @@ static switch_status_t switch_codec2_decode(switch_codec_t *codec,
{
struct codec2_context *context = codec->private_info;
codec2_assert(encoded_data_len == 8 /* aligned to 8 */);
codec2_assert(encoded_data_len == 8);
#ifdef LOG_DATA
fwrite(encoded_data, encoded_data_len, 1, context->decoder_in);
@ -181,11 +217,11 @@ static switch_status_t switch_codec2_decode(switch_codec_t *codec,
codec2_decode(context->decoder, decoded_data, encoded_data);
#ifdef LOG_DATA
fwrite(decoded_data, CODEC2_SAMPLES_PER_FRAME, 2, context->decoder_out);
fwrite(decoded_data, context->nsam, 2, context->decoder_out);
fflush(context->decoder_out);
#endif
*decoded_data_len = CODEC2_SAMPLES_PER_FRAME * 2; /* 160 samples */
*decoded_data_len = context->nsam * 2; /* eg: 160 samples for 3200,2400 */
return SWITCH_STATUS_SUCCESS;
}
@ -224,13 +260,58 @@ static switch_status_t switch_codec2_destroy(switch_codec_t *codec)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t codec2_load_config(switch_bool_t reload) {
char *cf = "codec2.conf";
switch_xml_t cfg, xml = NULL, param, settings;
switch_status_t status = SWITCH_STATUS_SUCCESS;
codec2_prefs.mode = 2400 ;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opening of %s failed\n", cf);
return status;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *key = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(key, "mode") && !zstr(val)) {
codec2_prefs.mode = atoi(val);
}
}
}
if (xml) {
switch_xml_free(xml);
}
return status;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load)
{
switch_codec_interface_t *codec_interface;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if ((status = codec2_load_config(SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) {
return status;
}
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
/*there is no API call to retrieve ptime per mode, so hardcoding here*/
if ((codec2_prefs.mode == 3200) ||(codec2_prefs.mode == 2400)) {
codec2_prefs.ptime = 20000;
codec2_prefs.samples_per_frame = CODEC2_SAMPLES_PER_FRAME;
} else {
codec2_prefs.ptime = 40000;
codec2_prefs.samples_per_frame = CODEC2_SAMPLES_PER_FRAME * 2;
}
SWITCH_ADD_CODEC(codec_interface, "CODEC2 2400bps");
SWITCH_ADD_CODEC(codec_interface, "CODEC2 3200/2400/1400/1200bps");
switch_core_codec_add_implementation(pool, codec_interface,
SWITCH_CODEC_TYPE_AUDIO,
@ -239,10 +320,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_codec2_load)
NULL,
8000, /* samples/sec */
8000, /* samples/sec */
2400, /* bps */
20000, /* ptime */
CODEC2_SAMPLES_PER_FRAME, /* samples decoded */
CODEC2_SAMPLES_PER_FRAME*2, /* bytes decoded */
codec2_prefs.mode, /* bps */
codec2_prefs.ptime, /* ptime */
codec2_prefs.samples_per_frame, /* samples decoded */
codec2_prefs.samples_per_frame * 2, /* bytes decoded */
0, /* bytes encoded */
1, /* channels */
1, /* frames/packet */

View File

@ -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) {

View File

@ -949,7 +949,7 @@ static switch_status_t opus_load_config(switch_bool_t reload)
opus_prefs.use_dtx = 0;
opus_prefs.plpct = 20;
opus_prefs.use_vbr = 0;
//opus_prefs.fec_decode = 1;
opus_prefs.fec_decode = 1;
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {

View File

@ -317,14 +317,14 @@ 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);
}
sane = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 4, 30);
sane = switch_calc_bitrate(1920, 1080, 2, 30);
if (context->bandwidth > sane) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_WARNING, "BITRATE TRUNCATED TO %d\n", sane);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_WARNING, "BITRATE TRUNCATED FROM %d TO %d\n", context->bandwidth, sane);
context->bandwidth = sane;
}

View File

@ -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;

View File

@ -2450,9 +2450,7 @@ static switch_status_t load_skinny_config(void)
skinny_profile_respawn(profile, 0);
/* Register profile */
switch_mutex_lock(globals.mutex);
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_mutex_unlock(globals.mutex);
profile = NULL;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
@ -2498,6 +2496,7 @@ static void skinny_user_to_device_event_handler(switch_event_t *event)
send_data(listener, message_type,
application_id, line_instance, call_id, transaction_id, data_length,
data);
break;
case USER_TO_DEVICE_DATA_VERSION1_MESSAGE:
data_length = strlen(data); /* we ignore data_length sent */
send_extended_data(listener, message_type,
@ -2724,12 +2723,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
return SWITCH_STATUS_TERM;
}
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
switch_mutex_lock(globals.mutex);
switch_core_hash_init(&globals.profile_hash);
globals.running = 1;
globals.auto_restart = SWITCH_TRUE;
switch_mutex_unlock(globals.mutex);
/* load_skinny_config does it's own locking */
load_skinny_config();
switch_mutex_lock(globals.mutex);
/* at least one profile */
if (switch_core_hash_empty( globals.profile_hash)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No profile found!\n");
@ -2793,7 +2798,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skinny_load)
skinny_api_register(module_interface);
/* launch listeners */
switch_mutex_lock(globals.mutex);
for (hi = switch_core_hash_first(globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
void *val;
skinny_profile_t *profile;

View File

@ -28,7 +28,7 @@
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Raymond Chandler <intralanman@freeswitch.org>
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
*
*
* mod_sofia.c -- SOFIA SIP Endpoint
@ -463,7 +463,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
switch_snprintf(reason, sizeof(reason), "%s", val);
} else {
if ((switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE)
&& switch_false(switch_channel_get_variable(channel, "ignore_completed_elsewhere"))) {
&& !switch_true(switch_channel_get_variable(channel, "ignore_completed_elsewhere"))) {
switch_snprintf(reason, sizeof(reason), "SIP;cause=200;text=\"Call completed elsewhere\"");
} else if (cause > 0 && cause < 128) {
switch_snprintf(reason, sizeof(reason), "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
@ -1877,14 +1877,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (!zstr(msg->string_arg)) {
if (!switch_channel_test_flag(channel, CF_ANSWERED) && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *dest = (char *) msg->string_arg;
char *mydest = (char *) msg->string_arg;
char *argv[MAX_REDIR] = { 0 };
char *mydata = NULL, *newdest = NULL;
int argc = 0, i;
switch_size_t len = 0;
switch_call_cause_t sip_redirect_cause = SWITCH_CAUSE_NORMAL_UNSPECIFIED;
char *dest = switch_core_session_strdup(session, mydest);
if ((argc = switch_separate_string(dest, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
const char *redirect_cause = argv[1];
sip_redirect_cause = switch_channel_str2cause(redirect_cause);
}
if (strchr(dest, ',')) {
mydata = switch_core_session_strdup(session, dest);
mydata = dest;
len = strlen(mydata) * 2;
newdest = switch_core_session_alloc(session, len);
@ -1936,7 +1943,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
tech_pvt->respond_phrase = "Moved Temporarily";
}
switch_channel_hangup(tech_pvt->channel, sofia_glue_sip_cause_to_freeswitch(tech_pvt->respond_code));
if (sip_redirect_cause == SWITCH_CAUSE_NONE) {
sip_redirect_cause = SWITCH_CAUSE_NORMAL_UNSPECIFIED;
}
switch_channel_hangup(tech_pvt->channel, sip_redirect_cause);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Too late for redirecting, already answered\n");
@ -2628,6 +2638,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
stream->write_function(stream, "%25s\t%32s\t%s\t%6.2f\t%u/%u\t%u/%u",
pkey, gp->register_to, sofia_state_names[gp->state], gp->ping_time,
gp->ib_failed_calls, gp->ib_calls, gp->ob_failed_calls, gp->ob_calls);
free(pkey);
if (gp->state == REG_STATE_FAILED || gp->state == REG_STATE_TRYING) {
time_t now = switch_epoch_time_now(NULL);
@ -4939,6 +4950,7 @@ static int notify_csta_callback(void *pArg, int argc, char **argv, char **column
switch_safe_free(route_uri);
sofia_glue_free_destination(dst);
free(extra_headers);
free(id);
free(contact);
@ -5197,6 +5209,7 @@ static void general_event_handler(switch_event_t *event)
const char *csta_event = switch_event_get_header(event, "Feature-Event");
char *ct = "application/x-as-feature-event+xml";
char *ct_m = NULL;
sofia_profile_t *profile;
@ -5248,7 +5261,8 @@ static void general_event_handler(switch_event_t *event)
stream.write_function(&stream, "--%s--\r\n", boundary_string);
ct = switch_mprintf("multipart/mixed; boundary=\"%s\"", boundary_string);
ct_m = switch_mprintf("multipart/mixed; boundary=\"%s\"", boundary_string);
ct = ct_m;
} else {
char *fwd_type = NULL;
@ -5285,6 +5299,7 @@ static void general_event_handler(switch_event_t *event)
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "missing something\n");
}
switch_safe_free(ct_m);
}
break;
case SWITCH_EVENT_SEND_MESSAGE:

View File

@ -3384,6 +3384,7 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
if (zstr(name) || switch_regex_match(name, "^[\\w\\.\\-\\_]+$") != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ignoring invalid name '%s'\n", name ? name : "NULL");
free(pkey);
goto skip;
}
@ -4813,7 +4814,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
} else if (!strcasecmp(var, "hold-music")) {
profile->hold_music = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "outbound-proxy")) {
profile->outbound_proxy = switch_core_strdup(profile->pool, val);
if (strncasecmp(val, "sip:", 4) && strncasecmp(val, "sips:", 5)) {
profile->outbound_proxy = switch_core_sprintf(profile->pool, "sip:%s", val);
} else {
profile->outbound_proxy = switch_core_strdup(profile->pool, val);
}
} else if (!strcasecmp(var, "rtcp-audio-interval-msec")) {
profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "rtcp-video-interval-msec")) {
@ -5472,6 +5477,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
}
if (sofia_test_flag(profile, TFLAG_INB_NOMEDIA) && !sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "inbound-bypass-media implictly enables inbound-late-negotiation\n");
sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
}
if (sofia_test_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE) && !sofia_test_pflag(profile, PFLAG_ALLOW_UPDATE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "send-display-update=true is set, but we can't comply because allow-update=false\n");
sofia_clear_pflag(profile, PFLAG_SEND_DISPLAY_UPDATE);
@ -8692,9 +8702,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
home = NULL;
}
if (etmp) {
switch_safe_free(etmp);
}
switch_safe_free(etmp);
}
@ -10421,6 +10429,8 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
switch_channel_set_variable(channel, "sip_geolocation", un->un_value);
} else if (!strcasecmp(un->un_name, "Geolocation-Error")) {
switch_channel_set_variable(channel, "sip_geolocation_error", un->un_value);
} else if (!strcasecmp(un->un_name, "userLocation")) {
switch_channel_set_variable(channel, "sip_user_location", un->un_value);
} else if (!strncasecmp(un->un_name, "X-", 2) || !strncasecmp(un->un_name, "P-", 2) || !strcasecmp(un->un_name, "User-to-User")) {
if (!zstr(un->un_value)) {
char new_name[512] = "";

View File

@ -1958,7 +1958,7 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
char *remote_user;
char *remote_host;
char *remote_uri;
char *local_user_param = "";
char *local_user_param = NULL;
char remote_display_buf[512];
char *buf_to_free = NULL;
int bInternal = 0;
@ -2091,13 +2091,14 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
data,
uuid, call_id, to_tag, from_tag, direction,
state,
local_user, local_user, local_host, local_user_param,
local_user, local_user, local_host, switch_str_nil(local_user_param),
local_user, local_host,
!strcasecmp(event_status, "hold") ? "no" : "yes",
remote_display_buf, remote_user, remote_host,
remote_uri
);
switch_core_hash_insert(h->hash, key, tmp);
switch_safe_free(local_user_param);
switch_safe_free(buf_to_free);
h->rowcount++;

View File

@ -51,6 +51,7 @@
#endif
#ifndef WIN32
#include <poll.h>
#define closesocket(x) close(x)
#endif
#include <switch_utils.h>
#include "mcast.h"
@ -67,7 +68,7 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
family = AF_INET6;
}
if ((!(flags & MCAST_SEND) && !(flags & MCAST_RECV)) || (handle->sock = (int)socket(family, SOCK_DGRAM, 0)) <= 0 ) {
if ((!(flags & MCAST_SEND) && !(flags & MCAST_RECV)) || (handle->sock = (mcast_socket_t)socket(family, SOCK_DGRAM, 0)) != mcast_sock_invalid ) {
return -1;
}
@ -84,7 +85,7 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
}
if ( setsockopt(handle->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)) != 0 ) {
close(handle->sock);
mcast_socket_close(handle);
return -1;
}
@ -101,14 +102,12 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(handle->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) < 0) {
close(handle->sock);
handle->sock = -1;
mcast_socket_close(handle);
return -1;
}
if (bind(handle->sock, (struct sockaddr *) &handle->recv_addr, sizeof(handle->recv_addr)) < 0) {
close(handle->sock);
handle->sock = -1;
mcast_socket_close(handle);
return -1;
}
@ -139,9 +138,7 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
setsockopt(handle->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&mreq, sizeof(mreq));
if (bind(handle->sock, (struct sockaddr *) &handle->recv_addr6, sizeof(handle->recv_addr6)) < 0) {
printf("FUCK (%s) %s\n", host, strerror(errno));
close(handle->sock);
handle->sock = -1;
mcast_socket_close(handle);
return -1;
}
}
@ -185,15 +182,15 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
void mcast_socket_close(mcast_handle_t *handle)
{
if (handle->sock > -1) {
close(handle->sock);
handle->sock = -1;
if (handle->sock != mcast_sock_invalid) {
closesocket(handle->sock);
handle->sock = mcast_sock_invalid;
}
}
ssize_t mcast_socket_send(mcast_handle_t *handle, void *data, size_t datalen)
{
if (handle->sock <= -1) {
if (handle->sock != mcast_sock_invalid) {
return -1;
}

View File

@ -69,8 +69,15 @@ extern "C" {
typedef WS_SSIZE_T ssize_t;
#endif
#ifndef WIN32
typedef int mcast_socket_t;
#else
typedef SOCKET mcast_socket_t;
#endif
#define mcast_sock_invalid (mcast_socket_t)-1
typedef struct {
int sock;
mcast_socket_t sock;
unsigned char ttl;
struct sockaddr_in send_addr;
struct sockaddr_in recv_addr;

View File

@ -65,7 +65,7 @@ char *McastHandle::recv(int ms)
return NULL;
}
int McastHandle::filenum(void)
mcast_socket_t McastHandle::filenum(void)
{
return handle.sock;
}

View File

@ -36,6 +36,7 @@
#ifdef __cplusplus
extern "C" {
#include "mcast.h"
#endif /* defined(__cplusplus) */
#if EMACS_WORKS
}
@ -49,7 +50,7 @@ class McastHandle {
virtual ~McastHandle();
int send(const char *data);
char *recv(int ms = 0);
int filenum(void);
mcast_socket_t filenum(void);
};
#ifdef __cplusplus

View File

@ -1889,7 +1889,7 @@ static void client_run(jsock_t *jsock)
if (s[0] != '#') goto nm;
switch_snprintf(repl, sizeof(repl), "#SPU %ld", (b - a) / 1000);
switch_snprintf(repl, sizeof(repl), "#SPU %ld", (long)((b - a) / 1000));
ws_write_frame(&jsock->ws, WSOC_TEXT, repl, strlen(repl));
loops = size / 1024;
rem = size % 1024;
@ -1906,7 +1906,7 @@ static void client_run(jsock_t *jsock)
ws_write_frame(&jsock->ws, WSOC_TEXT, repl, rem);
}
b = switch_time_now();
ddur += ((b - a) / 1000);
ddur += (int)((b - a) / 1000);
dur += ddur;
}

View File

@ -1,3 +1,4 @@
#include <switch.h>
#include "ws.h"
#include <pthread.h>

View File

@ -25,6 +25,17 @@
//#include "sha1.h"
#include <openssl/ssl.h>
#if defined(_MSC_VER) || defined(__APPLE__)
#define __bswap_64(x) \
x = (x>>56) | \
((x<<40) & 0x00FF000000000000) | \
((x<<24) & 0x0000FF0000000000) | \
((x<<8) & 0x000000FF00000000) | \
((x>>8) & 0x00000000FF000000) | \
((x>>24) & 0x0000000000FF0000) | \
((x>>40) & 0x000000000000FF00) | \
(x<<56)
#endif
#ifdef _MSC_VER
#ifndef strncasecmp
#define strncasecmp _strnicmp

View File

@ -178,6 +178,60 @@ switch_status_t mod_amqp_command_create(char *name, switch_xml_t cfg)
return SWITCH_STATUS_GENERR;
}
static void mod_amqp_command_response(mod_amqp_command_profile_t *profile, char *command, switch_stream_handle_t stream,
char *fs_resp_exchange, char *fs_resp_key, switch_status_t status)
{
char *json_output = NULL;
amqp_basic_properties_t props;
cJSON *message = NULL;
if (! profile->conn_active) {
/* No connection, so we can not send the message. */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] not active\n", profile->name);
return;
}
/* Construct the api response */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Preparing api command response: [%s]\n", (char *)stream.data);
message = cJSON_CreateObject();
cJSON_AddItemToObject(message, "output", cJSON_CreateString((const char *) stream.data));
cJSON_AddItemToObject(message, "command", cJSON_CreateString(command));
cJSON_AddItemToObject(message, "status", cJSON_CreateNumber((double) status));
json_output = cJSON_Print(message);
cJSON_Delete(message);
memset(&props, 0, sizeof(amqp_basic_properties_t));
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG;
props.content_type = amqp_cstring_bytes("text/json");
status = amqp_basic_publish(
profile->conn_active->state,
1,
amqp_cstring_bytes(fs_resp_exchange),
amqp_cstring_bytes(fs_resp_key),
0,
0,
&props,
amqp_cstring_bytes(json_output));
switch_safe_free(json_output);
if (status < 0) {
const char *errstr = amqp_error_string2(-status);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile[%s] failed to send event on connection[%s]: %s\n",
profile->name, profile->conn_active->name, errstr);
/* This is bad, we couldn't send the message. Clear up any connection */
mod_amqp_connection_close(profile->conn_active);
profile->conn_active = NULL;
return;
}
return;
}
void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void *data)
{
@ -286,6 +340,7 @@ void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void
COMMAND_FORMAT_UNKNOWN,
COMMAND_FORMAT_PLAINTEXT
} commandFormat = COMMAND_FORMAT_PLAINTEXT;
char *fs_resp_exchange = NULL, *fs_resp_key = NULL;
amqp_maybe_release_buffers(profile->conn_active->state);
@ -342,6 +397,24 @@ void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void
}
}
if (envelope.message.properties.headers.num_entries) {
int x = 0;
for ( x = 0; x < envelope.message.properties.headers.num_entries; x++) {
char *header_key = (char *)envelope.message.properties.headers.entries[x].key.bytes;
char *header_value = (char *)envelope.message.properties.headers.entries[x].value.value.bytes.bytes;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AMQP message custom header key[%s] value[%s]\n", header_key, header_value);
if ( !strncmp(header_key, "x-fs-api-resp-exchange", 22)) {
fs_resp_exchange = header_value;
} else if (!strncmp(header_key, "x-fs-api-resp-key", 17)) {
fs_resp_key = header_value;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring unrecognized event header [%s]\n", header_key);
}
}
}
if (commandFormat == COMMAND_FORMAT_PLAINTEXT) {
switch_stream_handle_t stream = { 0 }; /* Collects the command output */
@ -353,10 +426,15 @@ void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void
SWITCH_STANDARD_STREAM(stream);
if (switch_console_execute(command, 0, &stream) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Remote command failed:\n%s\n", (char *) stream.data);
if ( fs_resp_exchange && fs_resp_key ) {
switch_status_t status = switch_console_execute(command, 0, &stream);
mod_amqp_command_response(profile, command, stream, fs_resp_exchange, fs_resp_key, status);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote command succeeded:\n%s\n", (char *) stream.data);
if (switch_console_execute(command, 0, &stream) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Remote command failed:\n%s\n", (char *) stream.data);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote command succeeded:\n%s\n", (char *) stream.data);
}
}
switch_safe_free(stream.data);
}

View File

@ -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(

View File

@ -68,7 +68,7 @@
<start application="spandsp_start_tone_detect" data="1"/>
<stop application="spandsp_stop_tone_detect" data=""/>
<!-- map tone events to Rayo CPA signal type -->
<event class="CUSTOM" subclass="DETECTED_TONE" type-header="Detected-Tone">
<event class="DETECTED_TONE" type-header="Detected-Tone">
<signal-type header-value="SIT" value="sit"/>
<signal-type header-value="BUSY_TONE" value="busy"/>
<signal-type header-value="REORDER_TONE" value="congestion"/>

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -350,27 +350,37 @@ SWITCH_DECLARE(switch_channel_callstate_t) switch_channel_str2callstate(const ch
SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel, const char *file, const char *func, int line)
{
if (switch_channel_media_up(channel)) {
switch_core_session_message_t msg = { 0 };
msg.message_id = SWITCH_MESSAGE_INDICATE_AUDIO_SYNC;
msg.from = channel->name;
msg._file = file;
msg._func = func;
msg._line = line;
switch_core_session_receive_message(channel->session, &msg);
switch_core_session_message_t *msg = NULL;
msg = switch_core_session_alloc(channel->session, sizeof(*msg));
MESSAGE_STAMP_FFL(msg);
msg->message_id = SWITCH_MESSAGE_INDICATE_AUDIO_SYNC;
msg->from = channel->name;
msg->_file = file;
msg->_func = func;
msg->_line = line;
switch_core_session_queue_message(channel->session, msg);
}
}
SWITCH_DECLARE(void) switch_channel_perform_video_sync(switch_channel_t *channel, const char *file, const char *func, int line)
{
if (switch_channel_media_up(channel)) {
switch_core_session_message_t msg = { 0 };
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_SYNC;
msg.from = channel->name;
msg._file = file;
msg._func = func;
msg._line = line;
switch_core_session_receive_message(channel->session, &msg);
switch_core_session_message_t *msg = NULL;
msg = switch_core_session_alloc(channel->session, sizeof(*msg));
MESSAGE_STAMP_FFL(msg);
msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_SYNC;
msg->from = channel->name;
msg->_file = file;
msg->_func = func;
msg->_line = line;
switch_core_session_request_video_refresh(channel->session);
switch_core_session_queue_message(channel->session, msg);
}
}
@ -1858,11 +1868,8 @@ SWITCH_DECLARE(void) switch_channel_set_flag_value(switch_channel_t *channel, sw
switch_core_session_start_video_thread(channel->session);
}
if (flag == CF_VIDEO_DECODED_READ) {
if (flag == CF_VIDEO_DECODED_READ && channel->flags[CF_VIDEO]) {
switch_core_session_request_video_refresh(channel->session);
if (!switch_core_session_in_video_thread(channel->session)) {
switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
}
}
}
@ -1995,8 +2002,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;
}
@ -3799,13 +3807,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
}
if (switch_core_session_in_thread(channel->session)) {
if (switch_core_session_in_thread(channel->session) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
const char *delay;
if (switch_channel_test_flag(channel, CF_VIDEO)) {
switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
}
if ((delay = switch_channel_get_variable(channel, "answer_delay"))) {
uint32_t msec = atoi(delay);

View File

@ -69,7 +69,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
{
switch_io_event_hook_read_frame_t *ptr;
switch_status_t status = SWITCH_STATUS_FALSE;
int need_codec, perfect, do_bugs = 0, do_resample = 0, is_cng = 0, tap_only = 0;
int need_codec, perfect, bug_locked = 0, global_prune = 0, do_bugs = 0, do_resample = 0, is_cng = 0, tap_only = 0;
switch_codec_implementation_t codec_impl;
unsigned int flag = 0;
int i;
@ -183,12 +183,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
if (status == SWITCH_STATUS_INUSE) {
*frame = &runtime.dummy_cng_frame;
switch_yield(20000);
return SWITCH_STATUS_SUCCESS;
switch_goto_status(SWITCH_STATUS_SUCCESS, bail_out);
}
if (!SWITCH_READ_ACCEPTABLE(status) || !session->read_codec || !switch_core_codec_ready(session->read_codec)) {
*frame = NULL;
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, bail_out);
}
switch_mutex_lock(session->codec_read_mutex);
@ -198,7 +198,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s has no read codec.\n", switch_channel_get_name(session->channel));
switch_channel_hangup(session->channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
*frame = &runtime.dummy_cng_frame;
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, bail_out);
}
switch_mutex_lock(session->read_codec->mutex);
@ -232,13 +232,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
goto done;
}
if (!bug_locked) {
switch_thread_rwlock_rdlock(session->bug_rwlock);
if (session->bugs) {
bug_locked = 1;
} else {
switch_thread_rwlock_unlock(session->bug_rwlock);
}
}
if (session->bugs && !((*frame)->flags & SFF_CNG) && !((*frame)->flags & SFF_NOT_AUDIO)) {
switch_media_bug_t *bp;
switch_bool_t ok = SWITCH_TRUE;
int prune = 0;
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
ok = SWITCH_TRUE;
@ -275,10 +282,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
prune++;
}
}
switch_thread_rwlock_unlock(session->bug_rwlock);
if (prune) {
switch_core_media_bug_prune(session);
global_prune++;
}
}
@ -299,7 +305,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
int prune = 0;
if (session->bugs && switch_test_flag((*frame), SFF_CNG)) {
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
ok = SWITCH_TRUE;
@ -342,10 +347,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
prune++;
}
}
switch_thread_rwlock_unlock(session->bug_rwlock);
if (prune) {
switch_core_media_bug_prune(session);
global_prune++;
}
@ -438,12 +442,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
} else {
switch_codec_t *use_codec = read_frame->codec;
if (do_bugs) {
switch_thread_rwlock_wrlock(session->bug_rwlock);
if (!session->bugs) {
switch_thread_rwlock_unlock(session->bug_rwlock);
goto done;
}
if (!switch_core_codec_ready(&session->bug_codec) && switch_core_codec_ready(read_frame->codec)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting BUG Codec %s:%d\n",
read_frame->codec->implementation->iananame, read_frame->codec->implementation->ianacode);
@ -457,14 +455,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
if (switch_core_codec_ready(&session->bug_codec)) {
use_codec = &session->bug_codec;
}
switch_thread_rwlock_unlock(session->bug_rwlock);
switch_thread_rwlock_wrlock(session->bug_rwlock);
if (!session->bugs) {
do_bugs = 0;
}
switch_thread_rwlock_unlock(session->bug_rwlock);
if (!do_bugs) goto done;
}
if (!switch_test_flag(read_frame->codec, SWITCH_CODEC_FLAG_HAS_PLC) &&
@ -486,7 +476,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
codec = read_frame->codec;
}
switch_thread_rwlock_rdlock(session->bug_rwlock);
codec->cur_frame = read_frame;
session->read_codec->cur_frame = read_frame;
status = switch_core_codec_decode(codec,
@ -501,8 +490,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
session->raw_read_frame.channels = codec->implementation->number_of_channels;
codec->cur_frame = NULL;
session->read_codec->cur_frame = NULL;
switch_thread_rwlock_unlock(session->bug_rwlock);
}
if (status == SWITCH_STATUS_SUCCESS && session->read_impl.number_of_channels == 1) {
@ -636,7 +623,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_media_bug_t *bp;
switch_bool_t ok = SWITCH_TRUE;
int prune = 0;
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
ok = SWITCH_TRUE;
@ -677,9 +663,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
}
switch_thread_rwlock_unlock(session->bug_rwlock);
if (prune) {
switch_core_media_bug_prune(session);
global_prune++;
}
}
@ -687,7 +673,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_media_bug_t *bp;
switch_bool_t ok = SWITCH_TRUE;
int prune = 0;
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
ok = SWITCH_TRUE;
@ -738,9 +723,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
prune++;
}
}
switch_thread_rwlock_unlock(session->bug_rwlock);
if (prune) {
switch_core_media_bug_prune(session);
global_prune++;
}
}
@ -868,7 +853,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_media_bug_t *bp;
switch_bool_t ok = SWITCH_TRUE;
int prune = 0;
switch_thread_rwlock_rdlock(session->bug_rwlock);
for (bp = session->bugs; bp; bp = bp->next) {
ok = SWITCH_TRUE;
@ -907,9 +892,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
prune++;
}
}
switch_thread_rwlock_unlock(session->bug_rwlock);
if (prune) {
switch_core_media_bug_prune(session);
global_prune++;
}
}
}
@ -930,6 +915,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_channel_set_callstate(session->channel, CCS_ACTIVE);
}
bail_out:
if (bug_locked) {
switch_thread_rwlock_unlock(session->bug_rwlock);
}
if (global_prune) {
switch_core_media_bug_prune(session);
}
return status;
}

View File

@ -2120,6 +2120,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
return SWITCH_STATUS_FALSE;
}
if (switch_channel_test_flag(session->channel, CF_LEG_HOLDING)) {
return SWITCH_STATUS_INUSE;
}
if (smh->read_mutex[type] && switch_mutex_trylock(smh->read_mutex[type]) != SWITCH_STATUS_SUCCESS) {
/* return CNG, another thread is already reading */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s is already being read for %s\n",
@ -2135,9 +2139,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
while (smh->media_flags[SCMF_RUNNING] && engine->read_frame.datalen == 0) {
engine->read_frame.flags = SFF_NONE;
status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags);
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
if (status == SWITCH_STATUS_TIMEOUT) {
@ -2180,7 +2182,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
if (type == SWITCH_MEDIA_TYPE_VIDEO) {
switch_core_media_set_video_codec(session, 1);
} else {
if (switch_core_media_set_codec(session, 1, 0) != SWITCH_STATUS_SUCCESS) {
if (switch_core_media_set_codec(session, 1, smh->mparams->codec_flags) != SWITCH_STATUS_SUCCESS) {
*frame = NULL;
switch_goto_status(SWITCH_STATUS_GENERR, end);
}
@ -2777,6 +2779,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_
if (!force) {
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
}
if (strcasecmp(a_engine->read_impl.iananame, a_engine->cur_payload_map->iananame) ||
(uint32_t) a_engine->read_impl.microseconds_per_packet / 1000 != a_engine->cur_payload_map->codec_ms ||
a_engine->read_impl.samples_per_second != a_engine->cur_payload_map->rm_rate ) {
@ -2802,7 +2805,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_
"Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz\n",
a_engine->read_impl.iananame,
a_engine->read_impl.microseconds_per_packet / 1000,
a_engine->read_impl.samples_per_second,
a_engine->read_impl.actual_samples_per_second,
a_engine->cur_payload_map->iananame,
a_engine->cur_payload_map->codec_ms,
@ -2860,6 +2863,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_
a_engine->write_codec.session = session;
if (switch_rtp_ready(a_engine->rtp_session)) {
switch_channel_audio_sync(session->channel);
switch_rtp_reset_jb(a_engine->rtp_session);
}
switch_channel_set_variable(session->channel, "rtp_use_codec_name", a_engine->cur_payload_map->iananame);
switch_channel_set_variable(session->channel, "rtp_use_codec_fmtp", a_engine->cur_payload_map->rm_fmtp);
switch_channel_set_variable_printf(session->channel, "rtp_use_codec_rate", "%d", a_engine->cur_payload_map->rm_rate);
@ -4383,24 +4391,28 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt);
switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp);
if (switch_core_codec_ready(&a_engine->read_codec) &&
(strcasecmp(matches[0].imp->iananame, a_engine->read_codec.implementation->iananame) ||
matches[0].imp->microseconds_per_packet != a_engine->read_codec.implementation->microseconds_per_packet ||
matches[0].imp->samples_per_second != a_engine->read_codec.implementation->samples_per_second
)) {
if (a_engine->read_impl.iananame) {
if (!switch_core_codec_ready(&a_engine->read_codec) ||
((strcasecmp(matches[0].imp->iananame, a_engine->read_impl.iananame) ||
matches[0].imp->microseconds_per_packet != a_engine->read_impl.microseconds_per_packet ||
matches[0].imp->samples_per_second != a_engine->read_impl.samples_per_second
))) {
a_engine->reset_codec = 1;
}
if (switch_core_media_set_codec(session, 0, smh->mparams->codec_flags) == SWITCH_STATUS_SUCCESS) {
if (check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, m) == SWITCH_STATUS_FALSE) {
match = 0;
} else {
got_audio = 1;
a_engine->reset_codec = 1;
}
} else {
} else if (switch_core_media_set_codec(session, 0, smh->mparams->codec_flags) != SWITCH_STATUS_SUCCESS) {
match = 0;
}
if (match) {
if (check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, m) == SWITCH_STATUS_FALSE) {
match = 0;
got_audio = 0;
} else {
got_audio = 1;
}
}
}
for (map = m->m_rtpmaps; map; map = map->rm_next) {
@ -4521,6 +4533,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
case SWITCH_MEDIA_FLOW_RECVONLY:
switch_channel_set_variable(smh->session->channel, "video_media_flow", "sendonly");
v_engine->smode = SWITCH_MEDIA_FLOW_SENDONLY;
switch_channel_set_flag(smh->session->channel, CF_VIDEO_READY);
break;
case SWITCH_MEDIA_FLOW_SENDONLY:
switch_channel_set_variable(smh->session->channel, "video_media_flow", "recvonly");
@ -5053,7 +5066,8 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
continue;
}
if (!switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) && (++xloops > 20 || switch_channel_test_flag(channel, CF_VIDEO_PASSIVE))) {
if (!switch_channel_test_flag(channel, CF_VIDEO_READY) &&
switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) && (++xloops > 10 || switch_channel_test_flag(channel, CF_VIDEO_PASSIVE))) {
switch_channel_set_flag(channel, CF_VIDEO_READY);
}
@ -5095,12 +5109,8 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
}
}
if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
switch_channel_set_flag(channel, CF_VIDEO_READY);
}
//if (!smh->video_write_fh || !switch_channel_test_flag(channel, CF_VIDEO_READY)) {
status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
status = switch_core_session_read_video_frame(session, &read_frame, smh->video_write_fh ? SWITCH_IO_FLAG_NOBLOCK : SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
switch_cond_next();
@ -5129,10 +5139,6 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
switch_core_media_gen_key_frame(session);
}
if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
send_blank = 1;
}
if (switch_channel_test_flag(channel, CF_VIDEO_READY)) {
switch_mutex_lock(mh->file_mutex);
if (smh->video_write_fh && switch_channel_ready(session->channel) && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) {
@ -5149,7 +5155,7 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
send_blank = 0;
}
switch_mutex_unlock(mh->file_mutex);
} else if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) {
} else if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) || v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) {
send_blank = 1;
}
@ -7475,11 +7481,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) {
@ -8914,6 +8925,28 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_outgoing_bitrate(switch_co
return status;
}
//?
SWITCH_DECLARE(switch_status_t) switch_core_media_reset_jb(switch_core_session_t *session, switch_media_type_t type)
{
switch_media_handle_t *smh;
switch_rtp_engine_t *engine;
switch_assert(session);
if (!(smh = session->media_handle)) {
return SWITCH_STATUS_FALSE;
}
engine = &smh->engines[type];
if (switch_rtp_ready(engine->rtp_session)) {
switch_rtp_reset_jb(engine->rtp_session);
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
//?
SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
{
@ -8938,6 +8971,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
case SWITCH_MESSAGE_RESAMPLE_EVENT:
{
if (switch_rtp_ready(a_engine->rtp_session)) {
switch_channel_audio_sync(session->channel);
switch_rtp_reset_jb(a_engine->rtp_session);
}
if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
switch_channel_set_flag(session->channel, CF_CONFERENCE_RESET_MEDIA);
}
@ -9206,12 +9244,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC:
if (switch_rtp_ready(a_engine->rtp_session)) {
rtp_flush_read_buffer(a_engine->rtp_session, SWITCH_RTP_FLUSH_ONCE);
//switch_rtp_reset_jb(a_engine->rtp_session);
}
goto end;
case SWITCH_MESSAGE_INDICATE_VIDEO_SYNC:
if (switch_rtp_ready(v_engine->rtp_session)) {
switch_rtp_flush(v_engine->rtp_session);
//switch_rtp_reset_jb(v_engine->rtp_session);
}
goto end;
case SWITCH_MESSAGE_INDICATE_3P_MEDIA:
@ -10958,9 +10998,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
(*frame)->img->w, (*frame)->img->h, (*frame)->img->d_w, (*frame)->img->d_h);
}
if ((*frame)->img && (*frame)->img->d_w && (*frame)->img->d_h && ++smh->ready_loops > 5) {
switch_channel_set_flag(session->channel, CF_VIDEO_READY);
if ((*frame)->img && (*frame)->img->d_w && (*frame)->img->d_h) {
smh->vid_params.width = (*frame)->img->d_w;
smh->vid_params.height = (*frame)->img->d_h;
}
@ -10978,6 +11016,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
if (decode_status == SWITCH_STATUS_MORE_DATA || !(*frame)->img) {
goto top;
}
}
if (!switch_channel_test_flag(session->channel, CF_VIDEO_READY) && *frame) {
if (((switch_channel_test_flag(session->channel, CF_VIDEO_DECODED_READ) && (*frame)->img) || (*frame)->m) && ++smh->ready_loops > 5) {
switch_channel_set_flag(session->channel, CF_VIDEO_READY);
}
}

View File

@ -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,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *
return SWITCH_STATUS_SUCCESS;
}
if (dmachine->pinging) {
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 +586,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;
@ -608,6 +617,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;
}

View File

@ -694,7 +694,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
continue;
}
if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD)) {
if (status != SWITCH_STATUS_BREAK && !switch_channel_test_flag(chan_a, CF_HOLD) && !switch_channel_test_flag(chan_b, CF_LEG_HOLDING)) {
if (switch_core_session_write_frame(session_b, read_frame, SWITCH_IO_FLAG_NONE, stream_id) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG,
"%s ending bridge by request from write function\n", switch_channel_get_name(chan_b));
@ -1698,6 +1698,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;
@ -1718,16 +1720,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);
}

View File

@ -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]);
}

View File

@ -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'};

View File

@ -1088,6 +1088,11 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
uint32_t i;
uint16_t want = ntohs(jb->next_seq), got = ntohs(packet->header.seq);
if (len >= sizeof(switch_rtp_packet_t)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "trying to put %" SWITCH_SIZE_T_FMT " bytes exceeding buffer, truncate to %" SWITCH_SIZE_T_FMT "\n", len, sizeof(switch_rtp_packet_t));
len = sizeof(switch_rtp_packet_t);
}
switch_mutex_lock(jb->mutex);
if (!want) want = got;

View File

@ -2740,6 +2740,15 @@ SWITCH_DECLARE(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session
rtp_session->max_missed_packets = max;
}
SWITCH_DECLARE(void) switch_rtp_reset_jb(switch_rtp_t *rtp_session)
{
if (switch_rtp_ready(rtp_session)) {
if (rtp_session->jb) {
switch_jb_reset(rtp_session->jb);
}
}
}
SWITCH_DECLARE(void) switch_rtp_reset_vb(switch_rtp_t *rtp_session)
{
if (rtp_session->vb) {
@ -2888,6 +2897,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_
switch_mutex_lock(rtp_session->write_mutex);
rtp_session->remote_addr = remote_addr;
switch_cp_addr(rtp_session->rtp_from_addr, rtp_session->remote_addr);
if (change_adv_addr) {
rtp_session->remote_host_str = switch_core_strdup(rtp_session->pool, host);
@ -3259,7 +3269,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
const char *kind = "";
BIO *bio;
DH *dh;
#ifndef OPENSSL_NO_EC
EC_KEY* ecdh;
#endif
#ifndef HAVE_OPENSSL_DTLS_SRTP
return SWITCH_STATUS_FALSE;
@ -3367,6 +3379,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
SSL_set_read_ahead(dtls->ssl, 1);
//SSL_set_verify(dtls->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), cb_verify_peer);
#ifndef OPENSSL_NO_EC
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
if (!ecdh) {
return SWITCH_STATUS_FALSE;
@ -3374,6 +3387,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
SSL_set_options(dtls->ssl, SSL_OP_SINGLE_ECDH_USE);
SSL_set_tmp_ecdh(dtls->ssl, ecdh);
EC_KEY_free(ecdh);
#endif
SSL_set_verify(dtls->ssl, SSL_VERIFY_NONE, NULL);
SSL_set_app_data(dtls->ssl, dtls);
@ -6724,6 +6738,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
case RESULT_GOTO_TIMERCHECK:
goto timer_check;
case RESULT_CONTINUE:
status = SWITCH_STATUS_SUCCESS;
goto result_continue;
}

View File

@ -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,27 +591,14 @@ 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);
if (tmp) {
r = strcpy(tmp, r);
} else {
if (r)
free(r);
return NULL;
}
char *tmp = (char *) switch_must_malloc(l);
r = strcpy(tmp, r);
} else {
char *tmp = (char *) realloc(r, l);
if (tmp) {
r = tmp;
} else {
if (r)
free(r);
return NULL;
}
r = (char *) switch_must_realloc(r, l);
}
}
e = strchr((s = r + d), ';'); /* fix up pointers */
@ -618,7 +616,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++;
@ -672,19 +670,11 @@ static void switch_xml_char_content(switch_xml_root_t root, char *s, switch_size
xml->txt = s; /* initial character content */
else { /* allocate our own memory and make a copy */
if ((xml->flags & SWITCH_XML_TXTM)) { /* allocate some space */
char *tmp = (char *) realloc(xml->txt, (l = strlen(xml->txt)) + len);
if (tmp) {
xml->txt = tmp;
} else {
return;
}
xml->txt = (char *) switch_must_realloc(xml->txt, (l = strlen(xml->txt)) + len);
} else {
char *tmp = (char *) malloc((l = strlen(xml->txt)) + len);
if (tmp) {
xml->txt = strcpy(tmp, xml->txt);
} else {
return;
}
char *tmp = (char *) switch_must_malloc((l = strlen(xml->txt)) + len);
xml->txt = strcpy(tmp, xml->txt);
}
strcpy(xml->txt + l, s); /* add new char content */
if (s != m)
@ -748,38 +738,29 @@ static void switch_xml_proc_inst(switch_xml_root_t root, char *s, switch_size_t
}
if (!root->pi || !root->pi[0]) {
root->pi = (char ***) malloc(sizeof(char **));
if (!root->pi)
return;
root->pi = (char ***) switch_must_malloc(sizeof(char **));
*(root->pi) = NULL; /* first pi */
}
while (root->pi[i] && strcmp(target, root->pi[i][0]))
i++; /* find target */
if (!root->pi[i]) { /* new target */
char ***ssstmp = (char ***) realloc(root->pi, sizeof(char **) * (i + 2));
if (!ssstmp)
return;
char ***ssstmp = (char ***) switch_must_realloc(root->pi, sizeof(char **) * (i + 2));
root->pi = ssstmp;
if (!root->pi)
return;
root->pi[i] = (char **) malloc(sizeof(char *) * 3);
if (!root->pi[i])
return;
root->pi[i] = (char **) switch_must_malloc(sizeof(char *) * 3);
root->pi[i][0] = target;
root->pi[i][1] = (char *) (root->pi[i + 1] = NULL); /* terminate pi list */
root->pi[i][2] = strdup(""); /* empty document position list */
root->pi[i][2] = switch_must_strdup(""); /* empty document position list */
}
while (root->pi[i][j])
j++; /* find end of instruction list for this target */
sstmp = (char **) realloc(root->pi[i], sizeof(char *) * (j + 3));
if (!sstmp)
return;
sstmp = (char **) switch_must_realloc(root->pi[i], sizeof(char *) * (j + 3));
root->pi[i] = sstmp;
stmp = (char *) realloc(root->pi[i][j + 1], j + 1);
if (!stmp)
return;
stmp = (char *) switch_must_realloc(root->pi[i][j + 1], j + 1);
root->pi[i][j + 2] = stmp;
strcpy(root->pi[i][j + 2] + j - 1, (root->xml.name) ? ">" : "<");
root->pi[i][j + 1] = NULL; /* null terminate pi list for this target */
@ -793,7 +774,7 @@ static short switch_xml_internal_dtd(switch_xml_root_t root, char *s, switch_siz
int i, j;
char **sstmp;
pe = (char **) memcpy(malloc(sizeof(SWITCH_XML_NIL)), SWITCH_XML_NIL, sizeof(SWITCH_XML_NIL));
pe = (char **) memcpy(switch_must_malloc(sizeof(SWITCH_XML_NIL)), SWITCH_XML_NIL, sizeof(SWITCH_XML_NIL));
for (s[len] = '\0'; s;) {
while (*s && *s != '<' && *s != '%')
@ -813,11 +794,7 @@ static short switch_xml_internal_dtd(switch_xml_root_t root, char *s, switch_siz
}
for (i = 0, ent = (*c == '%') ? pe : root->ent; ent[i]; i++);
sstmp = (char **) realloc(ent, (i + 3) * sizeof(char *)); /* space for next ent */
if (!sstmp) {
switch_xml_err(root, v, "Allocation Error!");
break;
}
sstmp = (char **) switch_must_realloc(ent, (i + 3) * sizeof(char *)); /* space for next ent */
ent = sstmp;
if (*c == '%')
pe = ent;
@ -889,20 +866,15 @@ static short switch_xml_internal_dtd(switch_xml_root_t root, char *s, switch_siz
}
if (!root->attr[i]) { /* new tag name */
root->attr = (!i) ? (char ***) malloc(2 * sizeof(char **))
: (char ***) realloc(root->attr, (i + 2) * sizeof(char **));
root->attr[i] = (char **) malloc(2 * sizeof(char *));
root->attr = (!i) ? (char ***) switch_must_malloc(2 * sizeof(char **))
: (char ***) switch_must_realloc(root->attr, (i + 2) * sizeof(char **));
root->attr[i] = (char **) switch_must_malloc(2 * sizeof(char *));
root->attr[i][0] = t; /* set tag name */
root->attr[i][1] = (char *) (root->attr[i + 1] = NULL);
}
for (j = 1; root->attr[i][j]; j += 3); /* find end of list */
sstmp = (char **) realloc(root->attr[i], (j + 4) * sizeof(char *));
if (!sstmp) {
switch_xml_err(root, t, "Allocation Error!");
break;
}
sstmp = (char **) switch_must_realloc(root->attr[i], (j + 4) * sizeof(char *));
root->attr[i] = sstmp;
root->attr[i][j + 3] = NULL; /* null terminate list */
@ -937,7 +909,7 @@ static char *switch_xml_str2utf8(char **s, switch_size_t *len)
if (be == -1)
return NULL; /* not UTF-16 */
u = (char *) malloc(max);
u = (char *) switch_must_malloc(max);
for (sl = 2; sl < *len - 1; sl += 2) {
c = (be) ? (((*s)[sl] & 0xFF) << 8) | ((*s)[sl + 1] & 0xFF) /* UTF-16BE */
: (((*s)[sl + 1] & 0xFF) << 8) | ((*s)[sl] & 0xFF); /* UTF-16LE */
@ -949,9 +921,7 @@ static char *switch_xml_str2utf8(char **s, switch_size_t *len)
while (l + 6 > max) {
char *tmp;
tmp = (char *) realloc(u, max += SWITCH_XML_BUFSIZE);
if (!tmp)
return NULL;
tmp = (char *) switch_must_realloc(u, max += SWITCH_XML_BUFSIZE);
u = tmp;
}
if (c < 0x80)
@ -965,7 +935,7 @@ static char *switch_xml_str2utf8(char **s, switch_size_t *len)
u[l++] = (char) (0x80 | ((c >> (6 * --b)) & 0x3F)); /* payload */
}
}
return *s = (char *) realloc(u, *len = l);
return *s = (char *) switch_must_realloc(u, *len = l);
}
/* frees a tag attribute list */
@ -995,7 +965,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_str_dynamic(char *s, switch_bool_t
char *data;
switch_assert(s);
data = dup ? strdup(s) : s;
data = dup ? switch_must_strdup(s) : s;
if ((root = (switch_xml_root_t) switch_xml_parse_str(data, strlen(data)))) {
root->dynamic = 1; /* Make sure we free the memory is switch_xml_free() */
@ -1045,10 +1015,10 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_str(char *s, switch_size_t len)
for (i = 0; (a = root->attr[i]) && strcmp(a[0], d); i++);
for (l = 0; *s && *s != '/' && *s != '>'; l += 2) { /* new attrib */
attr = (l) ? (char **) realloc(attr, (l + 4) * sizeof(char *))
: (char **) malloc(4 * sizeof(char *)); /* allocate space */
attr[l + 3] = (l) ? (char *) realloc(attr[l + 1], (l / 2) + 2)
: (char *) malloc(2); /* mem for list of maloced vals */
attr = (l) ? (char **) switch_must_realloc(attr, (l + 4) * sizeof(char *))
: (char **) switch_must_malloc(4 * sizeof(char *)); /* allocate space */
attr[l + 3] = (l) ? (char *) switch_must_realloc(attr[l + 1], (l / 2) + 2)
: (char *) switch_must_malloc(2); /* mem for list of maloced vals */
strcpy(attr[l + 3] + (l / 2), " "); /* value is not malloced */
attr[l + 2] = NULL; /* null terminate list */
attr[l + 1] = (char *) ""; /* temporary attribute value */
@ -1165,17 +1135,12 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_fp(FILE * fp)
switch_size_t l, len = 0;
char *s;
if (!(s = (char *) malloc(SWITCH_XML_BUFSIZE)))
return NULL;
s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
do {
len += (l = fread((s + len), 1, SWITCH_XML_BUFSIZE, fp));
if (l == SWITCH_XML_BUFSIZE) {
char *tmp = s;
s = (char *) realloc(s, len + SWITCH_XML_BUFSIZE);
if (!s) {
free(tmp);
return NULL;
}
s = (char *) switch_must_realloc(s, len + SWITCH_XML_BUFSIZE);
}
} while (s && l == SWITCH_XML_BUFSIZE);
@ -1204,9 +1169,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_fd(int fd)
return NULL;
}
m = malloc(st.st_size);
if (!m)
return NULL;
m = switch_must_malloc(st.st_size);
if (!(0<(l = read(fd, m, st.st_size)))
|| !(root = (switch_xml_root_t) switch_xml_parse_str((char *) m, l))) {
free(m);
@ -1346,8 +1310,8 @@ static FILE *preprocess_glob(const char *cwd, const char *pattern, FILE *write_f
}
for (n = 0; n < glob_data.gl_pathc; ++n) {
dir_path = strdup(glob_data.gl_pathv[n]);
switch_assert(dir_path);
dir_path = switch_must_strdup(glob_data.gl_pathv[n]);
if ((e = strrchr(dir_path, *SWITCH_PATH_SEPARATOR))) {
*e = '\0';
}
@ -1400,12 +1364,12 @@ static int preprocess(const char *cwd, const char *file, FILE *write_fd, int rle
}
eblen = len * 2;
ebuf = malloc(eblen);
ebuf = switch_must_malloc(eblen);
memset(ebuf, 0, eblen);
while (!(bp = expand_vars(buf, ebuf, eblen, &cur, &err))) {
eblen *= 2;
ebuf = realloc(ebuf, eblen);
ebuf = switch_must_realloc(ebuf, eblen);
memset(ebuf, 0, eblen);
}
@ -1595,8 +1559,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file_simple(const char *file)
if ((fd = open(file, O_RDONLY, 0)) > -1) {
fstat(fd, &st);
if (!st.st_size) goto error;
m = malloc(st.st_size);
switch_assert(m);
m = switch_must_malloc(st.st_size);
if (!(0<(l = read(fd, m, st.st_size)))) goto error;
if (!(root = (switch_xml_root_t) switch_xml_parse_str((char *) m, l))) goto error;
root->dynamic = 1;
@ -2051,7 +2015,7 @@ static void switch_xml_user_cache(const char *key, const char *user_name, const
switch_safe_free(expires_lookup);
}
if (expires) {
char *expires_val = malloc(1024);
char *expires_val = switch_must_malloc(1024);
if (sprintf(expires_val, "%ld", (long)expires)) {
switch_core_hash_insert(CACHE_EXPIRES_HASH, mega_key, expires_val);
} else {
@ -2072,7 +2036,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user_merged(const char *key, c
int i, nkeys;
if (strchr(key, ':')) {
kdup = strdup(key);
kdup = switch_must_strdup(key);
nkeys = switch_split(kdup, ':', keys);
} else {
keys[0] = (char *)key;
@ -2445,10 +2409,7 @@ static char *switch_xml_ampencode(const char *s, switch_size_t len, char **dst,
while (s != e) {
while (*dlen + 10 > *max) {
char *tmp = (char *) realloc(*dst, *max += SWITCH_XML_BUFSIZE);
if (!tmp)
return *dst;
*dst = tmp;
*dst = (char *) switch_must_realloc(*dst, *max += SWITCH_XML_BUFSIZE);
}
if (immune) {
@ -2563,10 +2524,7 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len,
*s = switch_xml_ampencode(txt + start, xml->off - start, s, len, max, 0);
while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT) * (*count)) + 1 > *max) { /* reallocate s */
char *tmp = *s;
*s = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE);
if (!*s)
return tmp;
*s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
}
if (*len && *(*s + (*len) - 1) == '>') {
@ -2581,10 +2539,7 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len,
if (switch_xml_attr(xml, xml->attr[i]) != xml->attr[i + 1])
continue;
while (*len + strlen(xml->attr[i]) + 7 + (strlen(XML_INDENT) * (*count)) > *max) { /* reallocate s */
char *tmp = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE);
if (!tmp)
return *s;
*s = tmp;
*s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
}
*len += sprintf(*s + *len, " %s=\"", xml->attr[i]);
@ -2597,10 +2552,7 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len,
if (!attr[i][j + 1] || switch_xml_attr(xml, attr[i][j]) != attr[i][j + 1])
continue; /* skip duplicates and non-values */
while (*len + strlen(attr[i][j]) + 8 + (strlen(XML_INDENT) * (*count)) > *max) { /* reallocate s */
char *tmp = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE);
if (!tmp)
return *s;
*s = tmp;
*s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
}
*len += sprintf(*s + *len, " %s=\"", attr[i][j]);
@ -2619,10 +2571,7 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len,
}
while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT) * (*count)) > *max) { /* reallocate s */
char *tmp = *s;
*s = (char *) realloc(*s, *max += SWITCH_XML_BUFSIZE);
if (!*s)
return tmp;
*s = (char *) switch_must_realloc(*s, *max += SWITCH_XML_BUFSIZE);
}
if (xml->child || xml->txt) {
@ -2653,8 +2602,8 @@ static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len,
SWITCH_DECLARE(char *) switch_xml_toxml_nolock(switch_xml_t xml, switch_bool_t prn_header)
{
char *s = (char *) malloc(SWITCH_XML_BUFSIZE);
switch_assert(s);
char *s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
return switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE, 0, prn_header);
}
@ -2663,8 +2612,7 @@ SWITCH_DECLARE(char *) switch_xml_toxml(switch_xml_t xml, switch_bool_t prn_head
{
char *r, *s;
s = (char *) malloc(SWITCH_XML_BUFSIZE);
switch_assert(s);
s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
r = switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE, 0, prn_header);
@ -2676,10 +2624,10 @@ SWITCH_DECLARE(char *) switch_xml_tohtml(switch_xml_t xml, switch_bool_t prn_hea
char *r, *s, *h;
switch_size_t rlen = 0;
switch_size_t len = SWITCH_XML_BUFSIZE;
s = (char *) malloc(SWITCH_XML_BUFSIZE);
switch_assert(s);
h = (char *) malloc(SWITCH_XML_BUFSIZE);
switch_assert(h);
s = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
h = (char *) switch_must_malloc(SWITCH_XML_BUFSIZE);
r = switch_xml_toxml_buf(xml, s, SWITCH_XML_BUFSIZE, 0, prn_header);
h = switch_xml_ampencode(r, 0, &h, &rlen, &len, 1);
switch_safe_free(r);
@ -2693,7 +2641,7 @@ SWITCH_DECLARE(char *) switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_
switch_xml_t p = (xml) ? xml->parent : NULL;
switch_xml_root_t root = (switch_xml_root_t) xml;
switch_size_t len = 0, max = buflen;
char *s, *t, *n, *r;
char *s, *t, *n;
int i, j, k;
uint32_t count = 0;
@ -2706,10 +2654,7 @@ SWITCH_DECLARE(char *) switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_
}
if (!xml || !xml->name) {
if (!(r = (char *) realloc(s, len + 1))) {
abort();
}
return r;
return (char *) switch_must_realloc(s, len + 1);
}
while (root->xml.parent) {
@ -2723,10 +2668,7 @@ SWITCH_DECLARE(char *) switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_
continue; /* not pre-root */
}
while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) {
if (!(r = (char *) realloc(s, max += SWITCH_XML_BUFSIZE))) {
abort();
}
s = r;
s = (char *) switch_must_realloc(s, max += SWITCH_XML_BUFSIZE);
}
len += sprintf(s + len, "<?%s%s%s?>", t, *n ? " " : "", n);
}
@ -2741,20 +2683,13 @@ SWITCH_DECLARE(char *) switch_xml_toxml_buf(switch_xml_t xml, char *buf, switch_
continue; /* not post-root */
}
while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) {
if (!(r = (char *) realloc(s, max += SWITCH_XML_BUFSIZE))) {
abort();
}
s = r;
s = (char *) switch_must_realloc(s, max += SWITCH_XML_BUFSIZE);
}
len += sprintf(s + len, "\n<?%s%s%s?>", t, *n ? " " : "", n);
}
}
if (!(r = (char *) realloc(s, len + 1))) {
abort();
}
return r;
return (char *) switch_must_realloc(s, len + 1);
}
/* free the memory allocated for the switch_xml structure */
@ -2856,14 +2791,13 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_new(const char *name)
static const char *ent[] = { "lt;", "&#60;", "gt;", "&#62;", "quot;", "&#34;",
"apos;", "&#39;", "amp;", "&#38;", NULL
};
switch_xml_root_t root = (switch_xml_root_t) malloc(sizeof(struct switch_xml_root));
if (!root)
return NULL;
switch_xml_root_t root = (switch_xml_root_t) switch_must_malloc(sizeof(struct switch_xml_root));
memset(root, '\0', sizeof(struct switch_xml_root));
root->xml.name = (char *) name;
root->cur = &root->xml;
strcpy(root->err, root->xml.txt = (char *) "");
root->ent = (char **) memcpy(malloc(sizeof(ent)), ent, sizeof(ent));
root->ent = (char **) memcpy(switch_must_malloc(sizeof(ent)), ent, sizeof(ent));
root->attr = root->pi = (char ***) (root->xml.attr = SWITCH_XML_NIL);
return &root->xml;
}
@ -2916,8 +2850,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_add_child(switch_xml_t xml, const char *
if (!xml)
return NULL;
if (!(child = (switch_xml_t) malloc(sizeof(struct switch_xml))))
return NULL;
child = (switch_xml_t) switch_must_malloc(sizeof(struct switch_xml));
memset(child, '\0', sizeof(struct switch_xml));
child->name = (char *) name;
child->attr = SWITCH_XML_NIL;
@ -2954,20 +2888,15 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_set_attr(switch_xml_t xml, const char *n
if (!value)
return xml; /* nothing to do */
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 */
xml->attr = (char **) switch_must_malloc(4 * sizeof(char *));
xml->attr[1] = switch_must_strdup(""); /* empty list of malloced names/vals */
} else {
char **tmp = (char **) realloc(xml->attr, (l + 4) * sizeof(char *));
if (!tmp)
return xml;
xml->attr = tmp;
xml->attr = (char **) switch_must_realloc(xml->attr, (l + 4) * sizeof(char *));
}
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);
xml->attr[l + 3] = (char *) switch_must_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 */
if (xml->flags & SWITCH_XML_DUP)
xml->attr[l + 3][c] = SWITCH_XML_NAMEM;
@ -2985,14 +2914,10 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_set_attr(switch_xml_t xml, const char *n
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;
xml->attr = (char **) switch_must_realloc(xml->attr, (c + 2) * sizeof(char *));
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 */
}
xml->flags &= ~SWITCH_XML_DUP; /* clear strdup() flag */
@ -3636,14 +3561,7 @@ static int globextend(const char *path, glob_t *pglob, size_t *limit)
}
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ? realloc((char *) pglob->gl_pathv, newsize) : malloc(newsize);
if (pathv == NULL) {
if (pglob->gl_pathv) {
free(pglob->gl_pathv);
pglob->gl_pathv = NULL;
}
return (GLOB_NOSPACE);
}
pathv = pglob->gl_pathv ? switch_must_realloc((char *) pglob->gl_pathv, newsize) : switch_must_malloc(newsize);
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
/* first time around -- clear initial gl_offs items */
@ -3656,10 +3574,9 @@ static int globextend(const char *path, glob_t *pglob, size_t *limit)
for (p = path; *p++;)
continue;
len = (size_t) (p - path);
if ((copy = malloc(len)) != NULL) {
memcpy(copy, path, len);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
}
copy = switch_must_malloc(len);
memcpy(copy, path, len);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
return (copy == NULL ? GLOB_NOSPACE : 0);
}

View File

@ -17,6 +17,9 @@
Arguments=" -service "/>
<ServiceControl Id="StartService" Stop="both" Remove="uninstall" Name="FreeSWITCH" Wait="no" />
</Component>
<Component Id="cmp5A06A4A7E1884331BC6C949456B5F293" Guid="*">
<File Id="filD71F29178BC541A58D2E1A110EF3503D" Name="fs_cli.exe" Source="$(var.FreeSwitchConsole.TargetDir)\fs_cli.exe" KeyPath="yes"/>
</Component>
</DirectoryRef>
</Fragment>
<Fragment>

View File

@ -72,7 +72,9 @@
<!-- <ComponentRef Id="ProductComponent" /> -->
<!-- The following Ref pulls in FreeSWITCHconsole.wxs items -->
<ComponentRef Id="cmpBEF12B96A80D45AC32F3B692E94A57C9"/>
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<!-- This following Ref Pulls in fs_cli.exe-->
<ComponentRef Id="cmp5A06A4A7E1884331BC6C949456B5F293"/>
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="FreeSWITCHBaseFiles" />
<?if $(var.Platform) != x64 ?>
<MergeRef Id="CrtFiles_x86"/>

View File

@ -10,16 +10,16 @@
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\x86\Debug\</OutputPath>
<OutputPath>bin\Win32\Debug\</OutputPath>
<IntermediateOutputPath>obj\X86\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;FreeSWITCHConfFilesDir=$(ProjectDir)..\..\conf\vanilla;FreeSWITCHSoundFilesDir=$(ProjectDir)..\..\Win32\debug\sounds;FreeSWITCHBaseDir=$(SolutionDir)$(Platform)\$(Configuration);</DefineConstants>
<DefineConstants>Debug;FreeSWITCHConfFilesDir=$(ProjectDir)..\..\conf\vanilla;FreeSWITCHSoundFilesDir=$(ProjectDir)..\..\Win32\debug\sounds;FreeSWITCHBaseDir=$(SolutionDir)Win32\$(Configuration);PlatformDir=Win32;</DefineConstants>
<WixVariables>
</WixVariables>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\x86\release\</OutputPath>
<IntermediateOutputPath>obj\X86\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug;FreeSWITCHConfFilesDir=$(ProjectDir)..\..\conf\vanilla;FreeSWITCHSoundFilesDir=$(ProjectDir)..\..\Win32\release\sounds;FreeSWITCHBaseDir=$(SolutionDir)$(Platform)\$(Configuration);</DefineConstants>
<DefineConstants>Debug;FreeSWITCHConfFilesDir=$(ProjectDir)..\..\conf\vanilla;FreeSWITCHSoundFilesDir=$(ProjectDir)..\..\Win32\release\sounds;FreeSWITCHBaseDir=$(SolutionDir)Win32\$(Configuration);</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<OutputPath>bin\x64\Debug\</OutputPath>
@ -50,6 +50,358 @@
<Folder Include="Fragments" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\libs\esl\fs_cli.2015.vcxproj">
<Name>fs_cli</Name>
<Project>{d2fb8043-d208-4aee-8f18-3b5857c871b9}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_commands\mod_commands.2015.vcxproj">
<Name>mod_commands</Name>
<Project>{30a5b29c-983e-4580-9fd0-d647ccdcc7eb}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_conference\mod_conference.2015.vcxproj">
<Name>mod_conference</Name>
<Project>{c24fb505-05d7-4319-8485-7540b44c8603}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_curl\mod_curl.2015.vcxproj">
<Name>mod_curl</Name>
<Project>{ef300386-a8df-4372-b6d8-fb9bffca9aed}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_db\mod_db.2015.vcxproj">
<Name>mod_db</Name>
<Project>{f6a33240-8f29-48bd-98f0-826995911799}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_directory\mod_directory.2015.vcxproj">
<Name>mod_directory</Name>
<Project>{b889a18e-70a7-44b5-b2c9-47798d4f43b3}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_dptools\mod_dptools.2015.vcxproj">
<Name>mod_dptools</Name>
<Project>{b5881a85-fe70-4f64-8607-2caae52669c6}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_enum\mod_enum.2015.vcxproj">
<Name>mod_enum</Name>
<Project>{71a967d5-0e99-4cef-a587-98836ee6f2ef}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_fifo\mod_fifo.2015.vcxproj">
<Name>mod_fifo</Name>
<Project>{75df7f29-2fbf-47f7-b5af-5b4952dc1abd}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_hash\mod_hash.2015.vcxproj">
<Name>mod_hash</Name>
<Project>{2e250296-0c08-4342-9c8a-bcbdd0e7df65}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_httapi\mod_httapi.2015.vcxproj">
<Name>mod_httapi</Name>
<Project>{4748ff56-ca85-4809-97d6-a94c0fac1d77}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_spandsp\mod_spandsp.2015.vcxproj">
<Name>mod_spandsp</Name>
<Project>{1e21afe0-6fdb-41d2-942d-863607c24b91}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\applications\mod_voicemail\mod_voicemail.2015.vcxproj">
<Name>mod_voicemail</Name>
<Project>{d7f1e3f2-a3f4-474c-8555-15122571af52}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\codecs\mod_g723_1\mod_g723_1.2015.vcxproj">
<Name>mod_g723_1</Name>
<Project>{fea1eef7-876f-48de-88bf-c0e3e606d758}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\codecs\mod_g729\mod_g729.2015.vcxproj">
<Name>mod_g729</Name>
<Project>{1d95cd95-0de2-48c3-ac23-d5c7d1c9c0f0}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\codecs\mod_h26x\mod_h26x.2015.vcxproj">
<Name>mod_h26x</Name>
<Project>{2c3c2423-234b-4772-8899-d3b137e5ca35}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\codecs\mod_opus\mod_opus.2015.vcxproj">
<Name>mod_opus</Name>
<Project>{64e99cca-3c6f-4aeb-9fa3-cfac711257bb}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\dialplans\mod_dialplan_xml\mod_dialplan_xml.2015.vcxproj">
<Name>mod_dialplan_xml</Name>
<Project>{07113b25-d3af-4e04-ba77-4cd1171f022c}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\endpoints\mod_loopback\mod_loopback.2015.vcxproj">
<Name>mod_loopback</Name>
<Project>{b3f424ec-3d8f-417c-b244-3919d5e1a577}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\endpoints\mod_rtc\mod_rtc.2015.vcxproj">
<Name>mod_rtc</Name>
<Project>{3884add2-91d0-4cd6-86d3-d5fb2d4aab9e}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\endpoints\mod_sofia\mod_sofia.2015.vcxproj">
<Name>mod_sofia</Name>
<Project>{0df3abd0-ddc0-4265-b778-07c66780979b}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\endpoints\mod_verto\mod_verto.2015.vcxproj">
<Name>mod_verto</Name>
<Project>{5b2bace4-0f5a-4a21-930d-c0f4b1f58fa6}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\event_handlers\mod_cdr_csv\mod_cdr_csv.2015.vcxproj">
<Name>mod_cdr_csv</Name>
<Project>{44d7deaf-fda5-495e-8b9d-1439e4f4c21e}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\event_handlers\mod_event_socket\mod_event_socket.2015.vcxproj">
<Name>mod_event_socket</Name>
<Project>{05515420-16de-4e63-be73-85be85ba5142}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\formats\mod_local_stream\mod_local_stream.2015.vcxproj">
<Name>mod_local_stream</Name>
<Project>{2ca40887-1622-46a1-a7f9-17fd7e7e545b}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\formats\mod_native_file\mod_native_file.2015.vcxproj">
<Name>mod_native_file</Name>
<Project>{9254c4b0-6f60-42b6-bb3a-36d63fc001c7}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\formats\mod_shout\mod_shout.2015.vcxproj">
<Name>mod_shout</Name>
<Project>{38fe0559-9910-43a8-9e45-3e5004c27692}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\formats\mod_sndfile\mod_sndfile.2015.vcxproj">
<Name>mod_sndfile</Name>
<Project>{afac0568-7548-42d5-9f6a-8d3400a1e4f6}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\formats\mod_tone_stream\mod_tone_stream.2015.vcxproj">
<Name>mod_tone_stream</Name>
<Project>{6ff941ac-82c5-429f-aa4c-ad2fb9e5da52}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\loggers\mod_console\mod_console.2015.vcxproj">
<Name>mod_console</Name>
<Project>{1c453396-d912-4213-89fd-9b489162b7b5}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\loggers\mod_logfile\mod_logfile.2015.vcxproj">
<Name>mod_logfile</Name>
<Project>{d0bcac02-d94b-46b8-9b49-cddcc2bd7909}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_de\mod_say_de.2015.vcxproj">
<Name>mod_say_de</Name>
<Project>{5bc072db-3826-48ea-af34-fe32aa01e83b}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_en\mod_say_en.2015.vcxproj">
<Name>mod_say_en</Name>
<Project>{988cacf7-3fcb-4992-be69-77872ae67dc8}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_es\mod_say_es.2015.vcxproj">
<Name>mod_say_es</Name>
<Project>{fa429e98-8b03-45e6-a096-a4bc5e821de4}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_fr\mod_say_fr.2015.vcxproj">
<Name>mod_say_fr</Name>
<Project>{06e3a538-ab32-44f2-b477-755ff9cb5d37}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_it\mod_say_it.2015.vcxproj">
<Name>mod_say_it</Name>
<Project>{6d1bec70-4dcd-4fe9-adbd-4a43a67e4d05}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_nl\mod_say_nl.2015.vcxproj">
<Name>mod_say_nl</Name>
<Project>{a4b122cf-5196-476b-8c0e-d8bd59ac3c14}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_pt\mod_say_pt.2015.vcxproj">
<Name>mod_say_pt</Name>
<Project>{7c22bdff-cc09-400c-8a09-660733980028}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_ru\mod_say_ru.2015.vcxproj">
<Name>mod_say_ru</Name>
<Project>{0382e8fd-cfdc-41c0-8b03-792c7c84fc31}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_sv\mod_say_sv.2015.vcxproj">
<Name>mod_say_sv</Name>
<Project>{8cda2b34-fa44-49cc-9ec2-b8f35856cd15}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\say\mod_say_zh\mod_say_zh.2015.vcxproj">
<Name>mod_say_zh</Name>
<Project>{b6a9fb7a-1cc4-442b-812d-ec33e4e4a36e}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\xml_int\mod_xml_cdr\mod_xml_cdr.2015.vcxproj">
<Name>mod_xml_cdr</Name>
<Project>{08dad348-9e0a-4a2e-97f1-f1e7e24a7836}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\xml_int\mod_xml_curl\mod_xml_curl.2015.vcxproj">
<Name>mod_xml_curl</Name>
<Project>{ab91a099-7690-4ecf-8994-e458f4ea1ed4}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\src\mod\xml_int\mod_xml_rpc\mod_xml_rpc.2015.vcxproj">
<Name>mod_xml_rpc</Name>
<Project>{cbec7225-0c21-4da8-978e-1f158f8ad950}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\Console\FreeSwitchConsole.2015.vcxproj">
<Name>FreeSwitchConsole</Name>
<Project>{1af3a893-f7be-43dd-b697-8ab2397c0d67}</Project>
@ -61,18 +413,12 @@
</ItemGroup>
<ItemGroup>
<Content Include="filter.xslt" />
<Content Include="packages.config" />
</ItemGroup>
<PropertyGroup>
<WixToolPath>$(SolutionDir)packages\WiX.Toolset.2015.3.10.0.1503\tools\wix\</WixToolPath>
<WixTargetsPath>$(WixToolPath)wix.targets</WixTargetsPath>
<WixTasksPath>$(WixToolPath)WixTasks.dll</WixTasksPath>
</PropertyGroup>
<Import Project="$(WixTargetsPath)" />
<PropertyGroup>
<PreBuildEvent>"$(WixToolPath)\heat.exe" dir "$(ProjectDir)..\..\conf\vanilla" -cg FreeSWITCHConfFiles -gg -scom -sreg -sfrag -srd -dr CONFLOCATION -var var.FreeSWITCHConfFilesDir -out "$(ProjectDir)Fragments\FreeSWITCHConfFiles.wxs"
"$(WixToolPath)\heat.exe" dir "$(SolutionDir)$(Platform)\$(Configuration)\sounds" -cg FreeSWITCHSoundFiles8 -gg -scom -sreg -sfrag -srd -dr SOUNDLOCATION -var var.FreeSWITCHSoundFilesDir -out "$(ProjectDir)Fragments\FreeSWITCHSoundFiles8.wxs"
"$(WixToolPath)\heat.exe" dir "$(SolutionDir)$(Platform)\$(Configuration)" -t $(ProjectDir)filter.xslt -cg FreeSWITCHBaseFiles -gg -scom -sreg -sfrag -srd -dr INSTALLLOCATION -var var.FreeSWITCHBaseDir -out "$(ProjectDir)Fragments\FreeSWITCHBaseFiles.wxs"</PreBuildEvent>
"$(WixToolPath)\heat.exe" dir "$(SolutionDir)x64\$(Configuration)\sounds" -cg FreeSWITCHSoundFiles8 -gg -scom -sreg -sfrag -srd -dr SOUNDLOCATION -var var.FreeSWITCHSoundFilesDir -out "$(ProjectDir)Fragments\FreeSWITCHSoundFiles8.wxs"
"$(WixToolPath)\heat.exe" dir "$(SolutionDir)x64\$(Configuration)" -t $(ProjectDir)filter.xslt -cg FreeSWITCHBaseFiles -gg -scom -sreg -sfrag -srd -dr INSTALLLOCATION -var var.FreeSWITCHBaseDir -out "$(ProjectDir)Fragments\FreeSWITCHBaseFiles.wxs"</PreBuildEvent>
</PropertyGroup>
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="WiX.Toolset.2015" version="3.10.0.1503" />
</packages>

View File

@ -1,26 +1,28 @@
[freeswitch-testing]
name=FreeSwitch Packages for Enterprise Linux $releasever - Testing - $basearch
baseurl=http://files.freeswitch.org/yum/testing/$releasever/$basearch
baseurl=http://files.freeswitch.org/yum_unstable/$releasever/$basearch
#mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=testing-freeswitch$releasever&arch=$basearch
#failovermethod=priority
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
[freeswitch-testing-debuginfo]
name=FreeSwitch Packages for Enterprise Linux $releasever - Testing - $basearch - Debug
baseurl=http://files.freeswitch.org/yum/testing/$releasever/$basearch/debug
#mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=testing-debug-freeswitch$releasever&arch=$basearch
#failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
gpgcheck=1
#[freeswitch-testing-debuginfo]
## Included in freeswitch repo
#name=FreeSwitch Packages for Enterprise Linux $releasever - Testing - $basearch - Debug
#baseurl=http://files.freeswitch.org/yum_unstable/$releasever/$basearch
##mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=testing-debug-freeswitch$releasever&arch=$basearch
##failovermethod=priority
#enabled=0
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
#gpgcheck=1
[freeswitch-testing-source]
name=FreeSwitch Packages for Enterprise Linux $releasever - Testing - $basearch - Source
baseurl=http://files.freeswitch.org/yum/testing/$releasever/SRPMS
#mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=testing-source-freeswitch$releasever&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
gpgcheck=1
#[freeswitch-testing-source]
## Included in freeswitch repo
#name=FreeSwitch Packages for Enterprise Linux $releasever - Testing - $basearch - Source
#baseurl=http://files.freeswitch.org/yum_unstable/$releasever/$basearch
##mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=testing-source-freeswitch$releasever&arch=$basearch
#failovermethod=priority
#enabled=0
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
#gpgcheck=1

View File

@ -7,20 +7,22 @@ enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
[freeswitch-debuginfo]
name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch - Debug
baseurl=http://files.freeswitch.org/yum-1.6/$releasever/$basearch/debug
#mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-debug-5&arch=$basearch
#failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
gpgcheck=1
#[freeswitch-debuginfo]
## Included in freeswitch repo
#name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch - Debug
#baseurl=http://files.freeswitch.org/yum-1.6/$releasever/$basearch
##mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-debug-5&arch=$basearch
##failovermethod=priority
#enabled=0
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
#gpgcheck=1
[freeswitch-source]
name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch - Source
baseurl=http://files.freeswitch.org/yum-1.6/$releasever/SRPMS
#mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-source-5&arch=$basearch
#failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
gpgcheck=1
#[freeswitch-source]
## Included in freeswitch repo
#name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch - Source
#baseurl=http://files.freeswitch.org/yum-1.6/$releasever
##mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-source-5&arch=$basearch
##failovermethod=priority
#enabled=0
#gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH
#gpgcheck=1