Merge pull request #591 in FS/freeswitch from feature/FS-8293 to master

* commit '1ee2f0abc224fd6830fb8a2ddf120abfd8f641f0':
  add colors to good and bad
  update new pass
  FS-8293 [verto_communicator] - Showing speed in the menu bar if autoBand is true, adding option to test speed before making a call, enabling dedEnc if inboundBandwidth is below dedEncWatermark (3072 by default). FS-8293 [verto_communicator] - Changed info in the top menu bar for a icon+popover, changed autoBand's code in testSpeed method, moved 'Bandwidth settings' to 'Video settings' in settings modal and now hidding video quality selection when autoBand is checked. FS-8293 [verto_communicator] - Better bandwidth info ui. FS-8293 [verto_communicator] - Fixed speed test breaking at splash screen if user isn't logged in.
  Removed unused function.
  FS-8293 [verto_communicator] Implemented speed test in verto communicator.
  always change bw
  tweaks
  WIP not shabby auto vid settings
  first pass, add some funcs to conference and speed test features and fix bugs in ws.c for big payloads
This commit is contained in:
Anthony Minessale II 2015-11-12 18:40:27 -06:00
commit 785727e6fa
26 changed files with 717 additions and 147 deletions

View File

@ -91,6 +91,32 @@
/// The next JSON-RPC request id.
$.JsonRpcClient.prototype._current_id = 1;
$.JsonRpcClient.prototype.speedTest = function (bytes, cb) {
var socket = this.options.getSocket(this.wsOnMessage);
if (socket !== null) {
this.speedCB = cb;
this.speedBytes = bytes;
socket.send("#SPU " + bytes);
var loops = bytes / 1024;
var rem = bytes % 1024;
var i;
var data = new Array(1024).join(".");
for (i = 0; i < loops; i++) {
socket.send("#SPB " + data);
}
if (rem) {
socket.send("#SPB " + data);
}
socket.send("#SPE");
}
};
/**
* @fn call
* @memberof $.JsonRpcClient
@ -382,6 +408,26 @@
$.JsonRpcClient.prototype._wsOnMessage = function(event) {
// Check if this could be a JSON RPC message.
var response;
// Special sub proto
if (event.data[0] == "#" && event.data[1] == "S" && event.data[2] == "P") {
if (event.data[3] == "U") {
this.up_dur = parseInt(event.data.substring(4));
} else if (this.speedCB && event.data[3] == "D") {
this.down_dur = parseInt(event.data.substring(4));
var up_kps = (((this.speedBytes * 8) / (this.up_dur / 1000)) / 1024).toFixed(0);
var down_kps = (((this.speedBytes * 8) / (this.down_dur / 1000)) / 1024).toFixed(0);
console.info("Speed Test: Up: " + up_kps + " Down: " + down_kps);
this.speedCB(event, { upDur: this.up_dur, downDur: this.down_dur, upKPS: up_kps, downKPS: down_kps });
this.speedCB = null;
}
return;
}
try {
response = $.parseJSON(event.data);

View File

@ -15,7 +15,7 @@
"grunt-contrib-copy": "^0.7.0",
"grunt-contrib-cssmin": "^0.12.0",
"grunt-contrib-htmlmin": "^0.4.0",
"grunt-contrib-imagemin": "^0.9.2",
"grunt-contrib-imagemin": "^1.0.0",
"grunt-contrib-jshint": "^0.11.0",
"grunt-contrib-uglify": "^0.7.0",
"grunt-contrib-watch": "latest",

View File

@ -1481,6 +1481,43 @@ body:-webkit-full-screen #incall .video-footer {
.preview-wrapper video {
transform: scaleX(-1);
}
.drop-net-info {
padding-top: 0px;
cursor: default;
}
.drop-net-info .title {
text-align: center;
font-size: 16px;
font-weight: bold;
padding: 8px 14px;
margin: 0;
font-size: 14px;
background-color: #f7f7f7;
border-bottom: 1px solid #ebebeb;
}
.drop-net-info .title:hover {
background-color: #f7f7f7;
}
.drop-net-info a:hover {
color: #333 !important;
}
.net-info .yellow {
color: #e3d95b;
}
.net-info .green {
color: #00ae00;
}
.net-info .red {
color: #ae0000;
}
#mic-meter {
position: absolute;
bottom: 5px;

View File

@ -1,4 +1,10 @@
<div class="centered-block-frame" id="dialpad">
<div ng-show="loading">
<h3 style="margin-top: 4%;" class="text-center">Calling to {{ dialpadNumber }}...</h3>
<svg class="spinner" width="65px" height="65px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg">
<circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
</svg>
</div>
<div class="centered-block-frame" id="dialpad" ng-show="!loading">
<div id="call-history-wrapper">
<div id="call_history" class="shadow-z-2 panel">
<div class="panel-heading">

View File

@ -19,9 +19,21 @@
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li class="navbar-item-icon net-info" ng-show="(bandUp || bandDown) && storage.data.autoBand">
<a href="" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
<i ng-class="iconClass"></i>
<span class="caret"></span>
</a>
<ul class="dropdown-menu drop-net-info" role="menu" ng-click="$event.stopPropagation()">
<li><a class="title">Bandwidth Info</a></li>
<li><a>Outgoing: {{bandUp}} Kbps</a></li>
<li><a>Incoming: {{bandDown}} Kbps</a></li>
<li><a>Video Resolution: {{vidRes}}</a></li>
</ul>
</li>
<li>
<a href="">
<i class="mdi-toggle-radio-button-on" user-status condition="storage.data.userStatus"></i>
<i class="mdi-toggle-radio-button-on" user-status condition="storage.data.userStatus"></i>
</a>
</li>
<li>
@ -29,7 +41,6 @@
{{ storage.data.called_number && storage.data.userStatus == 'connecting' ? 'Last Call: ' : 'In Call: ' }} {{ storage.data.called_number }}
</a>
</li>
<li class="navbar-item-icon" ng-show="verto.data.connected">
<a href="" ng-click="openModal('partials/modal_settings.html', 'ModalSettingsController')">
<i class="mdi-action-settings"></i>

View File

@ -84,35 +84,53 @@
</div>
<div class="form-group">
<label for="video-quality">Video quality:</label>
<select name="video_quality" id="video-quality" class="form-control"
ng-model="mydata.vidQual"
ng-options="item.id as item.label for item in verto.videoQuality"></select>
</div>
<label>Video settings:</label> <br><br>
<a class="btn btn-primary" href="" ng-click="testSpeed()">Check Speed</a>
<span ng-bind="speedMsg"></span>
<input type="hidden" name="use_dedenc" ng-value="mydata.useDedenc" ng-model="mydata.useDedenc">
<input type="hidden" name="use_dedenc" ng-value="mydata.useDedenc" ng-model="mydata.useDedenc">
<h4>Dedicated Remote Encoder</h4>
<h5>Select a non default bandwidth to use a dedicated remote encoder.</h5>
<div ng-show="mydata.useDedenc" class="dedicated_encoder">
<p>Dedicated Remote Encoder enabled.</b>
</div>
<div ng-show="mydata.useDedenc" class="dedicated_encoder">
<p>Dedicated Remote Encoder enabled.</b>
</div>
<div class="form-group">
<label for="outgoing-bandwidth">Max outgoing bandwidth:</label>
<select name="outgoing_bandwidth" id="outgoing-bandwidth" class="form-control"
ng-model="mydata.outgoingBandwidth"
ng-change="checkUseDedRemoteEncoder(mydata.outgoingBandwidth)"
ng-options="item.id as item.label for item in verto.bandwidth"></select>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="mydata.autoBand" ng-change="checkAutoBand(mydata.autoBand)">
Auto
</label>
</div>
<div class="form-group">
<label for="incoming-bandwidth">Max incoming bandwidth:</label>
<select name="incoming_bandwidth" id="incoming-bandwidth" class="form-control"
ng-model="mydata.incomingBandwidth"
ng-change="checkUseDedRemoteEncoder(mydata.incomingBandwidth)"
ng-options="item.id as item.label for item in verto.bandwidth"></select>
<div class="checkbox" ng-show="mydata.autoBand">
<label>
<input type="checkbox" ng-model="mydata.testSpeedJoin">
Check bandwidth before joining call
</label>
</div>
<div ng-show="!mydata.autoBand">
<label for="video-quality">Video quality:</label>
<select name="video_quality" id="video-quality" class="form-control"
ng-disabled="mydata.autoBand"
ng-model="mydata.vidQual"
ng-options="item.id as item.label for item in verto.videoQuality"></select>
</div>
<div ng-show="!mydata.autoBand">
<label for="incoming-bandwidth">Max incoming bandwidth:</label>
<select name="incoming_bandwidth" id="incoming-bandwidth" class="form-control"
ng-model="mydata.incomingBandwidth"
ng-change="checkUseDedRemoteEncoder(mydata.incomingBandwidth)"
ng-options="item.id as item.label for item in verto.bandwidth"></select>
</div>
<div ng-show="!mydata.autoBand">
<label for="outgoing-bandwidth">Max outgoing bandwidth:</label>
<select name="outgoing_bandwidth" id="outgoing-bandwidth" class="form-control"
ng-model="mydata.outgoingBandwidth"
ng-options="item.id as item.label for item in verto.bandwidth"></select>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
.module('storageService')
.service('splashscreen', ['$rootScope', '$q', 'storage', 'config', 'verto',
function($rootScope, $q, storage, config, verto) {
var checkBrowser = function() {
return $q(function(resolve, reject) {
var activity = 'browser-upgrade';
@ -22,10 +22,10 @@
if (!navigator.getUserMedia) {
result['status'] = 'error';
result['message'] = 'Error: browser doesn\'t support WebRTC.';
reject(result);
reject(result);
}
resolve(result);
resolve(result);
});
};
@ -48,7 +48,7 @@
reject(result);
}
verto.data.mediaPerm = true;
resolve(result);
resolve(result);
});
});
};
@ -62,7 +62,7 @@
'activity': activity,
'message': 'Refresh Media Devices.'
};
verto.refreshDevices(function(status) {
verto.refreshDevicesCallback(function() {
resolve(result);
@ -72,6 +72,28 @@
});
};
var checkConnectionSpeed = function() {
return $q(function(resolve, reject) {
var activity = 'check-connection-speed';
var result = {
'status': 'success',
'soft': true,
'activity': activity,
'message': 'Check Connection Speed.'
};
if (storage.data.autoBand && verto.data.instance) {
verto.testSpeed(cb);
} else {
resolve(result);
}
function cb(data) {
resolve(result);
}
});
};
var provisionConfig = function() {
return $q(function(resolve, reject) {
var activity = 'provision-config';
@ -100,7 +122,7 @@
});
result['promise'] = configPromise;
resolve(result);
});
};
@ -136,13 +158,13 @@
verto.data.connecting = false;
resolve(result);
});
};
};
};
if(storage.data.ui_connected && storage.data.ws_connected) {
checkUserStored();
checkUserStored();
} else {
resolve(result);
resolve(result);
};
});
};
@ -152,7 +174,8 @@
checkMediaPerm,
refreshMediaDevices,
provisionConfig,
checkLogin
checkLogin,
checkConnectionSpeed
];
var progress_message = [
@ -160,12 +183,13 @@
'Checking media permissions',
'Refresh Media Devices.',
'Provisioning configuration.',
'Checking login.'
'Checking login.',
'Check Connection Speed.'
];
var getProgressMessage = function(current_progress) {
if(progress_message[current_progress] != undefined) {
return progress_message[current_progress];
return progress_message[current_progress];
} else {
return 'Please wait...';
}
@ -176,7 +200,7 @@
var calculateProgress = function(index) {
var _progress;
_progress = index + 1;
progress_percentage = (_progress / progress.length) * 100;
return progress_percentage;
@ -186,12 +210,12 @@
var fn, fn_return, status, interrupt, activity, soft, message, promise;
interrupt = false;
current_progress++;
if(current_progress >= progress.length) {
$rootScope.$emit('progress.complete', current_progress);
return;
}
fn = progress[current_progress];
fn_return = fn();
@ -221,7 +245,7 @@
emitNextProgress(fn_return);
}
);
};
return {
@ -232,4 +256,3 @@
};
}]);

View File

@ -35,7 +35,9 @@
askRecoverCall: false,
googNoiseSuppression: true,
googHighpassFilter: true,
googEchoCancellation: true
googEchoCancellation: true,
autoBand: true,
testSpeedJoin: true
};
data.$default(defaultSettings);

View File

@ -97,8 +97,17 @@
/**
* Call to the number in the $rootScope.dialpadNumber.
*/
$scope.loading = false;
$rootScope.call = function(extension) {
return call(extension);
if (!storage.data.testSpeedJoin || !$rootScope.dialpadNumber) {
return call(extension);
}
$scope.loading = true;
verto.testSpeed(function() {
$scope.loading = false;
call(extension);
});
}
}
]);

View File

@ -52,10 +52,13 @@
storage.data.email = verto.data.email;
storage.data.login = verto.data.login;
storage.data.password = verto.data.password;
if (storage.data.autoBand) {
verto.testSpeed();
}
if (redirect && storage.data.preview) {
$location.path('/preview');
}
else if (redirect) {
} else if (redirect) {
$location.path('/dialpad');
}
}
@ -180,6 +183,9 @@
};
function onWSLogin(ev, data) {
if(storage.data.autoBand) {
verto.testSpeed();
}
if(!ws_modalInstance) {
return;
};

View File

@ -4,10 +4,43 @@
angular
.module('vertoControllers')
.controller('MenuController', ['$scope', '$http', '$location',
'verto', 'storage',
function($scope, $http, $location, verto, storage) {
'verto', 'storage', '$rootScope',
function($scope, $http, $location, verto, storage, $rootScope) {
console.debug('Executing MenuController.');
}
$scope.storage = storage;
$rootScope.$on('testSpeed', function(e, data) {
var vidQual = storage.data.vidQual;
var bwp = 4;
$scope.bandDown = data.downKPS;
$scope.bandUp = data.upKPS;
if (data.downKPS < 2000) {
bwp--;
}
if (data.upKPS < 2000) {
bwp--;
}
$scope.iconClass = 'mdi-device-signal-wifi-4-bar green';
if (bwp < 4) {
$scope.iconClass = 'mdi-device-signal-wifi-3-bar yellow';
} else if (bwp < 2) {
$scope.iconClass = 'mdi-device-signal-wifi-1-bar red';
}
verto.videoQuality.forEach(function(vid) {
if (vid.id == vidQual){
$scope.vidRes = vid.label;
}
});
$scope.$apply();
});
}
]);
})();
})();

View File

@ -15,6 +15,9 @@
$scope.ok = function() {
storage.changeData($scope.mydata);
verto.data.instance.iceServers(storage.data.useSTUN);
if (storage.data.autoBand) {
$scope.testSpeed();
}
$modalInstance.close('Ok.');
};
@ -26,6 +29,16 @@
return verto.refreshDevices();
};
$scope.testSpeed = function() {
return verto.testSpeed(cb);
function cb(data) {
$scope.mydata.vidQual = storage.data.vidQual;
$scope.speedMsg = 'Up: ' + data.upKPS + ' Down: ' + data.downKPS;
$scope.$apply();
}
};
$scope.resetSettings = function() {
if (confirm('Factory Reset Settings?')) {
storage.factoryReset();
@ -35,11 +48,22 @@
};
};
$scope.checkUseDedRemoteEncoder = function(option) {
if ($scope.mydata.incomingBandwidth != 'default' || $scope.mydata.outgoingBandwidth != 'default') {
$scope.mydata.useDedenc = true;
$scope.checkAutoBand = function(option) {
$scope.mydata.useDedenc = false;
if (!option) {
$scope.mydata.outgoingBandwidth = 'default';
$scope.mydata.incomingBandwidth = 'default';
$scope.mydata.vidQual = 'hd';
} else {
$scope.mydata.testSpeedJoin = true;
}
};
$scope.checkUseDedRemoteEncoder = function(option) {
if (['0', 'default', '5120'].indexOf(option) != -1) {
$scope.mydata.useDedenc = false;
} else {
$scope.mydata.useDedenc = true;
}
};
}

View File

@ -40,7 +40,7 @@ vertoService.service('config', ['$rootScope', '$http', '$location', 'storage', '
verto.data.googlelogin = data.googlelogin;
verto.data.googleclientid = data.googleclientid;
}
angular.extend(verto.data, data);
/**
@ -62,13 +62,13 @@ vertoService.service('config', ['$rootScope', '$http', '$location', 'storage', '
console.debug("auto login per config.json");
verto.data.autologin_done = true;
}
if(verto.data.autologin && storage.data.name.length && storage.data.email.length && storage.data.login.length && storage.data.password.length) {
$rootScope.$emit('config.http.success', data);
$rootScope.$emit('config.http.success', data);
};
return response;
}, function(response) {
$rootScope.$emit('config.http.error', response);
$rootScope.$emit('config.http.error', response);
return response;
});
@ -79,4 +79,3 @@ vertoService.service('config', ['$rootScope', '$http', '$location', 'storage', '
'configure': configure
};
}]);

View File

@ -76,6 +76,12 @@ var bandwidth = [{
}, {
id: '2048',
label: '2mb'
}, {
id: '3196',
label: '3mb'
}, {
id: '4192',
label: '4mb'
}, {
id: '5120',
label: '5mb'
@ -797,6 +803,39 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
}
},
/**
* Do speed test.
*
* @param callback
*/
testSpeed: function(cb) {
data.instance.rpcClient.speedTest(1024 * 256, function(e, data) {
var upBand = Math.ceil(data.upKPS * .75),
downBand = Math.ceil(data.downKPS * .75);
if (storage.data.autoBand) {
storage.data.incomingBandwidth = downBand;
storage.data.outgoingBandwidth = upBand;
storage.data.useDedenc = false;
storage.data.vidQual = 'hd';
if (upBand < 512) {
storage.data.vidQual = 'qvga';
}
else if (upBand < 1024) {
storage.data.vidQual = 'vga';
}
}
if(cb) {
cb(data);
}
$rootScope.$emit('testSpeed', data);
});
},
/**
* Mute the microphone for the current call.
*

View File

@ -91,7 +91,7 @@ div#preload { display: none; }
<body>
<div data-role="page" id="page-login" align="center">
<div data-role="header" class="page-header">
FreeSWITCH Verto&trade; Video Transcoding Demo
FreeSWITCH Verto&trade; Video Transcoding Demo
</div>
</div>
@ -108,6 +108,18 @@ div#preload { display: none; }
</div>
<div data-role="page" id="page-bwtest" align="center">
<div data-role="header" class="page-header">
FreeSWITCH Verto&trade; Testing Network Connection
</div>
<h1>Testing Network Connection</h1>
<img src="images/speed.gif"/>
</div>
<div data-role="page" id="page-incall" align="center">
<div data-role="header" id="calltitle" class="pageheader">
Verto&trade; IN CALL
@ -248,7 +260,7 @@ div#preload { display: none; }
<div data-role="page" id="page-main" align="center">
<div data-role="header" class="pageheader">
FreeSWITCH Verto&trade; Video Transcoding Demo
FreeSWITCH Verto&trade; Video Transcoding Demo (<span id="bwinfo">*checking*</span>)
</div>
<br>
<center> <table width="1024" border="0">
@ -347,9 +359,9 @@ if ($('#devices').is(':visible')) {
}
</script>
<!--<button data-inline="true" id="showdemo" onclick="toggle_demo();">View Demo Extensions</button>-->
<button data-inline="true" id="showdevices" onclick="toggle_device();">View Device Settings</button>
<button data-inline="true"id="speedbtn">Check Speed</button>
<button data-inline="true"id="logoutbtn">Log Out</button>
<div id="devices" style="border-style:outset;border-width:2px">

View File

@ -95,7 +95,9 @@ $.FSRTC.getValidRes=function(cam,func){var used=[];var cached=localStorage.getIt
return func?func(cache):null;}
$.FSRTC.validRes=[];resI=0;checkRes(cam,func);}
$.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true);}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);}
console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.speedTest=function(bytes,cb){var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this.speedCB=cb;this.speedBytes=bytes;socket.send("#SPU "+bytes);var loops=bytes/512;var rem=bytes%512;var i;var data=new Array(512).join(".");for(i=0;i<loops;i++){socket.send("#SPB "+data);}
if(rem){socket.send("#SPB "+data);}
socket.send("#SPE");}};$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};}
if(this.options.sessid){params.sessid=this.options.sessid;}
var request={jsonrpc:'2.0',method:method,params:params,id:this._current_id++};if(!success_cb){success_cb=function(e){console.log("Success: ",e);};}
if(!error_cb){error_cb=function(e){console.log("Error: ",e);};}
@ -113,7 +115,9 @@ console.error("Websocket Lost "+self.ws_cnt+" sleep: "+self.ws_sleep+"msec");sel
self.ws_sleep=1000;self.ws_cnt=0;if(self.options.onWSConnect){self.options.onWSConnect(self);}
var req;while((req=$.JsonRpcClient.q.pop())){self._ws_socket.send(req);}};}}
return self._ws_socket?true:false;};$.JsonRpcClient.prototype._getSocket=function(onmessage_cb){if(this.options.socketUrl===null||!("WebSocket"in window))return null;this.connectSocket(onmessage_cb);return this._ws_socket;};$.JsonRpcClient.q=[];$.JsonRpcClient.prototype._wsCall=function(socket,request,success_cb,error_cb){var request_json=$.toJSON(request);if(socket.readyState<1){self=this;$.JsonRpcClient.q.push(request_json);}else{socket.send(request_json);}
if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}else if('error'in response&&this._ws_callbacks[response.id]){var error_cb=this._ws_callbacks[response.id].error_cb;var orig_req=this._ws_callbacks[response.id].request;if(!self.authing&&response.error.code==-32000&&self.options.login&&self.options.passwd){self.authing=true;this.call("login",{login:self.options.login,passwd:self.options.passwd,loginParams:self.options.loginParams,userVariables:self.options.userVariables},this._ws_callbacks[response.id].request_obj.method=="login"?function(e){self.authing=false;console.log("logged in");delete self._ws_callbacks[response.id];if(self.options.onWSLogin){self.options.onWSLogin(true,self);}}:function(e){self.authing=false;console.log("logged in, resending request id: "+response.id);var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send(orig_req);}
if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;if(event.data[0]=="#"&&event.data[1]=="S"&&event.data[2]=="P"){if(event.data[3]=="U"){this.up_dur=parseInt(event.data.substring(4));}else if(this.speedCB&&event.data[3]=="D"){this.down_dur=parseInt(event.data.substring(4));var up_kps=(((this.speedBytes*8)/(this.up_dur/1000))/1024).toFixed(0);var down_kps=(((this.speedBytes*8)/(this.down_dur/1000))/1024).toFixed(0);console.info("Speed Test: Up: "+up_kps+" Down: "+down_kps);this.speedCB(event,{upDur:this.up_dur,downDur:this.down_dur,upKPS:up_kps,downKPS:down_kps});this.speedCB=null;}
return;}
try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}else if('error'in response&&this._ws_callbacks[response.id]){var error_cb=this._ws_callbacks[response.id].error_cb;var orig_req=this._ws_callbacks[response.id].request;if(!self.authing&&response.error.code==-32000&&self.options.login&&self.options.passwd){self.authing=true;this.call("login",{login:self.options.login,passwd:self.options.passwd,loginParams:self.options.loginParams,userVariables:self.options.userVariables},this._ws_callbacks[response.id].request_obj.method=="login"?function(e){self.authing=false;console.log("logged in");delete self._ws_callbacks[response.id];if(self.options.onWSLogin){self.options.onWSLogin(true,self);}}:function(e){self.authing=false;console.log("logged in, resending request id: "+response.id);var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send(orig_req);}
if(self.options.onWSLogin){self.options.onWSLogin(true,self);}},function(e){console.log("error logging in, request id:",response.id);delete self._ws_callbacks[response.id];error_cb(response.error,this);if(self.options.onWSLogin){self.options.onWSLogin(false,self);}});return;}
delete this._ws_callbacks[response.id];error_cb(response.error,this);return;}}}catch(err){console.log("ERROR: "+err);return;}
if(typeof this.options.onmessage==='function'){event.eventData=response;if(!event.eventData){event.eventData={};}

View File

@ -197,7 +197,46 @@ function check_vid() {
return use_vid;
}
// Attach audio output device to video element using device/sink ID.
function do_speed_test(fn)
{
goto_page("bwtest");
vertoHandle.rpcClient.speedTest(1024 * 256, function(e, obj) {
//console.error("Up: " + obj.upKPS, "Down: ", obj.downKPS);
var vid = "default";
//if (outgoingBandwidth === "default") {
outgoingBandwidth = Math.ceil(obj.upKPS * .75).toString();
$("#vqual_hd").prop("checked", true);
vid = "1280x720";
if (outgoingBandwidth < 1024) {
$("#vqual_vga").prop("checked", true);
vid = "640x480";
}
if (outgoingBandwidth < 512) {
$("#vqual_qvga").prop("checked", true);
vid = "320x240";
}
//}
if (incomingBandwidth === "default") {
incomingBandwidth = Math.ceil(obj.downKPS * .75).toString();
}
console.info(outgoingBandwidth, incomingBandwidth);
$("#bwinfo").html("<b>Bandwidth: " + "Up: " + obj.upKPS + " Down: " + obj.downKPS + " Vid: " + vid + "</b>");
if (fn) {
fn();
}
});
}
// Attach audio output device to video element using device/sink ID.
function attachSinkId(element, sinkId) {
if (typeof element.sinkId !== 'undefined') {
element.setSinkId(sinkId)
@ -559,24 +598,34 @@ var callbacks = {
ringing = false;
if (success) {
online(true);
/*
verto.subscribe("presence", {
handler: function(v, e) {
console.error("PRESENCE:", e);
}
});
*/
do_speed_test(function() {
online(true);
goto_page("main");
if (!window.location.hash) {
goto_page("main");
}
$("input[type='radio']").checkboxradio("refresh");
$("input[type='checkbox']").checkboxradio("refresh");
/*
verto.subscribe("presence", {
handler: function(v, e) {
console.error("PRESENCE:", e);
}
});
*/
if (!window.location.hash) {
goto_page("main");
}
if (autocall) {
autocall = false;
docall();
}
});
if (autocall) {
autocall = false;
docall();
}
} else {
goto_page("main");
goto_dialog("login-error");
@ -765,7 +814,7 @@ function docall() {
$("#main_info").html("Trying");
check_vid_res();
console.error(outgoingBandwidth, incomingBandwidth);
cur_call = vertoHandle.newCall({
destination_number: $("#ext").val(),
caller_id_name: $("#cidname").val(),
@ -993,8 +1042,10 @@ function refresh_devices()
$("#useshare").selectmenu('refresh', true);
//$("input[type='radio']).checkboxradio({});
$("input[type='radio']").checkboxradio("refresh");
$("input[type='checkbox']").checkboxradio("refresh");
//$("input[type='radio']").checkboxradio("refresh");
//$("input[type='checkbox']").checkboxradio("refresh");
//console.error($("#usecamera").find(":selected").val());
//$.FSRTC.getValidRes($("#usecamera").find(":selected").val(), undefined);
@ -1021,7 +1072,7 @@ function refresh_devices()
function init() {
cur_call = null;
goto_page("main");
goto_page("bwtest");
$("#usecamera").selectmenu({});
$("#usemic").selectmenu({});
@ -1480,6 +1531,13 @@ function init() {
$("#errordisplay").html("");
});
$("#speedbtn").click(function() {
do_speed_test(function() {
goto_page("main");
});
$("#errordisplay").html("");
});
$("#loginbtn").click(function() {
online(false);
vertoHandle.loginData({

View File

@ -341,6 +341,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses
SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_core_session_t *session, switch_rw_t rw);
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_END_EXTERN_C
#endif

View File

@ -767,6 +767,19 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m
conference_utils_member_set_flag_locked(member, MFLAG_NO_MINIMIZE_ENCODING);
}
if ((var = switch_channel_get_variable(member->channel, "rtp_video_max_bandwidth_in"))) {
member->max_bw_in = switch_parse_bandwidth_string(var);
}
if ((var = switch_channel_get_variable(member->channel, "rtp_video_max_bandwidth_out"))) {
member->max_bw_out = switch_parse_bandwidth_string(var);;
if (member->max_bw_out < conference->video_codec_settings.video.bandwidth) {
conference_utils_member_set_flag_locked(member, MFLAG_NO_MINIMIZE_ENCODING);
switch_core_media_set_outgoing_bitrate(member->session, SWITCH_MEDIA_TYPE_VIDEO, member->max_bw_out);
}
}
switch_channel_set_variable_printf(channel, "conference_member_id", "%d", member->id);
switch_channel_set_variable_printf(channel, "conference_moderator", "%s", conference_utils_member_test_flag(member, MFLAG_MOD) ? "true" : "false");
switch_channel_set_variable_printf(channel, "conference_ghost", "%s", conference_utils_member_test_flag(member, MFLAG_GHOST) ? "true" : "false");

View File

@ -1828,13 +1828,66 @@ 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)
{
switch_core_session_message_t msg = { 0 };
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 = kps;
}
void conference_video_set_max_incoming_bitrate_member(conference_member_t *member, int kps)
{
member->max_bw_in = kps;
member->managed_kps = 0;
}
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);
}
}
void conference_video_set_max_incoming_bitrate(conference_obj_t *conference, int kps)
{
conference_member_t *imember;
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)) {
conference_video_set_max_incoming_bitrate_member(imember, kps);
}
}
switch_mutex_unlock(conference->member_mutex);
}
void conference_video_set_absolute_incoming_bitrate(conference_obj_t *conference, int kps)
{
conference_member_t *imember;
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)) {
conference_video_set_absolute_incoming_bitrate_member(imember, kps);
}
}
switch_mutex_unlock(conference->member_mutex);
}
void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_t *layer)
{
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) {
switch_core_session_message_t msg = { 0 };
int kps;
int w = 320;
int h = 240;
@ -1845,23 +1898,40 @@ void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_
h = layer->screen_h;
}
}
if (!layer || !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) || member->avatar_png_img) {
kps = 200;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
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 {
kps = switch_calc_bitrate(w, h, 2, (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);
int max = 0;
if (!layer || !conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) || member->avatar_png_img) {
kps = 256;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "%s auto-setting bitrate to %dkps because user's image is not visible\n",
switch_channel_get_name(member->channel), kps);
} else {
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);
}
}
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 = kps;
conference_video_set_incoming_bitrate(member, kps);
}
}

View File

@ -2862,7 +2862,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, 2, (int)conference->video_fps.fps);
conference->video_codec_settings.video.bandwidth = switch_calc_bitrate(canvas_w, canvas_h, 1, (int)conference->video_fps.fps);
} else {
conference->video_codec_settings.video.bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth);
}

View File

@ -657,6 +657,8 @@ typedef struct conference_obj {
int recording_members;
uint32_t video_floor_packets;
video_layout_t *new_personal_vlayout;
int max_bw_in;
int force_bw_in;
} conference_obj_t;
/* Relationship with another member */
@ -757,6 +759,9 @@ struct conference_member {
switch_media_flow_t video_media_flow;
mcu_canvas_t *canvas;
switch_image_t *pcanvas_img;
int max_bw_in;
int force_bw_in;
int max_bw_out;
};
typedef enum {

View File

@ -1844,15 +1844,79 @@ static void client_run(jsock_t *jsock)
switch_ssize_t bytes;
ws_opcode_t oc;
uint8_t *data;
bytes = ws_read_frame(&jsock->ws, &oc, &data);
if (bytes < 0) {
die("BAD READ %" SWITCH_SSIZE_T_FMT "\n", bytes);
break;
}
if (bytes) {
char *s = (char *) data;
if (*s == '#') {
char repl[2048] = "";
switch_time_t a, b;
if (s[1] == 'S' && s[2] == 'P') {
if (s[3] == 'U') {
int i, size = 0;
char *p = s+4;
int loops = 0;
int rem = 0;
int dur = 0, j = 0;
if (!(size = atoi(p))) {
continue;
}
a = switch_time_now();
do {
bytes = ws_read_frame(&jsock->ws, &oc, &data);
s = (char *) data;
} while (bytes && data && s[0] == '#' && s[3] == 'B');
b = switch_time_now();
if (!bytes || !data) continue;
if (s[0] != '#') goto nm;
switch_snprintf(repl, sizeof(repl), "#SPU %ld", (b - a) / 1000);
ws_write_frame(&jsock->ws, WSOC_TEXT, repl, strlen(repl));
loops = size / 1024;
rem = size % 1024;
switch_snprintf(repl, sizeof(repl), "#SPB ");
memset(repl+4, '.', 1024);
for (j = 0; j < 10 ; j++) {
int ddur = 0;
a = switch_time_now();
for (i = 0; i < loops; i++) {
ws_write_frame(&jsock->ws, WSOC_TEXT, repl, 1024);
}
if (rem) {
ws_write_frame(&jsock->ws, WSOC_TEXT, repl, rem);
}
b = switch_time_now();
ddur += ((b - a) / 1000);
dur += ddur;
}
dur /= j+1;
switch_snprintf(repl, sizeof(repl), "#SPD %d", dur);
ws_write_frame(&jsock->ws, WSOC_TEXT, repl, strlen(repl));
}
}
continue;
}
nm:
if (process_input(jsock, data, bytes) != SWITCH_STATUS_SUCCESS) {
die("Input Error\n");
}
@ -3271,7 +3335,7 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
{
cJSON *obj = cJSON_CreateObject(), *screenShare = NULL, *dedEnc = NULL, *mirrorInput, *json_ptr = NULL;
cJSON *obj = cJSON_CreateObject(), *screenShare = NULL, *dedEnc = NULL, *mirrorInput, *json_ptr = NULL, *bandwidth = NULL;
switch_core_session_t *session = NULL;
switch_channel_t *channel;
switch_event_t *var_event;
@ -3281,7 +3345,7 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock
cJSON *dialog;
verto_pvt_t *tech_pvt;
char name[512];
const char *var, *destination_number, *call_id = NULL, *sdp = NULL, *bandwidth = NULL,
const char *var, *destination_number, *call_id = NULL, *sdp = NULL,
*caller_id_name = NULL, *caller_id_number = NULL, *remote_caller_id_name = NULL, *remote_caller_id_number = NULL,*context = NULL;
switch_event_header_t *hp;
@ -3353,15 +3417,19 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock
switch_channel_set_flag(channel, CF_VIDEO_MIRROR_INPUT);
}
if ((bandwidth = cJSON_GetObjectCstr(dialog, "outgoingBandwidth"))) {
if (strcasecmp(bandwidth, "default")) {
switch_channel_set_variable(channel, "rtp_video_max_bandwidth_in", bandwidth);
if ((bandwidth = cJSON_GetObjectItem(dialog, "outgoingBandwidth"))) {
if (!zstr(bandwidth->valuestring) && strcasecmp(bandwidth->valuestring, "default")) {
switch_channel_set_variable(channel, "rtp_video_max_bandwidth_in", bandwidth->valuestring);
} else if (bandwidth->valueint) {
switch_channel_set_variable_printf(channel, "rtp_video_max_bandwidth_in", "%d", bandwidth->valueint);
}
}
if ((bandwidth = cJSON_GetObjectCstr(dialog, "incomingBandwidth"))) {
if (strcasecmp(bandwidth, "default")) {
switch_channel_set_variable(channel, "rtp_video_max_bandwidth_out", bandwidth);
if ((bandwidth = cJSON_GetObjectItem(dialog, "incomingBandwidth"))) {
if (!zstr(bandwidth->valuestring) && strcasecmp(bandwidth->valuestring, "default")) {
switch_channel_set_variable(channel, "rtp_video_max_bandwidth_out", bandwidth->valuestring);
} else if (bandwidth->valueint) {
switch_channel_set_variable_printf(channel, "rtp_video_max_bandwidth_out", "%d", bandwidth->valueint);
}
}

View File

@ -264,7 +264,7 @@ int ws_handshake(wsh_t *wsh)
}
}
if (bytes > sizeof(wsh->buffer) -1) {
if (bytes > wsh->buflen -1) {
goto err;
}
@ -362,7 +362,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
}
}
} while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 100);
} while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 1000);
goto end;
}
@ -382,7 +382,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block)
ms_sleep(10);
}
}
} while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 100);
} while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 1000);
if (wsh->x >= 1000 || (block && wsh->x >= 100)) {
r = -1;
@ -596,7 +596,15 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, SSL_CTX *ssl_ctx, int close_sock, int
wsh->close_sock = 1;
}
wsh->buflen = sizeof(wsh->buffer);
wsh->buflen = 1024 * 64;
wsh->bbuflen = wsh->buflen;
wsh->buffer = malloc(wsh->buflen);
wsh->bbuffer = malloc(wsh->bbuflen);
//printf("init %p %ld\n", (void *) wsh->bbuffer, wsh->bbuflen);
//memset(wsh->buffer, 0, wsh->buflen);
//memset(wsh->bbuffer, 0, wsh->bbuflen);
wsh->secure = ssl_ctx ? 1 : 0;
setup_socket(sock);
@ -644,6 +652,12 @@ void ws_destroy(wsh_t *wsh)
SSL_free(wsh->ssl);
wsh->ssl = NULL;
}
if (wsh->buffer) free(wsh->buffer);
if (wsh->bbuffer) free(wsh->bbuffer);
wsh->buffer = wsh->bbuffer = NULL;
}
ssize_t ws_close(wsh_t *wsh, int16_t reason)
@ -685,6 +699,20 @@ ssize_t ws_close(wsh_t *wsh, int16_t reason)
}
uint64_t hton64(uint64_t val)
{
if (__BYTE_ORDER == __BIG_ENDIAN) return (val);
else return __bswap_64(val);
}
uint64_t ntoh64(uint64_t val)
{
if (__BYTE_ORDER == __BIG_ENDIAN) return (val);
else return __bswap_64(val);
}
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
{
@ -692,6 +720,10 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
char *maskp;
int ll = 0;
int frag = 0;
int blen;
wsh->body = wsh->bbuffer;
wsh->packetlen = 0;
again:
need = 2;
@ -745,12 +777,11 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
int fin = (wsh->buffer[0] >> 7) & 1;
int mask = (wsh->buffer[1] >> 7) & 1;
if (fin) {
if (*oc == WSOC_CONTINUATION) {
frag = 1;
} else {
frag = 0;
}
if (!fin && *oc != WSOC_CONTINUATION) {
frag = 1;
} else if (fin && *oc == WSOC_CONTINUATION) {
frag = 0;
}
if (mask) {
@ -765,23 +796,33 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
wsh->plen = wsh->buffer[1] & 0x7f;
wsh->payload = &wsh->buffer[2];
if (wsh->plen == 127) {
uint64_t *u64;
int more = 0;
need += 8;
if (need > wsh->datalen) {
/* too small - protocol err */
*oc = WSOC_CLOSE;
return ws_close(wsh, WS_PROTO_ERR);
}
//*oc = WSOC_CLOSE;
//return ws_close(wsh, WS_PROTO_ERR);
more = ws_raw_read(wsh, wsh->buffer + wsh->datalen, need - wsh->datalen, WS_BLOCK);
if (more < need - wsh->datalen) {
*oc = WSOC_CLOSE;
return ws_close(wsh, WS_PROTO_ERR);
} else {
wsh->datalen += more;
}
}
u64 = (uint64_t *) wsh->payload;
wsh->payload += 8;
wsh->plen = ntohl((u_long)*u64);
wsh->plen = ntoh64(*u64);
} else if (wsh->plen == 126) {
uint16_t *u16;
@ -811,16 +852,30 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
return ws_close(wsh, WS_PROTO_ERR);
}
if ((need + wsh->datalen) > (ssize_t)wsh->buflen) {
/* too big - Ain't nobody got time fo' dat */
*oc = WSOC_CLOSE;
return ws_close(wsh, WS_DATA_TOO_BIG);
blen = wsh->body - wsh->bbuffer;
if (need + blen > (ssize_t)wsh->bbuflen) {
void *tmp;
wsh->bbuflen = need + blen + wsh->rplen;
if ((tmp = realloc(wsh->bbuffer, wsh->bbuflen))) {
wsh->bbuffer = tmp;
} else {
abort();
}
wsh->body = wsh->bbuffer + blen;
}
wsh->rplen = wsh->plen - need;
if (wsh->rplen) {
memcpy(wsh->body, wsh->payload, wsh->rplen);
}
while(need) {
ssize_t r = ws_raw_read(wsh, wsh->payload + wsh->rplen, need, WS_BLOCK);
ssize_t r = ws_raw_read(wsh, wsh->body + wsh->rplen, need, WS_BLOCK);
if (r < 1) {
/* invalid read - protocol err .. */
@ -837,28 +892,30 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
ssize_t i;
for (i = 0; i < wsh->datalen; i++) {
wsh->payload[i] ^= maskp[i % 4];
wsh->body[i] ^= maskp[i % 4];
}
}
if (*oc == WSOC_PING) {
ws_write_frame(wsh, WSOC_PONG, wsh->payload, wsh->rplen);
ws_write_frame(wsh, WSOC_PONG, wsh->body, wsh->rplen);
goto again;
}
*(wsh->body+wsh->rplen) = '\0';
wsh->packetlen += wsh->rplen;
wsh->body += wsh->rplen;
if (frag) {
goto again;
}
*data = (uint8_t *)wsh->bbuffer;
*(wsh->payload+wsh->rplen) = '\0';
*data = (uint8_t *)wsh->payload;
//printf("READ[%ld][%d]-----------------------------:\n[%s]\n-------------------------------\n", wsh->rplen, *oc, (char *)*data);
//printf("READ[%ld][%d]-----------------------------:\n[%s]\n-------------------------------\n", wsh->packetlen, *oc, (char *)*data);
return wsh->rplen;
return wsh->packetlen;
}
break;
default:
@ -871,6 +928,7 @@ ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data)
}
}
#if 0
ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes)
{
@ -885,6 +943,7 @@ ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes)
return bytes;
}
ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc)
{
ssize_t r = 0;
@ -899,7 +958,7 @@ ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc)
return r;
}
#endif
ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes)
{
@ -934,7 +993,7 @@ ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes)
hlen += 8;
u64 = (uint64_t *) &hdr[2];
*u64 = htonl(bytes);
*u64 = hton64(bytes);
}
if (wsh->write_buffer_len < (hlen + bytes + 1)) {

View File

@ -78,15 +78,18 @@ typedef enum {
typedef struct wsh_s {
ws_socket_t sock;
char buffer[65536];
char wbuffer[65536];
char *buffer;
char *bbuffer;
char *body;
char *uri;
size_t buflen;
size_t bbuflen;
ssize_t datalen;
ssize_t wdatalen;
char *payload;
ssize_t plen;
ssize_t rplen;
ssize_t packetlen;
SSL *ssl;
int handshake;
uint8_t down;

View File

@ -8890,6 +8890,30 @@ SWITCH_DECLARE(switch_bool_t) switch_core_media_check_dtls(switch_core_session_t
}
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_media_handle_t *smh;
switch_rtp_engine_t *engine;
switch_status_t status = SWITCH_STATUS_FALSE;
if (!(smh = session->media_handle)) {
return SWITCH_STATUS_FALSE;
}
if (switch_channel_down(session->channel)) {
return SWITCH_STATUS_FALSE;
}
engine = &smh->engines[type];
if (switch_core_codec_ready(&engine->write_codec)) {
status = switch_core_codec_control(&engine->write_codec, SCC_VIDEO_BANDWIDTH,
SCCT_INT, &bitrate, SCCT_NONE, NULL, NULL, NULL);
}
return status;
}
//?
SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
{