From a961b0e90b9c6621be447ff59b79a1c3d25b17c9 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Tue, 30 Dec 2014 13:13:26 +0800 Subject: [PATCH 01/72] fix type, send returns ssize_t --- src/mod/endpoints/mod_verto/ws.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_verto/ws.c b/src/mod/endpoints/mod_verto/ws.c index a572a89d07..db2e39e5ab 100644 --- a/src/mod/endpoints/mod_verto/ws.c +++ b/src/mod/endpoints/mod_verto/ws.c @@ -400,7 +400,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block) ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) { - size_t r; + ssize_t r; int sanity = 2000; int ssl_err = 0; From bf5210bf72d6c4b0d9b599a5a07ee59a9c947436 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Tue, 30 Dec 2014 13:16:28 +0800 Subject: [PATCH 02/72] retry send when the socket sent less than we want --- src/mod/endpoints/mod_verto/mod_verto.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index ae9d9a9e2f..7616416982 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -1456,6 +1456,9 @@ static void http_static_handler(switch_http_request_t *request, verto_vhost_t *v for (;;) { switch_status_t status; + ssize_t written = 0; + ssize_t ret = 0; + int sanity = 3; flen = sizeof(chunk); status = switch_file_read(fd, chunk, &flen); @@ -1464,7 +1467,17 @@ static void http_static_handler(switch_http_request_t *request, verto_vhost_t *v break; } - ws_raw_write(&jsock->ws, chunk, flen); +again: + ret = ws_raw_write(&jsock->ws, chunk + written, flen); + if (ret == -1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error write %" SWITCH_SIZE_T_FMT " bytes!\n", flen); + ws_close(&jsock->ws, WS_NONE); + } else if (ret > 0 && ret < flen && sanity > 0) { + switch_yield(1000); + flen -= ret; + written += ret; + goto again; + } } switch_file_close(fd); } else { From 1965b3b18d30b88a62d26e0f76ff46b6f5641e53 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 30 Dec 2014 09:06:32 -0600 Subject: [PATCH 03/72] FS-7106 #resolve Fix concurrency issue --- src/mod/applications/mod_httapi/mod_httapi.c | 52 +++++++++++--------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 420b7578d9..6a452b4ab4 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -149,6 +149,8 @@ static struct { hash_node_t *hash_root; hash_node_t *hash_tail; switch_hash_t *profile_hash; + switch_hash_t *request_hash; + switch_mutex_t *request_mutex; switch_hash_t *parse_hash; char cache_path[128]; int debug; @@ -170,7 +172,6 @@ struct http_file_context { char *cache_file; char *cache_file_base; char *meta_file; - char *lock_file; char *metadata; time_t expires; switch_file_t *lock_fd; @@ -192,6 +193,8 @@ struct http_file_context { char *name; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; } write; + + switch_mutex_t *mutex; }; typedef struct http_file_context http_file_context_t; @@ -2381,7 +2384,6 @@ static char *load_cache_data(http_file_context_t *context, const char *url) context->cache_file_base = switch_core_sprintf(context->pool, "%s%s%s", globals.cache_path, SWITCH_PATH_SEPARATOR, digest); context->meta_file = switch_core_sprintf(context->pool, "%s%s%s.meta", globals.cache_path, SWITCH_PATH_SEPARATOR, digest); - context->lock_file = switch_core_sprintf(context->pool, "%s%s%s.lock", globals.cache_path, SWITCH_PATH_SEPARATOR, digest); if (switch_file_exists(context->meta_file, context->pool) == SWITCH_STATUS_SUCCESS && ((fd = open(context->meta_file, O_RDONLY, 0)) > -1)) { if ((bytes = read(fd, meta_buffer, sizeof(meta_buffer))) > 0) { @@ -2703,27 +2705,29 @@ static switch_status_t lock_file(http_file_context_t *context, switch_bool_t loc { switch_status_t status = SWITCH_STATUS_SUCCESS; - + http_file_context_t *xcontext = NULL; if (lock) { - if (switch_file_open(&context->lock_fd, - context->lock_file, - SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE | SWITCH_FOPEN_TRUNCATE, - SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, context->pool) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + switch_mutex_lock(globals.request_mutex); + if (!(xcontext = switch_core_hash_find(globals.request_hash, context->dest_url))) { + switch_core_hash_insert(globals.request_hash, context->dest_url, context); + xcontext = context; } + switch_mutex_lock(context->mutex); + switch_mutex_unlock(globals.request_mutex); - - if (switch_file_lock(context->lock_fd, SWITCH_FLOCK_EXCLUSIVE) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + if (context != xcontext) { + switch_mutex_lock(xcontext->mutex); + switch_mutex_unlock(xcontext->mutex); } + } else { - if (context->lock_fd){ - switch_file_close(context->lock_fd); - status = SWITCH_STATUS_SUCCESS; + switch_mutex_lock(globals.request_mutex); + if ((xcontext = switch_core_hash_find(globals.request_hash, context->dest_url)) && xcontext == context) { + switch_core_hash_delete(globals.request_hash, context->dest_url); } - - unlink(context->lock_file); + switch_mutex_unlock(context->mutex); + switch_mutex_unlock(globals.request_mutex); } return status; @@ -2745,8 +2749,6 @@ static switch_status_t locate_url_file(http_file_context_t *context, const char return SWITCH_STATUS_SUCCESS; } - lock_file(context, SWITCH_TRUE); - if (context->url_params) { ext = switch_event_get_header(context->url_params, "ext"); } @@ -2837,8 +2839,6 @@ static switch_status_t locate_url_file(http_file_context_t *context, const char unlink(context->cache_file); } - lock_file(context, SWITCH_FALSE); - switch_event_destroy(&headers); return status; @@ -2875,6 +2875,7 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path, context = switch_core_alloc(handle->memory_pool, sizeof(*context)); context->pool = handle->memory_pool; + switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); pdup = switch_core_strdup(context->pool, pa); @@ -2953,10 +2954,14 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path, context->read.ext = switch_event_get_header(context->url_params, "ext"); } + lock_file(context, SWITCH_TRUE); + if ((status = locate_url_file(context, context->dest_url)) != SWITCH_STATUS_SUCCESS) { return status; } + lock_file(context, SWITCH_FALSE); + if ((status = switch_core_file_open(&context->fh, context->cache_file, handle->channels, @@ -2965,7 +2970,6 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid cache file %s opening url %s Discarding file.\n", context->cache_file, path); unlink(context->cache_file); unlink(context->meta_file); - unlink(context->lock_file); return status; } } @@ -3001,6 +3005,9 @@ static switch_status_t http_file_file_close(switch_file_handle_t *handle) { http_file_context_t *context = handle->private_info; + switch_mutex_lock(context->mutex); + switch_mutex_unlock(context->mutex); + if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&context->fh); } @@ -3041,7 +3048,6 @@ static switch_status_t http_file_file_close(switch_file_handle_t *handle) if (context->cache_file) { unlink(context->cache_file); unlink(context->meta_file); - unlink(context->lock_file); } } @@ -3105,6 +3111,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load) globals.cache_ttl = 300; globals.not_found_expires = 300; + switch_mutex_init(&globals.request_mutex, SWITCH_MUTEX_NESTED, pool); http_file_supported_formats[0] = "http"; @@ -3133,6 +3140,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load) switch_core_hash_init(&globals.profile_hash); + switch_core_hash_init(&globals.request_hash); switch_core_hash_init_case(&globals.parse_hash, SWITCH_FALSE); bind_parser("execute", parse_execute); From 0db3b1e34424c0552d508a1f8e923a7a8e663c6d Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 3 Jan 2015 09:22:32 +0800 Subject: [PATCH 04/72] FS-7127 #comment add grunt --- html5/verto/js/.gitignore | 4 ++++ html5/verto/js/Gruntfile.js | 30 ++++++++++++++++++++++++++++++ html5/verto/js/package.json | 9 +++++++++ 3 files changed, 43 insertions(+) create mode 100644 html5/verto/js/.gitignore create mode 100644 html5/verto/js/Gruntfile.js create mode 100644 html5/verto/js/package.json diff --git a/html5/verto/js/.gitignore b/html5/verto/js/.gitignore new file mode 100644 index 0000000000..347a88699e --- /dev/null +++ b/html5/verto/js/.gitignore @@ -0,0 +1,4 @@ +jsmin +node_modules +verto-max.js +verto-min.js diff --git a/html5/verto/js/Gruntfile.js b/html5/verto/js/Gruntfile.js new file mode 100644 index 0000000000..bb4fa39b82 --- /dev/null +++ b/html5/verto/js/Gruntfile.js @@ -0,0 +1,30 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + jshint: { + files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], + options: { + // options here to override JSHint defaults + globals: { + jQuery: true, + console: true, + module: true, + document: true + } + } + }, + + watch: { + files: ['<%= jshint.files %>'], + tasks: ['jshint'] + } + }); + + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + grunt.registerTask('default', ['jshint']); + +}; diff --git a/html5/verto/js/package.json b/html5/verto/js/package.json new file mode 100644 index 0000000000..1165968599 --- /dev/null +++ b/html5/verto/js/package.json @@ -0,0 +1,9 @@ +{ + "name": "verto", + "version": "0.0.1", + "devDependencies": { + "grunt": "~0.4.5", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-watch": "*" + } +} From a80c73940931b453ed7dec3431f65394a095a616 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 3 Jan 2015 09:23:36 +0800 Subject: [PATCH 05/72] FS-7127 #comment follow jshint advices --- html5/verto/js/src/jquery.FSRTC.js | 4 +- html5/verto/js/src/jquery.jsonrpcclient.js | 45 ++++++++++++---------- html5/verto/js/src/jquery.verto.js | 17 ++++---- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index 4635106069..9e973f2f24 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -431,13 +431,13 @@ var iceServers = null; if (options.iceServers) { - var tmp = options.iceServers;; + var tmp = options.iceServers; if (typeof(tmp) === "boolean") { tmp = null; } - if (tmp && typeof(tmp) !== "array") { + if (!(tmp && typeof(tmp) == "object" && tmp.constructor === Array)) { console.warn("iceServers must be an array, reverting to default ice servers"); tmp = null; } diff --git a/html5/verto/js/src/jquery.jsonrpcclient.js b/html5/verto/js/src/jquery.jsonrpcclient.js index 51244e1672..e6000f084f 100644 --- a/html5/verto/js/src/jquery.jsonrpcclient.js +++ b/html5/verto/js/src/jquery.jsonrpcclient.js @@ -247,19 +247,19 @@ } return true; - } + }; $.JsonRpcClient.prototype.closeSocket = function() { if (self.socketReady()) { - this._ws_socket.onclose = function (w) {console.log("Closing Socket")} + this._ws_socket.onclose = function (w) {console.log("Closing Socket");}; this._ws_socket.close(); } - } + }; $.JsonRpcClient.prototype.loginData = function(params) { self.options.login = params.login; self.options.passwd = params.passwd; - } + }; $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { var self = this; @@ -299,10 +299,10 @@ self.ws_cnt++; - if (self.ws_sleep < 3000 && (self.ws_cnt % 10) == 0) { + if (self.ws_sleep < 3000 && (self.ws_cnt % 10) === 0) { self.ws_sleep += 1000; } - } + }; // Set up sending of message for when the socket is open. self._ws_socket.onopen = function() { @@ -317,15 +317,15 @@ var req; // Send the requests. - while (req = $.JsonRpcClient.q.pop()) { + while ((req = $.JsonRpcClient.q.pop())) { self._ws_socket.send(req); } - } + }; } } return self._ws_socket ? true : false; - } + }; $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { // If there is no ws url set, we don't have a socket. @@ -381,9 +381,9 @@ /// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends. - if (typeof response === 'object' - && 'jsonrpc' in response - && response.jsonrpc === '2.0') { + if (typeof response === 'object' && + 'jsonrpc' in response && + response.jsonrpc === '2.0') { /// @todo Handle bad response (without id). @@ -419,8 +419,7 @@ self.authing = true; this.call("login", { login: self.options.login, passwd: self.options.passwd}, - this._ws_callbacks[response.id].request_obj.method == "login" - ? + this._ws_callbacks[response.id].request_obj.method == "login" ? function(e) { self.authing = false; console.log("logged in"); @@ -575,14 +574,18 @@ // Collect all request data and sort handlers by request id. var batch_request = []; var handlers = {}; + var i = 0; + var call; + var success_cb; + var error_cb; // If we have a WebSocket, just send the requests individually like normal calls. var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); if (socket !== null) { - for (var i = 0; i < this._requests.length; i++) { - var call = this._requests[i]; - var success_cb = ('success_cb' in call) ? call.success_cb : undefined; - var error_cb = ('error_cb' in call) ? call.error_cb : undefined; + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + success_cb = ('success_cb' in call) ? call.success_cb : undefined; + error_cb = ('error_cb' in call) ? call.error_cb : undefined; self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); } @@ -590,8 +593,8 @@ return; } - for (var i = 0; i < this._requests.length; i++) { - var call = this._requests[i]; + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; batch_request.push(call.request); // If the request has an id, it should handle returns (otherwise it's a notify). @@ -603,7 +606,7 @@ } } - var success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); }; + success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); }; // No WebSocket, and no HTTP backend? This won't work. if (self.jsonrpcclient.options.ajaxUrl === null) { diff --git a/html5/verto/js/src/jquery.verto.js b/html5/verto/js/src/jquery.verto.js index 4beedc6548..0a55dac2e7 100644 --- a/html5/verto/js/src/jquery.verto.js +++ b/html5/verto/js/src/jquery.verto.js @@ -1137,7 +1137,7 @@ $.verto.confMan = function(verto, params) { var confMan = this; - conf + confMan.params = $.extend({ tableID: null, statusID: null, @@ -1164,9 +1164,8 @@ "" + "" + "" + - "" - - + "

"; + "" + + "

"; jq.html(html); @@ -1260,7 +1259,7 @@ if (confMan.params.mainModID) { genMainMod($(confMan.params.mainModID)); - $(confMan.params.displayID).html("Moderator Controls Ready

") + $(confMan.params.displayID).html("Moderator Controls Ready

"); } else { $(confMan.params.mainModID).html(""); } @@ -1277,7 +1276,7 @@ clearTimeout(confMan.lastTimeout); confMan.lastTimeout = 0; } - confMan.lastTimeout = setTimeout(function() { $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready

")}, 4000); + confMan.lastTimeout = setTimeout(function() { $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready

");}, 4000); } } }); @@ -1349,7 +1348,7 @@ "fnRowCallback": row_callback }); - } + }; $.verto.confMan.prototype.modCommand = function(cmd, id, value) { var confMan = this; @@ -1363,7 +1362,7 @@ "value": value } }); - } + }; $.verto.confMan.prototype.destroy = function() { var confMan = this; @@ -1381,7 +1380,7 @@ if (confMan.params.mainModID) { $(confMan.params.mainModID).html(""); } - } + }; $.verto.dialog = function(direction, verto, params) { var dialog = this; From 7a517eecd81c422bac1809bb4a9e9a316dd3f2ac Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 3 Jan 2015 09:24:25 +0800 Subject: [PATCH 06/72] FS-7127 #comment update README and sync re-generate verto-min --- html5/verto/README | 5 + html5/verto/demo/js/verto-min.js | 3646 ++++++++++++++++++++++++++++-- 2 files changed, 3429 insertions(+), 222 deletions(-) diff --git a/html5/verto/README b/html5/verto/README index c3d81428d3..eff93ea32e 100644 --- a/html5/verto/README +++ b/html5/verto/README @@ -1,3 +1,8 @@ This needs to be fleshed out more. It would be nice to develop a web app here that implements a web phone. Do not base it on the demo because it was just tossed together. + +To run jshint: + + cd js + grunt diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index e871d56386..fa2ffd0398 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -1,223 +1,3425 @@ +/* + * Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH + * Copyright (C) 2005-2014, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * jquery.FSRTC.js - WebRTC Glue code + * + */ -(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} -function findLineInRange(sdpLines,startLine,endLine,prefix,substr){var realEndLine=(endLine!=-1)?endLine:sdpLines.length;for(var i=startLine;i=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}} -var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];} -var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;peer.onicecandidate=function(event){if(event.candidate){options.onICE(event.candidate);}else{if(options.onICEComplete){options.onICEComplete();} -if(options.type=="offer"){if(!moz&&!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i1){return false;} -return true;} -$.JsonRpcClient.prototype.closeSocket=function(){if(self.socketReady()){this._ws_socket.onclose=function(w){console.log("Closing Socket")} -this._ws_socket.close();}} -$.JsonRpcClient.prototype.loginData=function(params){self.options.login=params.login;self.options.passwd=params.passwd;} -$.JsonRpcClient.prototype.connectSocket=function(onmessage_cb){var self=this;if(self.to){clearTimeout(self.to);} -if(!self.socketReady()){self.authing=false;if(self._ws_socket){delete self._ws_socket;} -self._ws_socket=new WebSocket(self.options.socketUrl);if(self._ws_socket){self._ws_socket.onmessage=onmessage_cb;self._ws_socket.onclose=function(w){if(!self.ws_sleep){self.ws_sleep=1000;} -if(self.options.onWSClose){self.options.onWSClose(self);} -console.error("Websocket Lost "+self.ws_cnt+" sleep: "+self.ws_sleep+"msec");self.to=setTimeout(function(){console.log("Attempting Reconnection....");self.connectSocket(onmessage_cb);},self.ws_sleep);self.ws_cnt++;if(self.ws_sleep<3000&&(self.ws_cnt%10)==0){self.ws_sleep+=1000;}} -self._ws_socket.onopen=function(){if(self.to){clearTimeout(self.to);} -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},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={};} -var reply=this.options.onmessage(event);if(reply&&typeof reply==="object"&&event.eventData.id){var msg={jsonrpc:"2.0",id:event.eventData.id,result:reply};var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send($.toJSON(msg));}}}};$.JsonRpcClient._batchObject=function(jsonrpcclient,all_done_cb,error_cb){this._requests=[];this.jsonrpcclient=jsonrpcclient;this.all_done_cb=all_done_cb;this.error_cb=typeof error_cb==='function'?error_cb:function(){};};$.JsonRpcClient._batchObject.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};} -if(this.options.sessid){params.sessid=this.options.sessid;} -if(!success_cb){success_cb=function(e){console.log("Success: ",e);};} -if(!error_cb){error_cb=function(e){console.log("Error: ",e);};} -this._requests.push({request:{jsonrpc:'2.0',method:method,params:params,id:this.jsonrpcclient._current_id++},success_cb:success_cb,error_cb:error_cb});};$.JsonRpcClient._batchObject.prototype.notify=function(method,params){if(this.options.sessid){params.sessid=this.options.sessid;} -this._requests.push({request:{jsonrpc:'2.0',method:method,params:params}});};$.JsonRpcClient._batchObject.prototype._execute=function(){var self=this;if(this._requests.length===0)return;var batch_request=[];var handlers={};var socket=self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage);if(socket!==null){for(var i=0;i0){data.params.useVideo=true;} -if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;} -dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);dialog.setState($.verto.enum.state.recovering);break;case'verto.invite':if(data.params.sdp&&data.params.sdp.indexOf("m=video")>0){data.params.wantVideo=true;} -if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;} -dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);break;default:console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED");break;}} -return{method:data.method};}else{switch(data.method){case'verto.event':var list=null;var key=null;if(data.params){key=data.params.eventChannel;} -if(key){list=verto.eventSUBS[key];if(!list){list=verto.eventSUBS[key.split(".")[0]];}} -if(!list&&key&&key===verto.sessid){if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.pvtEvent,data.params);}}else if(!list&&key&&verto.dialogs[key]){verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent,data.params);}else if(!list){if(!key){key="UNDEFINED";} -console.error("UNSUBBED or invalid EVENT "+key+" IGNORED");}else{for(var i in list){var sub=list[i];if(!sub||!sub.ready){console.error("invalid EVENT for "+key+" IGNORED");}else if(sub.handler){sub.handler(verto,data.params,sub.userData);}else if(verto.callbacks.onEvent){verto.callbacks.onEvent(verto,data.params,sub.userData);}else{console.log("EVENT:",data.params);}}} -break;case"verto.info":if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.info,data.params.msg);} -console.debug("MESSAGE from: "+data.params.msg.from,data.params.msg.body);break;default:console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED",data.method);break;}}};var del_array=function(array,name){var r=[];var len=array.length;for(var i=0;i=array.length){array.push(name);}else{var x=0;var n=[];var len=array.length;for(var i=0;i":"\n");});return str;};};$.verto.liveArray=function(verto,context,name,config){var la=this;var lastSerno=0;var binding=null;var user_obj=config.userObj;var local=false;hashArray.call(la);la._add=la.add;la._del=la.del;la._reorder=la.reorder;la._clear=la.clear;la.context=context;la.name=name;la.user_obj=user_obj;la.verto=verto;la.broadcast=function(channel,obj){verto.broadcast(channel,obj);};la.errs=0;la.clear=function(){la._clear();lastSerno=0;if(la.onChange){la.onChange(la,{action:"clear"});}};la.checkSerno=function(serno){if(serno<0){return true;} -if(lastSerno>0&&serno!=(lastSerno+1)){if(la.onErr){la.onErr(la,{lastSerno:lastSerno,serno:serno});} -la.errs++;console.debug(la.errs);if(la.errs<3){la.bootstrap(la.user_obj);} -return false;}else{lastSerno=serno;return true;}};la.reorder=function(serno,a){if(la.checkSerno(serno)){la._reorder(a);if(la.onChange){la.onChange(la,{serno:serno,action:"reorder"});}}};la.init=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} -if(la.checkSerno(serno)){if(la.onChange){la.onChange(la,{serno:serno,action:"init",index:index,key:key,data:val});}}};la.bootObj=function(serno,val){if(la.checkSerno(serno)){for(var i in val){la._add(val[i][0],val[i][1]);} -if(la.onChange){la.onChange(la,{serno:serno,action:"bootObj",data:val,redraw:true});}}};la.add=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} -if(la.checkSerno(serno)){var redraw=la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"add",index:index,key:key,data:val,redraw:redraw});}}};la.modify=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} -if(la.checkSerno(serno)){la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"modify",key:key,data:val,index:index});}}};la.del=function(serno,key,index){if(key===null||key===undefined){key=serno;} -if(la.checkSerno(serno)){if(index===null||index<0||index===undefined){index=la.indexOf(key);} -var ok=la._del(key);if(ok&&la.onChange){la.onChange(la,{serno:serno,action:"del",key:key,index:index});}}};var eventHandler=function(v,e,la){var packet=e.data;if(packet.name!=la.name){return;} -switch(packet.action){case"init":la.init(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"bootObj":la.bootObj(packet.wireSerno,packet.data);break;case"add":la.add(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"modify":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.modify(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);} -break;case"del":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.del(packet.wireSerno,packet.hashKey,packet.arrIndex);} -break;case"clear":la.clear();break;case"reorder":la.reorder(packet.wireSerno,packet.order);break;default:if(la.checkSerno(packet.wireSerno)){if(la.onChange){la.onChange(la,{serno:packet.wireSerno,action:packet.action,data:packet.data});}} -break;}};if(la.context){binding=la.verto.subscribe(la.context,{handler:eventHandler,userData:la,subParams:config.subParams});} -la.destroy=function(){la._clear();la.verto.unsubscribe(binding);};la.sendCommand=function(cmd,obj){var self=la;self.broadcast(self.context,{liveArray:{command:cmd,context:self.context,name:self.name,obj:obj}});};la.bootstrap=function(obj){var self=la;la.sendCommand("bootstrap",obj);};la.changepage=function(obj){var self=la;self.clear();self.broadcast(self.context,{liveArray:{command:"changepage",context:la.context,name:la.name,obj:obj}});};la.heartbeat=function(obj){var self=la;var callback=function(){self.heartbeat.call(self,obj);};self.broadcast(self.context,{liveArray:{command:"heartbeat",context:self.context,name:self.name,obj:obj}});self.hb_pid=setTimeout(callback,30000);};la.bootstrap(la.user_obj);};$.verto.liveTable=function(verto,context,name,jq,config){var dt;var la=new $.verto.liveArray(verto,context,name,{subParams:config.subParams});var lt=this;lt.liveArray=la;lt.dataTable=dt;lt.verto=verto;lt.destroy=function(){if(dt){dt.fnDestroy();} -if(la){la.destroy();} -dt=null;la=null;};la.onErr=function(obj,args){console.error("Error: ",obj,args);};la.onChange=function(obj,args){var index=0;var iserr=0;if(!dt){if(!config.aoColumns){if(args.action!="init"){return;} -config.aoColumns=[];for(var i in args.data){config.aoColumns.push({"sTitle":args.data[i]});}} -dt=jq.dataTable(config);} -if(dt&&(args.action=="del"||args.action=="modify")){index=args.index;if(index===undefined&&args.key){index=la.indexOf(args.key);} -if(index===undefined){console.error("INVALID PACKET Missing INDEX\n",args);return;}} -if(config.onChange){config.onChange(obj,args);} -try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data");return;} -dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} -if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);} -dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;} -dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} -if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.confMan=function(verto,params){var confMan=this;conf -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++;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="

"+""+""+""+"" -+"

";jq.html(html);$("#"+play_id).click(function(){var file=prompt("Please enter file name","");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","");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 tmute_id="tmute_"+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="
"+""+""+""+""+""+"
";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");confMan.modCommand("transfer",x,xten);});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});$("#"+volup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_in",x,"down");});return html;} -var atitle="";var awidth=0;if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=200;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready

")}else{$(confMan.params.mainModID).html("");} -verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){console.error("MODDATA:",e.data);if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);} -if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"

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

")},4000);}}});} -var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};} -confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID"},{"sTitle":"Number"},{"sTitle":"Name"},{"sTitle":"Codec"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"300px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1000,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});} -$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.sendMethod("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});} -$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} -if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);} -if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}} -$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,tag:verto.options.tag,login:verto.options.login},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} -if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}} -dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;} -if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="Nobody";} -if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";} -RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;} -RTCcallbacks.onICESDP=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.SDP);dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup();};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,useVideo:dialog.videoStream,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:verto.options.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;} -obj.dialogParams[i]=dialog.params[i];} -dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;} -return false;} -$.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.info("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.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];dialog.rtc.stop();break;} -return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} -break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} -break;case"verto.bye":dialog.hangup();break;case"verto.modify":if(e.holdState){if(e.holdState=="held"){if(dialog.state!=$.verto.enum.state.held){dialog.setState($.verto.enum.state.held);}}else if(e.holdState=="active"){if(dialog.state!=$.verto.enum.state.active){dialog.setState($.verto.enum.state.active);}}} -if(success){} -break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;} -if(params.cause){dialog.cause=params.cause;}} -if(dialog.state.val>$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;} -dialog.rtc.useVideo(dialog.videoStream);};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){cur_call.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;} -if(!msg.body){console.error("Missing Body");err++;} -if(err){return false;} -dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(params){if(params.useVideo){dialog.useVideo(true);} -dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;} -dialog.rtc.createAnswer(dialog.params.sdp);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;} -if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+"Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+"Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} -if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;} -dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;} -dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.logout();verto.purge();}} -return $.verto.warnOnUnload;});})(jQuery); \ No newline at end of file +(function($) { + + // Find the line in sdpLines that starts with |prefix|, and, if specified, + // contains |substr| (case-insensitive search). + function findLine(sdpLines, prefix, substr) { + return findLineInRange(sdpLines, 0, -1, prefix, substr); + } + + // Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix| + // and, if specified, contains |substr| (case-insensitive search). + function findLineInRange(sdpLines, startLine, endLine, prefix, substr) { + var realEndLine = (endLine != -1) ? endLine : sdpLines.length; + for (var i = startLine; i < realEndLine; ++i) { + if (sdpLines[i].indexOf(prefix) === 0) { + if (!substr || sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) { + return i; + } + } + } + return null; + } + + // Gets the codec payload type from an a=rtpmap:X line. + function getCodecPayloadType(sdpLine) { + var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); + var result = sdpLine.match(pattern); + return (result && result.length == 2) ? result[1] : null; + } + + // Returns a new m= line with the specified codec as the first one. + function setDefaultCodec(mLine, payload) { + var elements = mLine.split(' '); + var newLine = []; + var index = 0; + for (var i = 0; i < elements.length; i++) { + if (index === 3) { // Format of media starts from the fourth. + newLine[index++] = payload; // Put target payload to the first. + } + if (elements[i] !== payload) newLine[index++] = elements[i]; + } + return newLine.join(' '); + } + + $.FSRTC = function(options) { + this.options = $.extend({ + useVideo: null, + useStereo: false, + userData: null, + iceServers: false, + videoParams: {}, + audioParams: {}, + callbacks: { + onICEComplete: function() {}, + onICE: function() {}, + onOfferSDP: function() {} + } + }, options); + + this.mediaData = { + SDP: null, + profile: {}, + candidateList: [] + }; + + this.constraints = { + optional: [{ + 'DtlsSrtpKeyAgreement': 'true' + }], + mandatory: { + OfferToReceiveAudio: true, + OfferToReceiveVideo: this.options.useVideo ? true : false, + } + }; + + if (self.options.useVideo) { + self.options.useVideo.style.display = 'none'; + } + + setCompat(); + checkCompat(); + }; + + $.FSRTC.prototype.useVideo = function(obj) { + var self = this; + + if (obj) { + self.options.useVideo = obj; + self.constraints.mandatory.OfferToReceiveVideo = true; + } else { + self.options.useVideo = null; + self.constraints.mandatory.OfferToReceiveVideo = false; + } + + if (self.options.useVideo) { + self.options.useVideo.style.display = 'none'; + } + }; + + $.FSRTC.prototype.useStereo = function(on) { + var self = this; + self.options.useStereo = on; + }; + + // Sets Opus in stereo if stereo is enabled, by adding the stereo=1 fmtp param. + $.FSRTC.prototype.stereoHack = function(sdp) { + var self = this; + + if (!self.options.useStereo) { + return sdp; + } + + var sdpLines = sdp.split('\r\n'); + + // Find opus payload. + var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000'), + opusPayload; + if (opusIndex) { + opusPayload = getCodecPayloadType(sdpLines[opusIndex]); + } + + // Find the payload in fmtp line. + var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString()); + if (fmtpLineIndex === null) return sdp; + + // Append stereo=1 to fmtp line. + sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; stereo=1'); + + sdp = sdpLines.join('\r\n'); + return sdp; + }; + + function setCompat() { + $.FSRTC.moz = !!navigator.mozGetUserMedia; + //navigator.getUserMedia || (navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia); + if (!navigator.getUserMedia) { + navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia; + } + } + + function checkCompat() { + if (!navigator.getUserMedia) { + alert('This application cannot function in this browser.'); + return false; + } + return true; + } + + function onStreamError(self) { + console.log('There has been a problem retrieving the streams - did you allow access?'); + + } + + function onStreamSuccess(self) { + console.log("Stream Success"); + } + + function onICE(self, candidate) { + self.mediaData.candidate = candidate; + self.mediaData.candidateList.push(self.mediaData.candidate); + + doCallback(self, "onICE"); + } + + function doCallback(self, func, arg) { + if (func in self.options.callbacks) { + self.options.callbacks[func](self, arg); + } + } + + function onICEComplete(self, candidate) { + console.log("ICE Complete"); + doCallback(self, "onICEComplete"); + } + + function onChannelError(self, e) { + console.error("Channel Error", e); + doCallback(self, "onError", e); + } + + function onICESDP(self, sdp) { + self.mediaData.SDP = self.stereoHack(sdp.sdp); + console.log("ICE SDP"); + doCallback(self, "onICESDP"); + } + + function onAnswerSDP(self, sdp) { + self.answer.SDP = self.stereoHack(sdp.sdp); + console.log("ICE ANSWER SDP"); + doCallback(self, "onAnswerSDP", self.answer.SDP); + } + + function onMessage(self, msg) { + console.log("Message"); + doCallback(self, "onICESDP", msg); + } + + function onRemoteStream(self, stream) { + if (self.options.useVideo) { + self.options.useVideo.style.display = 'block'; + } + + var element = self.options.useAudio; + console.log("REMOTE STREAM", stream, element); + + if (typeof element.srcObject !== 'undefined') { + element.srcObject = stream; + } else if (typeof element.mozSrcObject !== 'undefined') { + element.mozSrcObject = stream; + } else if (typeof element.src !== 'undefined') { + element.src = URL.createObjectURL(stream); + } else { + console.error('Error attaching stream to element.'); + } + + self.options.useAudio.play(); + self.remoteStream = stream; + } + + function onOfferSDP(self, sdp) { + self.mediaData.SDP = self.stereoHack(sdp.sdp); + console.log("Offer SDP"); + doCallback(self, "onOfferSDP"); + } + + $.FSRTC.prototype.answer = function(sdp, onSuccess, onError) { + this.peer.addAnswerSDP({ + type: "answer", + sdp: sdp + }, + onSuccess, onError); + }; + + $.FSRTC.prototype.stop = function() { + var self = this; + + if (self.options.useVideo) { + self.options.useVideo.style.display = 'none'; + } + + if (self.localStream) { + self.localStream.stop(); + self.localStream = null; + } + + if (self.peer) { + console.log("stopping peer"); + self.peer.stop(); + } + }; + + $.FSRTC.prototype.createAnswer = function(sdp) { + var self = this; + self.type = "answer"; + self.remoteSDP = sdp; + console.debug("inbound sdp: ", sdp); + + function onSuccess(stream) { + self.localStream = stream; + + self.peer = RTCPeerConnection({ + type: self.type, + attachStream: self.localStream, + onICE: function(candidate) { + return onICE(self, candidate); + }, + onICEComplete: function() { + return onICEComplete(self); + }, + onRemoteStream: function(stream) { + return onRemoteStream(self, stream); + }, + onICESDP: function(sdp) { + return onICESDP(self, sdp); + }, + onChannelError: function(e) { + return onChannelError(self, e); + }, + constraints: self.constraints, + iceServers: self.options.iceServers, + offerSDP: { + type: "offer", + sdp: self.remoteSDP + } + }); + + onStreamSuccess(self); + } + + function onError() { + onStreamError(self); + } + + getUserMedia({ + constraints: { + audio: { + mandatory: this.options.audioParams, + optional: [] + }, + video: this.options.useVideo ? { + mandatory: this.options.videoParams, + optional: [] + } : null + }, + video: this.options.useVideo ? true : false, + onsuccess: onSuccess, + onerror: onError + }); + + }; + + $.FSRTC.prototype.call = function(profile) { + checkCompat(); + + var self = this; + + self.type = "offer"; + + function onSuccess(stream) { + self.localStream = stream; + + self.peer = RTCPeerConnection({ + type: self.type, + attachStream: self.localStream, + onICE: function(candidate) { + return onICE(self, candidate); + }, + onICEComplete: function() { + return onICEComplete(self); + }, + onRemoteStream: function(stream) { + return onRemoteStream(self, stream); + }, + onOfferSDP: function(sdp) { + return onOfferSDP(self, sdp); + }, + onICESDP: function(sdp) { + return onICESDP(self, sdp); + }, + onChannelError: function(e) { + return onChannelError(self, e); + }, + constraints: self.constraints, + iceServers: self.options.iceServers, + }); + + onStreamSuccess(self); + } + + function onError() { + onStreamError(self); + } + + getUserMedia({ + constraints: { + audio: { + mandatory: this.options.audioParams, + optional: [] + }, + video: this.options.useVideo ? { + mandatory: this.options.videoParams, + optional: [] + } : null + }, + video: this.options.useVideo ? true : false, + onsuccess: onSuccess, + onerror: onError + }); + + /* + navigator.getUserMedia({ + video: this.options.useVideo, + audio: true + }, onSuccess, onError); + */ + + }; + + // DERIVED from RTCPeerConnection-v1.5 + // 2013, @muazkh - github.com/muaz-khan + // MIT License - https://www.webrtc-experiment.com/licence/ + // Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RTCPeerConnection + window.moz = !!navigator.mozGetUserMedia; + + function RTCPeerConnection(options) { + + var w = window, + PeerConnection = w.mozRTCPeerConnection || w.webkitRTCPeerConnection, + SessionDescription = w.mozRTCSessionDescription || w.RTCSessionDescription, + IceCandidate = w.mozRTCIceCandidate || w.RTCIceCandidate; + + var STUN = { + url: !moz ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121' + }; + + var TURN = { + url: 'turn:homeo@turn.bistri.com:80', + credential: 'homeo' + }; + + var iceServers = null; + + if (options.iceServers) { + var tmp = options.iceServers; + + if (typeof(tmp) === "boolean") { + tmp = null; + } + + if (!(tmp && typeof(tmp) == "object" && tmp.constructor === Array)) { + console.warn("iceServers must be an array, reverting to default ice servers"); + tmp = null; + } + + iceServers = { + iceServers: tmp || [STUN] + }; + + if (!moz && !tmp) { + if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28) TURN = { + url: 'turn:turn.bistri.com:80', + credential: 'homeo', + username: 'homeo' + }; + + iceServers.iceServers = [STUN]; + } + } + + var optional = { + optional: [] + }; + + if (!moz) { + optional.optional = [{ + DtlsSrtpKeyAgreement: true + }, + { + RtpDataChannels: options.onChannelMessage ? true : false + }]; + } + + var peer = new PeerConnection(iceServers, optional); + + openOffererChannel(); + var x = 0; + + peer.onicecandidate = function(event) { + if (event.candidate) { + options.onICE(event.candidate); + } else { + if (options.onICEComplete) { + options.onICEComplete(); + } + + if (options.type == "offer") { + if (!moz && !x && options.onICESDP) { + options.onICESDP(peer.localDescription); + //x = 1; + /* + x = 1; + peer.createOffer(function(sessionDescription) { + sessionDescription.sdp = serializeSdp(sessionDescription.sdp); + peer.setLocalDescription(sessionDescription); + if (options.onICESDP) { + options.onICESDP(sessionDescription); + } + }, onSdpError, constraints); + */ + } + } else { + if (!x && options.onICESDP) { + options.onICESDP(peer.localDescription); + //x = 1; + /* + x = 1; + peer.createAnswer(function(sessionDescription) { + sessionDescription.sdp = serializeSdp(sessionDescription.sdp); + peer.setLocalDescription(sessionDescription); + if (options.onICESDP) { + options.onICESDP(sessionDescription); + } + }, onSdpError, constraints); + */ + } + } + } + }; + + // attachStream = MediaStream; + if (options.attachStream) peer.addStream(options.attachStream); + + // attachStreams[0] = audio-stream; + // attachStreams[1] = video-stream; + // attachStreams[2] = screen-capturing-stream; + if (options.attachStreams && options.attachStream.length) { + var streams = options.attachStreams; + for (var i = 0; i < streams.length; i++) { + peer.addStream(streams[i]); + } + } + + peer.onaddstream = function(event) { + var remoteMediaStream = event.stream; + + // onRemoteStreamEnded(MediaStream) + remoteMediaStream.onended = function() { + if (options.onRemoteStreamEnded) options.onRemoteStreamEnded(remoteMediaStream); + }; + + // onRemoteStream(MediaStream) + if (options.onRemoteStream) options.onRemoteStream(remoteMediaStream); + + //console.debug('on:add:stream', remoteMediaStream); + }; + + var constraints = options.constraints || { + optional: [], + mandatory: { + OfferToReceiveAudio: true, + OfferToReceiveVideo: true + } + }; + + // onOfferSDP(RTCSessionDescription) + function createOffer() { + if (!options.onOfferSDP) return; + + peer.createOffer(function(sessionDescription) { + sessionDescription.sdp = serializeSdp(sessionDescription.sdp); + peer.setLocalDescription(sessionDescription); + options.onOfferSDP(sessionDescription); + if (moz && options.onICESDP) { + options.onICESDP(sessionDescription); + } + }, + onSdpError, constraints); + } + + // onAnswerSDP(RTCSessionDescription) + function createAnswer() { + if (options.type != "answer") return; + + //options.offerSDP.sdp = addStereo(options.offerSDP.sdp); + peer.setRemoteDescription(new SessionDescription(options.offerSDP), onSdpSuccess, onSdpError); + peer.createAnswer(function(sessionDescription) { + sessionDescription.sdp = serializeSdp(sessionDescription.sdp); + peer.setLocalDescription(sessionDescription); + if (options.onAnswerSDP) { + options.onAnswerSDP(sessionDescription); + } + }, + onSdpError, constraints); + } + + // if Mozilla Firefox & DataChannel; offer/answer will be created later + if ((options.onChannelMessage && !moz) || !options.onChannelMessage) { + createOffer(); + createAnswer(); + } + + // DataChannel Bandwidth + function setBandwidth(sdp) { + // remove existing bandwidth lines + sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, ''); + sdp = sdp.replace(/a=mid:data\r\n/g, 'a=mid:data\r\nb=AS:1638400\r\n'); + + return sdp; + } + + // old: FF<>Chrome interoperability management + function getInteropSDP(sdp) { + var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), + extractedChars = ''; + + function getChars() { + extractedChars += chars[parseInt(Math.random() * 40)] || ''; + if (extractedChars.length < 40) getChars(); + + return extractedChars; + } + + // usually audio-only streaming failure occurs out of audio-specific crypto line + // a=crypto:1 AES_CM_128_HMAC_SHA1_32 --------- kAttributeCryptoVoice + if (options.onAnswerSDP) sdp = sdp.replace(/(a=crypto:0 AES_CM_128_HMAC_SHA1_32)(.*?)(\r\n)/g, ''); + + // video-specific crypto line i.e. SHA1_80 + // a=crypto:1 AES_CM_128_HMAC_SHA1_80 --------- kAttributeCryptoVideo + var inline = getChars() + '\r\n' + (extractedChars = ''); + sdp = sdp.indexOf('a=crypto') == -1 ? sdp.replace(/c=IN/g, 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:' + inline + 'c=IN') : sdp; + + return sdp; + } + + function serializeSdp(sdp) { + //if (!moz) sdp = setBandwidth(sdp); + //sdp = getInteropSDP(sdp); + //console.debug(sdp); + return sdp; + } + + // DataChannel management + var channel; + + function openOffererChannel() { + if (!options.onChannelMessage || (moz && !options.onOfferSDP)) return; + + _openOffererChannel(); + + if (!moz) return; + navigator.mozGetUserMedia({ + audio: true, + fake: true + }, + function(stream) { + peer.addStream(stream); + createOffer(); + }, + useless); + } + + function _openOffererChannel() { + channel = peer.createDataChannel(options.channel || 'RTCDataChannel', moz ? {} : { + reliable: false + }); + + if (moz) channel.binaryType = 'blob'; + + setChannelEvents(); + } + + function setChannelEvents() { + channel.onmessage = function(event) { + if (options.onChannelMessage) options.onChannelMessage(event); + }; + + channel.onopen = function() { + if (options.onChannelOpened) options.onChannelOpened(channel); + }; + channel.onclose = function(event) { + if (options.onChannelClosed) options.onChannelClosed(event); + + console.warn('WebRTC DataChannel closed', event); + }; + channel.onerror = function(event) { + if (options.onChannelError) options.onChannelError(event); + + console.error('WebRTC DataChannel error', event); + }; + } + + if (options.onAnswerSDP && moz && options.onChannelMessage) openAnswererChannel(); + + function openAnswererChannel() { + peer.ondatachannel = function(event) { + channel = event.channel; + channel.binaryType = 'blob'; + setChannelEvents(); + }; + + if (!moz) return; + navigator.mozGetUserMedia({ + audio: true, + fake: true + }, + function(stream) { + peer.addStream(stream); + createAnswer(); + }, + useless); + } + + // fake:true is also available on chrome under a flag! + function useless() { + log('Error in fake:true'); + } + + function onSdpSuccess() {} + + function onSdpError(e) { + if (options.onChannelError) { + options.onChannelError(e); + } + console.error('sdp error:', e); + } + + return { + addAnswerSDP: function(sdp, cbSuccess, cbError) { + + peer.setRemoteDescription(new SessionDescription(sdp), cbSuccess ? cbSuccess : onSdpSuccess, cbError ? cbError : onSdpError); + }, + addICE: function(candidate) { + peer.addIceCandidate(new IceCandidate({ + sdpMLineIndex: candidate.sdpMLineIndex, + candidate: candidate.candidate + })); + }, + + peer: peer, + channel: channel, + sendData: function(message) { + if (channel) { + channel.send(message); + } + }, + + stop: function() { + peer.close(); + if (options.attachStream) { + options.attachStream.stop(); + } + } + + }; + } + + // getUserMedia + var video_constraints = { + mandatory: {}, + optional: [] + }; + + function getUserMedia(options) { + var n = navigator, + media; + n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia; + n.getMedia(options.constraints || { + audio: true, + video: video_constraints + }, + streaming, options.onerror || + function(e) { + console.error(e); + }); + + function streaming(stream) { + var video = options.video; + if (video) { + video[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream); + //video.play(); + } + if (options.onsuccess) { + options.onsuccess(stream); + } + media = stream; + } + + return media; + } + +})(jQuery); +/* + * Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH + * Copyright (C) 2005-2014, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is jquery.jsonrpclient.js modified for Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH + * + * The Initial Developer of the Original Code is + * Textalk AB http://textalk.se/ + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * jquery.jsonrpclient.js - JSON RPC client code + * + */ +/** + * This plugin requires jquery.json.js to be available, or at least the methods $.toJSON and + * $.parseJSON. + * + * The plan is to make use of websockets if they are available, but work just as well with only + * http if not. + * + * Usage example: + * + * var foo = new $.JsonRpcClient({ ajaxUrl: '/backend/jsonrpc' }); + * foo.call( + * 'bar', [ 'A parameter', 'B parameter' ], + * function(result) { alert('Foo bar answered: ' + result.my_answer); }, + * function(error) { console.log('There was an error', error); } + * ); + * + * More examples are available in README.md + */ +(function($) { + /** + * @fn new + * @memberof $.JsonRpcClient + * + * @param options An object stating the backends: + * ajaxUrl A url (relative or absolute) to a http(s) backend. + * socketUrl A url (relative of absolute) to a ws(s) backend. + * onmessage A socket message handler for other messages (non-responses). + * getSocket A function returning a WebSocket or null. + * It must take an onmessage_cb and bind it to the onmessage event + * (or chain it before/after some other onmessage handler). + * Or, it could return null if no socket is available. + * The returned instance must have readyState <= 1, and if less than 1, + * react to onopen binding. + */ + $.JsonRpcClient = function(options) { + var self = this; + this.options = $.extend({ + ajaxUrl : null, + socketUrl : null, ///< The ws-url for default getSocket. + onmessage : null, ///< Other onmessage-handler. + login : null, /// auth login + passwd : null, /// auth passwd + sessid : null, + getSocket : function(onmessage_cb) { return self._getSocket(onmessage_cb); } + }, options); + + self.ws_cnt = 0; + + // Declare an instance version of the onmessage callback to wrap 'this'. + this.wsOnMessage = function(event) { self._wsOnMessage(event); }; + }; + + /// Holding the WebSocket on default getsocket. + $.JsonRpcClient.prototype._ws_socket = null; + + /// Object : { success_cb: cb, error_cb: cb } + $.JsonRpcClient.prototype._ws_callbacks = {}; + + /// The next JSON-RPC request id. + $.JsonRpcClient.prototype._current_id = 1; + + /** + * @fn call + * @memberof $.JsonRpcClient + * + * @param method The method to run on JSON-RPC server. + * @param params The params; an array or object. + * @param success_cb A callback for successful request. + * @param error_cb A callback for error. + */ + $.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) { + // Construct the JSON-RPC 2.0 request. + + 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++ // Increase the id counter to match request/response + }; + + if (!success_cb) { + success_cb = function(e){console.log("Success: ", e);}; + } + + if (!error_cb) { + error_cb = function(e){console.log("Error: ", e);}; + } + + // Try making a WebSocket call. + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request, success_cb, error_cb); + return; + } + + // No WebSocket, and no HTTP backend? This won't work. + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.call used with no websocket and no http endpoint."; + } + + $.ajax({ + type : 'POST', + url : this.options.ajaxUrl, + data : $.toJSON(request), + dataType : 'json', + cache : false, + + success : function(data) { + if ('error' in data) error_cb(data.error, this); + success_cb(data.result, this); + }, + + // JSON-RPC Server could return non-200 on error + error : function(jqXHR, textStatus, errorThrown) { + try { + var response = $.parseJSON(jqXHR.responseText); + + if ('console' in window) console.log(response); + + error_cb(response.error, this); + } catch (err) { + // Perhaps the responseText wasn't really a jsonrpc-error. + error_cb({ error: jqXHR.responseText }, this); + } + } + }); + }; + + /** + * Notify sends a command to the server that won't need a response. In http, there is probably + * an empty response - that will be dropped, but in ws there should be no response at all. + * + * This is very similar to call, but has no id and no handling of callbacks. + * + * @fn notify + * @memberof $.JsonRpcClient + * + * @param method The method to run on JSON-RPC server. + * @param params The params; an array or object. + */ + $.JsonRpcClient.prototype.notify = function(method, params) { + // Construct the JSON-RPC 2.0 request. + + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + + var request = { + jsonrpc: '2.0', + method: method, + params: params + }; + + // Try making a WebSocket call. + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request); + return; + } + + // No WebSocket, and no HTTP backend? This won't work. + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.notify used with no websocket and no http endpoint."; + } + + $.ajax({ + type : 'POST', + url : this.options.ajaxUrl, + data : $.toJSON(request), + dataType : 'json', + cache : false + }); + }; + + /** + * Make a batch-call by using a callback. + * + * The callback will get an object "batch" as only argument. On batch, you can call the methods + * "call" and "notify" just as if it was a normal $.JsonRpcClient object, and all calls will be + * sent as a batch call then the callback is done. + * + * @fn batch + * @memberof $.JsonRpcClient + * + * @param callback The main function which will get a batch handler to run call and notify on. + * @param all_done_cb A callback function to call after all results have been handled. + * @param error_cb A callback function to call if there is an error from the server. + * Note, that batch calls should always get an overall success, and the + * only error + */ + $.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) { + var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb); + callback(batch); + batch._execute(); + }; + + /** + * The default getSocket handler. + * + * @param onmessage_cb The callback to be bound to onmessage events on the socket. + * + * @fn _getSocket + * @memberof $.JsonRpcClient + */ + + $.JsonRpcClient.prototype.socketReady = function() { + if (this._ws_socket === null || this._ws_socket.readyState > 1) { + return false; + } + + return true; + }; + + $.JsonRpcClient.prototype.closeSocket = function() { + if (self.socketReady()) { + this._ws_socket.onclose = function (w) {console.log("Closing Socket");}; + this._ws_socket.close(); + } + }; + + $.JsonRpcClient.prototype.loginData = function(params) { + self.options.login = params.login; + self.options.passwd = params.passwd; + }; + + $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { + var self = this; + + if (self.to) { + clearTimeout(self.to); + } + + if (!self.socketReady()) { + self.authing = false; + + if (self._ws_socket) { + delete self._ws_socket; + } + + // No socket, or dying socket, let's get a new one. + self._ws_socket = new WebSocket(self.options.socketUrl); + + if (self._ws_socket) { + // Set up onmessage handler. + self._ws_socket.onmessage = onmessage_cb; + self._ws_socket.onclose = function (w) { + if (!self.ws_sleep) { + self.ws_sleep = 1000; + } + + if (self.options.onWSClose) { + self.options.onWSClose(self); + } + + console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec"); + + self.to = setTimeout(function() { + console.log("Attempting Reconnection...."); + self.connectSocket(onmessage_cb); + }, self.ws_sleep); + + self.ws_cnt++; + + if (self.ws_sleep < 3000 && (self.ws_cnt % 10) === 0) { + self.ws_sleep += 1000; + } + }; + + // Set up sending of message for when the socket is open. + self._ws_socket.onopen = function() { + if (self.to) { + clearTimeout(self.to); + } + self.ws_sleep = 1000; + self.ws_cnt = 0; + if (self.options.onWSConnect) { + self.options.onWSConnect(self); + } + + var req; + // Send the requests. + while ((req = $.JsonRpcClient.q.pop())) { + self._ws_socket.send(req); + } + }; + } + } + + return self._ws_socket ? true : false; + }; + + $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { + // If there is no ws url set, we don't have a socket. + // Likewise, if there is no window.WebSocket. + if (this.options.socketUrl === null || !("WebSocket" in window)) return null; + + this.connectSocket(onmessage_cb); + + return this._ws_socket; + }; + + /** + * Queue to save messages delivered when websocket is not ready + */ + $.JsonRpcClient.q = []; + + /** + * Internal handler to dispatch a JRON-RPC request through a websocket. + * + * @fn _wsCall + * @memberof $.JsonRpcClient + */ + $.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) { + var request_json = $.toJSON(request); + + if (socket.readyState < 1) { + // The websocket is not open yet; we have to set sending of the message in onopen. + self = this; // In closure below, this is set to the WebSocket. Use self instead. + $.JsonRpcClient.q.push(request_json); + } else { + // We have a socket and it should be ready to send on. + socket.send(request_json); + } + + // Setup callbacks. If there is an id, this is a call and not a notify. + 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 }; + } + }; + + /** + * Internal handler for the websocket messages. It determines if the message is a JSON-RPC + * response, and if so, tries to couple it with a given callback. Otherwise, it falls back to + * given external onmessage-handler, if any. + * + * @param event The websocket onmessage-event. + */ + $.JsonRpcClient.prototype._wsOnMessage = function(event) { + // Check if this could be a JSON RPC message. + var response; + try { + response = $.parseJSON(event.data); + + /// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends. + + if (typeof response === 'object' && + 'jsonrpc' in response && + response.jsonrpc === '2.0') { + + /// @todo Handle bad response (without id). + + // If this is an object with result, it is a response. + if ('result' in response && this._ws_callbacks[response.id]) { + // Get the success callback. + var success_cb = this._ws_callbacks[response.id].success_cb; + + /* + // set the sessid if present + if ('sessid' in response.result && !this.options.sessid || (this.options.sessid != response.result.sessid)) { + this.options.sessid = response.result.sessid; + if (this.options.sessid) { + console.log("setting session UUID to: " + this.options.sessid); + } + } + */ + // Delete the callback from the storage. + delete this._ws_callbacks[response.id]; + + // Run callback with result as parameter. + success_cb(response.result, this); + return; + } else if ('error' in response && this._ws_callbacks[response.id]) { + // If this is an object with error, it is an error response. + + // Get the error callback. + var error_cb = this._ws_callbacks[response.id].error_cb; + var orig_req = this._ws_callbacks[response.id].request; + + // if this is an auth request, send the credentials and resend the failed 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}, + 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 the callback from the storage. + delete this._ws_callbacks[response.id]; + + // Run callback with the error object as parameter. + error_cb(response.error, this); + return; + } + } + } catch (err) { + // Probably an error while parsing a non json-string as json. All real JSON-RPC cases are + // handled above, and the fallback method is called below. + console.log("ERROR: "+ err); + return; + } + + // This is not a JSON-RPC response. Call the fallback message handler, if given. + if (typeof this.options.onmessage === 'function') { + event.eventData = response; + if (!event.eventData) { + event.eventData = {}; + } + + var reply = this.options.onmessage(event); + + if (reply && typeof reply === "object" && event.eventData.id) { + var msg = { + jsonrpc: "2.0", + id: event.eventData.id, + result: reply + }; + + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send($.toJSON(msg)); + } + } + } + }; + + + /************************************************************************************************ + * Batch object with methods + ************************************************************************************************/ + + /** + * Handling object for batch calls. + */ + $.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) { + // Array of objects to hold the call and notify requests. Each objects will have the request + // object, and unless it is a notify, success_cb and error_cb. + this._requests = []; + + this.jsonrpcclient = jsonrpcclient; + this.all_done_cb = all_done_cb; + this.error_cb = typeof error_cb === 'function' ? error_cb : function() {}; + + }; + + /** + * @sa $.JsonRpcClient.prototype.call + */ + $.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) { + + if (!params) { + params = {}; + } + + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + + if (!success_cb) { + success_cb = function(e){console.log("Success: ", e);}; + } + + if (!error_cb) { + error_cb = function(e){console.log("Error: ", e);}; + } + + this._requests.push({ + request : { + jsonrpc : '2.0', + method : method, + params : params, + id : this.jsonrpcclient._current_id++ // Use the client's id series. + }, + success_cb : success_cb, + error_cb : error_cb + }); + }; + + /** + * @sa $.JsonRpcClient.prototype.notify + */ + $.JsonRpcClient._batchObject.prototype.notify = function(method, params) { + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + + this._requests.push({ + request : { + jsonrpc : '2.0', + method : method, + params : params + } + }); + }; + + /** + * Executes the batched up calls. + */ + $.JsonRpcClient._batchObject.prototype._execute = function() { + var self = this; + + if (this._requests.length === 0) return; // All done :P + + // Collect all request data and sort handlers by request id. + var batch_request = []; + var handlers = {}; + var i = 0; + var call; + var success_cb; + var error_cb; + + // If we have a WebSocket, just send the requests individually like normal calls. + var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); + if (socket !== null) { + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + success_cb = ('success_cb' in call) ? call.success_cb : undefined; + error_cb = ('error_cb' in call) ? call.error_cb : undefined; + self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); + } + + if (typeof all_done_cb === 'function') all_done_cb(result); + return; + } + + for (i = 0; i < this._requests.length; i++) { + call = this._requests[i]; + batch_request.push(call.request); + + // If the request has an id, it should handle returns (otherwise it's a notify). + if ('id' in call.request) { + handlers[call.request.id] = { + success_cb : call.success_cb, + error_cb : call.error_cb + }; + } + } + + success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); }; + + // No WebSocket, and no HTTP backend? This won't work. + if (self.jsonrpcclient.options.ajaxUrl === null) { + throw "$.JsonRpcClient.batch used with no websocket and no http endpoint."; + } + + // Send request + $.ajax({ + url : self.jsonrpcclient.options.ajaxUrl, + data : $.toJSON(batch_request), + dataType : 'json', + cache : false, + type : 'POST', + + // Batch-requests should always return 200 + error : function(jqXHR, textStatus, errorThrown) { + self.error_cb(jqXHR, textStatus, errorThrown); + }, + success : success_cb + }); + }; + + /** + * Internal helper to match the result array from a batch call to their respective callbacks. + * + * @fn _batchCb + * @memberof $.JsonRpcClient + */ + $.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) { + for (var i = 0; i < result.length; i++) { + var response = result[i]; + + // Handle error + if ('error' in response) { + if (response.id === null || !(response.id in handlers)) { + // An error on a notify? Just log it to the console. + if ('console' in window) console.log(response); + } else { + handlers[response.id].error_cb(response.error, this); + } + } else { + // Here we should always have a correct id and no error. + if (!(response.id in handlers) && 'console' in window) { + console.log(response); + } else { + handlers[response.id].success_cb(response.result, this); + } + } + } + + if (typeof all_done_cb === 'function') all_done_cb(result); + }; + +})(jQuery); + +/* + * Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH + * Copyright (C) 2005-2014, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * jquery.verto.js - Main interface + * + */ + +(function($) { + + var generateGUID = (typeof(window.crypto) !== 'undefined' && typeof(window.crypto.getRandomValues) !== 'undefined') ? + function() { + // If we have a cryptographically secure PRNG, use that + // http://stackoverflow.com/questions/6906916/collisions-when-generating-uuids-in-javascript + var buf = new Uint16Array(8); + window.crypto.getRandomValues(buf); + var S4 = function(num) { + var ret = num.toString(16); + while (ret.length < 4) { + ret = "0" + ret; + } + return ret; + }; + return (S4(buf[0]) + S4(buf[1]) + "-" + S4(buf[2]) + "-" + S4(buf[3]) + "-" + S4(buf[4]) + "-" + S4(buf[5]) + S4(buf[6]) + S4(buf[7])); + } + + : + + function() { + // Otherwise, just use Math.random + // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, + v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + }; + + /// MASTER OBJ + $.verto = function(options, callbacks) { + var verto = this; + + $.verto.saved.push(verto); + + verto.options = $.extend({ + login: null, + passwd: null, + socketUrl: null, + tag: null, + videoParams: {}, + audioParams: {}, + iceServers: false, + ringSleep: 6000 + }, options); + + verto.sessid = $.cookie('verto_session_uuid') || generateGUID(); + $.cookie('verto_session_uuid', verto.sessid, { + expires: 1 + }); + + verto.dialogs = {}; + verto.callbacks = callbacks || {}; + verto.eventSUBS = {}; + + verto.rpcClient = new $.JsonRpcClient({ + login: verto.options.login, + passwd: verto.options.passwd, + socketUrl: verto.options.socketUrl, + sessid: verto.sessid, + onmessage: function(e) { + return verto.handleMessage(e.eventData); + }, + onWSConnect: function(o) { + o.call('login', {}); + }, + onWSLogin: function(success) { + if (verto.callbacks.onWSLogin) { + verto.callbacks.onWSLogin(verto, success); + } + }, + onWSClose: function(success) { + if (verto.callbacks.onWSClose) { + verto.callbacks.onWSClose(verto, success); + } + verto.purge(); + } + }); + + if (verto.options.ringFile && verto.options.tag) { + verto.ringer = $("#" + verto.options.tag); + } + + verto.rpcClient.call('login', {}); + + }; + + $.verto.prototype.iceServers = function(on) { + var verto = this; + verto.options.iceServers = on; + }; + + $.verto.prototype.loginData = function(params) { + verto.options.login = params.login; + verto.options.passwd = params.passwd; + verto.rpcClient.loginData(params); + }; + + $.verto.prototype.logout = function(msg) { + var verto = this; + verto.rpcClient.closeSocket(); + verto.purge(); + }; + + $.verto.prototype.login = function(msg) { + var verto = this; + verto.logout(); + verto.rpcClient.call('login', {}); + }; + + $.verto.prototype.message = function(msg) { + var verto = this; + var err = 0; + + if (!msg.to) { + console.error("Missing To"); + err++; + } + + if (!msg.body) { + console.error("Missing Body"); + err++; + } + + if (err) { + return false; + } + + verto.sendMethod("verto.info", { + msg: msg + }); + + return true; + }; + + $.verto.prototype.processReply = function(method, success, e) { + var verto = this; + var i; + + //console.log("Response: " + method, success, e); + + switch (method) { + case "verto.subscribe": + for (i in e.unauthorizedChannels) { + drop_bad(verto, e.unauthorizedChannels[i]); + } + for (i in e.subscribedChannels) { + mark_ready(verto, e.subscribedChannels[i]); + } + + break; + case "verto.unsubscribe": + //console.error(e); + break; + } + }; + + $.verto.prototype.sendMethod = function(method, params) { + var verto = this; + + verto.rpcClient.call(method, params, + + function(e) { + /* Success */ + verto.processReply(method, true, e); + }, + + function(e) { + /* Error */ + verto.processReply(method, false, e); + }); + }; + + function do_sub(verto, channel, obj) { + + } + + function drop_bad(verto, channel) { + console.error("drop unauthorized channel: " + channel); + delete verto.eventSUBS[channel]; + } + + function mark_ready(verto, channel) { + for (var j in verto.eventSUBS[channel]) { + verto.eventSUBS[channel][j].ready = true; + console.log("subscribed to channel: " + channel); + if (verto.eventSUBS[channel][j].readyHandler) { + verto.eventSUBS[channel][j].readyHandler(verto, channel); + } + } + } + + var SERNO = 1; + + function do_subscribe(verto, channel, subChannels, sparams) { + var params = sparams || {}; + + var local = params.local; + + var obj = { + eventChannel: channel, + userData: params.userData, + handler: params.handler, + ready: false, + readyHandler: params.readyHandler, + serno: SERNO++ + }; + + var isnew = false; + + if (!verto.eventSUBS[channel]) { + verto.eventSUBS[channel] = []; + subChannels.push(channel); + isnew = true; + } + + verto.eventSUBS[channel].push(obj); + + if (local) { + obj.ready = true; + obj.local = true; + } + + if (!isnew && verto.eventSUBS[channel][0].ready) { + obj.ready = true; + if (obj.readyHandler) { + obj.readyHandler(verto, channel); + } + } + + return { + serno: obj.serno, + eventChannel: channel + }; + + } + + $.verto.prototype.subscribe = function(channel, sparams) { + var verto = this; + var r = []; + var subChannels = []; + var params = sparams || {}; + + if (typeof(channel) === "string") { + r.push(do_subscribe(verto, channel, subChannels, params)); + } else { + for (var i in channel) { + r.push(do_subscribe(verto, channel, subChannels, params)); + } + } + + if (subChannels.length) { + verto.sendMethod("verto.subscribe", { + eventChannel: subChannels.length == 1 ? subChannels[0] : subChannels, + subParams: params.subParams + }); + } + + return r; + }; + + $.verto.prototype.unsubscribe = function(handle) { + var verto = this; + var i; + + if (!handle) { + for (i in verto.eventSUBS) { + if (verto.eventSUBS[i]) { + verto.unsubscribe(verto.eventSUBS[i]); + } + } + } else { + var unsubChannels = {}; + var sendChannels = []; + var channel; + + if (typeof(handle) == "string") { + delete verto.eventSUBS[handle]; + unsubChannels[handle]++; + } else { + for (i in handle) { + if (typeof(handle[i]) == "string") { + channel = handle[i]; + delete verto.eventSUBS[channel]; + unsubChannels[channel]++; + } else { + var repl = []; + channel = handle[i].eventChannel; + + for (var j in verto.eventSUBS[channel]) { + if (verto.eventSUBS[channel][j].serno == handle[i].serno) {} else { + repl.push(verto.eventSUBS[channel][j]); + } + } + + verto.eventSUBS[channel] = repl; + + if (verto.eventSUBS[channel].length === 0) { + delete verto.eventSUBS[channel]; + unsubChannels[channel]++; + } + } + } + } + + for (var u in unsubChannels) { + console.log("Sending Unsubscribe for: ", u); + sendChannels.push(u); + } + + if (sendChannels.length) { + verto.sendMethod("verto.unsubscribe", { + eventChannel: sendChannels.length == 1 ? sendChannels[0] : sendChannels + }); + } + } + }; + + $.verto.prototype.broadcast = function(channel, params) { + var verto = this; + var msg = { + eventChannel: channel, + data: {} + }; + for (var i in params) { + msg.data[i] = params[i]; + } + verto.sendMethod("verto.broadcast", msg); + }; + + $.verto.prototype.purge = function(callID) { + var verto = this; + var x = 0; + var i; + + for (i in verto.dialogs) { + if (!x) { + console.log("purging dialogs"); + } + x++; + verto.dialogs[i].setState($.verto.enum.state.purge); + } + + for (i in verto.eventSUBS) { + if (verto.eventSUBS[i]) { + console.log("purging subscription: " + i); + delete verto.eventSUBS[i]; + } + } + }; + + $.verto.prototype.hangup = function(callID) { + var verto = this; + if (callID) { + var dialog = verto.dialogs[callID]; + + if (dialog) { + dialog.hangup(); + } + } else { + for (var i in verto.dialogs) { + verto.dialogs[i].hangup(); + } + } + }; + + $.verto.prototype.newCall = function(args, callbacks) { + var verto = this; + + if (!verto.rpcClient.socketReady()) { + console.error("Not Connected..."); + return; + } + + var dialog = new $.verto.dialog($.verto.enum.direction.outbound, this, args); + + dialog.invite(); + + if (callbacks) { + dialog.callbacks = callbacks; + } + + return dialog; + }; + + $.verto.prototype.handleMessage = function(data) { + var verto = this; + + if (!(data && data.method)) { + console.error("Invalid Data", data); + return; + } + + if (data.params.callID) { + var dialog = verto.dialogs[data.params.callID]; + + if (dialog) { + + switch (data.method) { + case 'verto.bye': + dialog.hangup(data.params); + break; + case 'verto.answer': + dialog.handleAnswer(data.params); + break; + case 'verto.media': + dialog.handleMedia(data.params); + break; + case 'verto.display': + dialog.handleDisplay(data.params); + break; + case 'verto.info': + dialog.handleInfo(data.params); + break; + default: + console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", dialog, data.method); + break; + } + } else { + + switch (data.method) { + case 'verto.attach': + data.params.attach = true; + + if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { + data.params.useVideo = true; + } + + if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { + data.params.useStereo = true; + } + + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + dialog.setState($.verto.enum.state.recovering); + + break; + case 'verto.invite': + + if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { + data.params.wantVideo = true; + } + + if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { + data.params.useStereo = true; + } + + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + break; + default: + console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED"); + break; + } + } + + return { + method: data.method + }; + } else { + switch (data.method) { + case 'verto.event': + var list = null; + var key = null; + + if (data.params) { + key = data.params.eventChannel; + } + + if (key) { + list = verto.eventSUBS[key]; + + if (!list) { + list = verto.eventSUBS[key.split(".")[0]]; + } + } + + if (!list && key && key === verto.sessid) { + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.pvtEvent, data.params); + } + } else if (!list && key && verto.dialogs[key]) { + verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent, data.params); + } else if (!list) { + if (!key) { + key = "UNDEFINED"; + } + console.error("UNSUBBED or invalid EVENT " + key + " IGNORED"); + } else { + for (var i in list) { + var sub = list[i]; + + if (!sub || !sub.ready) { + console.error("invalid EVENT for " + key + " IGNORED"); + } else if (sub.handler) { + sub.handler(verto, data.params, sub.userData); + } else if (verto.callbacks.onEvent) { + verto.callbacks.onEvent(verto, data.params, sub.userData); + } else { + console.log("EVENT:", data.params); + } + } + } + + break; + + case "verto.info": + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.info, data.params.msg); + } + //console.error(data); + console.debug("MESSAGE from: " + data.params.msg.from, data.params.msg.body); + + break; + + default: + console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", data.method); + break; + } + } + }; + + var del_array = function(array, name) { + var r = []; + var len = array.length; + + for (var i = 0; i < len; i++) { + if (array[i] != name) { + r.push(array[i]); + } + } + + return r; + }; + + var hashArray = function() { + var vha = this; + + var hash = {}; + var array = []; + + vha.reorder = function(a) { + array = a; + var h = hash; + hash = {}; + + var len = array.length; + + for (var i = 0; i < len; i++) { + var key = array[i]; + if (h[key]) { + hash[key] = h[key]; + delete h[key]; + } + } + h = undefined; + }; + + vha.clear = function() { + hash = undefined; + array = undefined; + hash = {}; + array = []; + }; + + vha.add = function(name, val, insertAt) { + var redraw = false; + + if (!hash[name]) { + if (insertAt === undefined || insertAt < 0 || insertAt >= array.length) { + array.push(name); + } else { + var x = 0; + var n = []; + var len = array.length; + + for (var i = 0; i < len; i++) { + if (x++==insertAt) { + n.push(name); + } + n.push(array[i]); + } + + array = undefined; + array = n; + n = undefined; + redraw = true; + } + } + + hash[name] = val; + + return redraw; + }; + + vha.del = function(name) { + var r = false; + + if (hash[name]) { + array = del_array(array, name); + delete hash[name]; + r = true; + } else { + console.error("can't del nonexistant key " + name); + } + + return r; + }; + + vha.get = function(name) { + return hash[name]; + }; + + vha.order = function() { + return array; + }; + + vha.hash = function() { + return hash; + }; + + vha.indexOf = function(name) { + var len = array.length; + + for (var i = 0; i < len; i++) { + if (array[i] == name) { + return i; + } + } + }; + + vha.arrayLen = function() { + return array.length; + }; + + vha.asArray = function() { + var r = []; + + var len = array.length; + + for (var i = 0; i < len; i++) { + var key = array[i]; + r.push(hash[key]); + } + + return r; + }; + + vha.each = function(cb) { + var len = array.length; + + for (var i = 0; i < len; i++) { + cb(array[i], hash[array[i]]); + } + }; + + vha.dump = function(html) { + var str = ""; + + vha.each(function(name, val) { + str += "name: " + name + " val: " + JSON.stringify(val) + (html ? "
" : "\n"); + }); + + return str; + }; + + }; + + $.verto.liveArray = function(verto, context, name, config) { + var la = this; + var lastSerno = 0; + var binding = null; + var user_obj = config.userObj; + var local = false; + + // Inherit methods of hashArray + hashArray.call(la); + + // Save the hashArray add, del, reorder, clear methods so we can make our own. + la._add = la.add; + la._del = la.del; + la._reorder = la.reorder; + la._clear = la.clear; + + la.context = context; + la.name = name; + la.user_obj = user_obj; + + la.verto = verto; + la.broadcast = function(channel, obj) { + verto.broadcast(channel, obj); + }; + la.errs = 0; + + la.clear = function() { + la._clear(); + lastSerno = 0; + + if (la.onChange) { + la.onChange(la, { + action: "clear" + }); + } + }; + + la.checkSerno = function(serno) { + if (serno < 0) { + return true; + } + + if (lastSerno > 0 && serno != (lastSerno + 1)) { + if (la.onErr) { + la.onErr(la, { + lastSerno: lastSerno, + serno: serno + }); + } + la.errs++; + console.debug(la.errs); + if (la.errs < 3) { + la.bootstrap(la.user_obj); + } + return false; + } else { + lastSerno = serno; + return true; + } + }; + + la.reorder = function(serno, a) { + if (la.checkSerno(serno)) { + la._reorder(a); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "reorder" + }); + } + } + }; + + la.init = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "init", + index: index, + key: key, + data: val + }); + } + } + }; + + la.bootObj = function(serno, val) { + if (la.checkSerno(serno)) { + + //la.clear(); + for (var i in val) { + la._add(val[i][0], val[i][1]); + } + + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "bootObj", + data: val, + redraw: true + }); + } + } + }; + + // @param serno La is the serial number for la particular request. + // @param key If looking at it as a hash table, la represents the key in the hashArray object where you want to store the val object. + // @param index If looking at it as an array, la represents the position in the array where you want to store the val object. + // @param val La is the object you want to store at the key or index location in the hash table / array. + la.add = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + var redraw = la._add(key, val, index); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "add", + index: index, + key: key, + data: val, + redraw: redraw + }); + } + } + }; + + la.modify = function(serno, val, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + la._add(key, val, index); + if (la.onChange) { + la.onChange(la, { + serno: serno, + action: "modify", + key: key, + data: val, + index: index + }); + } + } + }; + + la.del = function(serno, key, index) { + if (key === null || key === undefined) { + key = serno; + } + if (la.checkSerno(serno)) { + if (index === null || index < 0 || index === undefined) { + index = la.indexOf(key); + } + var ok = la._del(key); + + if (ok && la.onChange) { + la.onChange(la, { + serno: serno, + action: "del", + key: key, + index: index + }); + } + } + }; + + var eventHandler = function(v, e, la) { + var packet = e.data; + + //console.error("READ:", packet); + + if (packet.name != la.name) { + return; + } + + switch (packet.action) { + + case "init": + la.init(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + break; + + case "bootObj": + la.bootObj(packet.wireSerno, packet.data); + break; + case "add": + la.add(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + break; + + case "modify": + if (! (packet.arrIndex || packet.hashKey)) { + console.error("Invalid Packet", packet); + } else { + la.modify(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); + } + break; + case "del": + if (! (packet.arrIndex || packet.hashKey)) { + console.error("Invalid Packet", packet); + } else { + la.del(packet.wireSerno, packet.hashKey, packet.arrIndex); + } + break; + + case "clear": + la.clear(); + break; + + case "reorder": + la.reorder(packet.wireSerno, packet.order); + break; + + default: + if (la.checkSerno(packet.wireSerno)) { + if (la.onChange) { + la.onChange(la, { + serno: packet.wireSerno, + action: packet.action, + data: packet.data + }); + } + } + break; + } + }; + + if (la.context) { + binding = la.verto.subscribe(la.context, { + handler: eventHandler, + userData: la, + subParams: config.subParams + }); + } + + la.destroy = function() { + la._clear(); + la.verto.unsubscribe(binding); + }; + + la.sendCommand = function(cmd, obj) { + var self = la; + self.broadcast(self.context, { + liveArray: { + command: cmd, + context: self.context, + name: self.name, + obj: obj + } + }); + }; + + la.bootstrap = function(obj) { + var self = la; + la.sendCommand("bootstrap", obj); + //self.heartbeat(); + }; + + la.changepage = function(obj) { + var self = la; + self.clear(); + self.broadcast(self.context, { + liveArray: { + command: "changepage", + context: la.context, + name: la.name, + obj: obj + } + }); + }; + + la.heartbeat = function(obj) { + var self = la; + + var callback = function() { + self.heartbeat.call(self, obj); + }; + self.broadcast(self.context, { + liveArray: { + command: "heartbeat", + context: self.context, + name: self.name, + obj: obj + } + }); + self.hb_pid = setTimeout(callback, 30000); + }; + + la.bootstrap(la.user_obj); + }; + + $.verto.liveTable = function(verto, context, name, jq, config) { + var dt; + var la = new $.verto.liveArray(verto, context, name, { + subParams: config.subParams + }); + var lt = this; + + lt.liveArray = la; + lt.dataTable = dt; + lt.verto = verto; + + lt.destroy = function() { + if (dt) { + dt.fnDestroy(); + } + if (la) { + la.destroy(); + } + + dt = null; + la = null; + }; + + la.onErr = function(obj, args) { + console.error("Error: ", obj, args); + }; + + la.onChange = function(obj, args) { + var index = 0; + var iserr = 0; + + if (!dt) { + if (!config.aoColumns) { + if (args.action != "init") { + return; + } + + config.aoColumns = []; + + for (var i in args.data) { + config.aoColumns.push({ + "sTitle": args.data[i] + }); + } + } + + dt = jq.dataTable(config); + } + + if (dt && (args.action == "del" || args.action == "modify")) { + index = args.index; + + if (index === undefined && args.key) { + index = la.indexOf(args.key); + } + + if (index === undefined) { + console.error("INVALID PACKET Missing INDEX\n", args); + return; + } + } + + if (config.onChange) { + config.onChange(obj, args); + } + + try { + switch (args.action) { + case "bootObj": + if (!args.data) { + console.error("missing data"); + return; + } + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + dt.fnAdjustColumnSizing(); + break; + case "add": + if (!args.data) { + console.error("missing data"); + return; + } + if (args.redraw > -1) { + // specific position, more costly + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + } else { + dt.fnAddData(args.data); + } + dt.fnAdjustColumnSizing(); + break; + case "modify": + if (!args.data) { + return; + } + //console.debug(args, index); + dt.fnUpdate(args.data, index); + dt.fnAdjustColumnSizing(); + break; + case "del": + dt.fnDeleteRow(index); + dt.fnAdjustColumnSizing(); + break; + case "clear": + dt.fnClearTable(); + break; + case "reorder": + // specific position, more costly + dt.fnClearTable(); + dt.fnAddData(obj.asArray()); + break; + case "hide": + jq.hide(); + break; + + case "show": + jq.show(); + break; + + } + } catch(err) { + console.error("ERROR: " + err); + iserr++; + } + + if (iserr) { + obj.errs++; + if (obj.errs < 3) { + obj.bootstrap(obj.user_obj); + } + } else { + obj.errs = 0; + } + + }; + + la.onChange(la, { + action: "init" + }); + + }; + + var CONFMAN_SERNO = 1; + + $.verto.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++; + + function genMainMod(jq) { + var play_id = "play_" + confMan.serno; + var stop_id = "stop_" + confMan.serno; + var recording_id = "recording_" + confMan.serno; + var rec_stop_id = "recording_stop" + confMan.serno; + var div_id = "confman_" + confMan.serno; + + var html = "

" + + "" + + "" + + "" + + "" + + "

"; + + jq.html(html); + + $("#" + play_id).click(function() { + var file = prompt("Please enter file name", ""); + 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", ""); + 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 tmute_id = "tmute_" + 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 = "
" + + "" + + "" + + "" + + "" + + "" + + "
" + ; + + 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"); + confMan.modCommand("transfer", x, xten); + }); + + $("#" + kick_id).click(function() { + confMan.modCommand("kick", x); + }); + + $("#" + tmute_id).click(function() { + confMan.modCommand("tmute", x); + }); + + $("#" + volup_id).click(function() { + confMan.modCommand("volume_in", x, "up"); + }); + + $("#" + voldn_id).click(function() { + confMan.modCommand("volume_in", x, "down"); + }); + + return html; + } + + var atitle = ""; + var awidth = 0; + + //$(".jsDataTable").width(confMan.params.hasVid ? "900px" : "800px"); + + if (confMan.params.laData.role === "moderator") { + atitle = "Action"; + awidth = 200; + + if (confMan.params.mainModID) { + genMainMod($(confMan.params.mainModID)); + $(confMan.params.displayID).html("Moderator Controls Ready

"); + } else { + $(confMan.params.mainModID).html(""); + } + + verto.subscribe(confMan.params.laData.modChannel, { + handler: function(v, e) { + console.error("MODDATA:", e.data); + if (confMan.params.onBroadcast) { + confMan.params.onBroadcast(verto, confMan, e.data); + } + if (!confMan.destroyed && confMan.params.displayID) { + $(confMan.params.displayID).html(e.data.response + "

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

");}, 4000); + } + } + }); + } + + var row_callback = null; + + if (confMan.params.laData.role === "moderator") { + row_callback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { + if (!aData[5]) { + var $row = $('td:eq(5)', nRow); + genControls($row, aData); + + if (confMan.params.onLaRow) { + confMan.params.onLaRow(verto, confMan, $row, aData); + } + } + }; + } + + confMan.lt = new $.verto.liveTable(verto, confMan.params.laData.laChannel, confMan.params.laData.laName, $(confMan.params.tableID), { + subParams: { + callID: confMan.params.dialog ? confMan.params.dialog.callID : null + }, + + "onChange": function(obj, args) { + $(confMan.params.statusID).text("Conference Members: " + " (" + obj.arrayLen() + " Total)"); + if (confMan.params.onLaChange) { + confMan.params.onLaChange(verto, confMan, $.verto.enum.confEvent.laChange, obj, args); + } + }, + + "aaData": [], + "aoColumns": [ + { + "sTitle": "ID" + }, + { + "sTitle": "Number" + }, + { + "sTitle": "Name" + }, + { + "sTitle": "Codec" + }, + { + "sTitle": "Status", + "sWidth": confMan.params.hasVid ? "300px" : "150px" + }, + { + "sTitle": atitle, + "sWidth": awidth, + } + ], + "bAutoWidth": true, + "bDestroy": true, + "bSort": false, + "bInfo": false, + "bFilter": false, + "bLengthChange": false, + "bPaginate": false, + "iDisplayLength": 1000, + + "oLanguage": { + "sEmptyTable": "The Conference is Empty....." + }, + + "fnRowCallback": row_callback + + }); + }; + + $.verto.confMan.prototype.modCommand = function(cmd, id, value) { + var confMan = this; + + confMan.verto.sendMethod("verto.broadcast", { + "eventChannel": confMan.params.laData.modChannel, + "data": { + "application": "conf-control", + "command": cmd, + "id": id, + "value": value + } + }); + }; + + $.verto.confMan.prototype.destroy = function() { + var confMan = this; + + confMan.destroyed = true; + + if (confMan.lt) { + confMan.lt.destroy(); + } + + if (confMan.params.laData.modChannel) { + confMan.verto.unsubscribe(confMan.params.laData.modChannel); + } + + if (confMan.params.mainModID) { + $(confMan.params.mainModID).html(""); + } + }; + + $.verto.dialog = function(direction, verto, params) { + var dialog = this; + + dialog.params = $.extend({ + useVideo: verto.options.useVideo, + useStereo: verto.options.useStereo, + tag: verto.options.tag, + login: verto.options.login + }, params); + + dialog.verto = verto; + dialog.direction = direction; + dialog.lastState = null; + dialog.state = dialog.lastState = $.verto.enum.state.new; + dialog.callbacks = verto.callbacks; + dialog.answered = false; + dialog.attach = params.attach || false; + + if (dialog.params.callID) { + dialog.callID = dialog.params.callID; + } else { + dialog.callID = dialog.params.callID = generateGUID(); + } + + if (dialog.params.tag) { + dialog.audioStream = document.getElementById(dialog.params.tag); + + if (dialog.params.useVideo) { + dialog.videoStream = dialog.audioStream; + } + } //else conjure one TBD + + dialog.verto.dialogs[dialog.callID] = dialog; + + var RTCcallbacks = {}; + + if (dialog.direction == $.verto.enum.direction.inbound) { + if (dialog.params.display_direction === "outbound") { + dialog.params.remote_caller_id_name = dialog.params.caller_id_name; + dialog.params.remote_caller_id_number = dialog.params.caller_id_number; + } else { + dialog.params.remote_caller_id_name = dialog.params.callee_id_name; + dialog.params.remote_caller_id_number = dialog.params.callee_id_number; + } + + if (!dialog.params.remote_caller_id_name) { + dialog.params.remote_caller_id_name = "Nobody"; + } + + if (!dialog.params.remote_caller_id_number) { + dialog.params.remote_caller_id_number = "UNKNOWN"; + } + + RTCcallbacks.onMessage = function(rtc, msg) { + console.debug(msg); + }; + + RTCcallbacks.onAnswerSDP = function(rtc, sdp) { + console.error("answer sdp", sdp); + }; + } else { + dialog.params.remote_caller_id_name = "Outbound Call"; + dialog.params.remote_caller_id_number = dialog.params.destination_number; + } + + RTCcallbacks.onICESDP = function(rtc) { + + if (rtc.type == "offer") { + console.log("offer", rtc.mediaData.SDP); + + dialog.setState($.verto.enum.state.requesting); + + dialog.sendMethod("verto.invite", { + sdp: rtc.mediaData.SDP + }); + } else { //answer + dialog.setState($.verto.enum.state.answering); + + dialog.sendMethod(dialog.attach ? "verto.attach" : "verto.answer", { + sdp: dialog.rtc.mediaData.SDP + }); + } + }; + + RTCcallbacks.onICE = function(rtc) { + //console.log("cand", rtc.mediaData.candidate); + if (rtc.type == "offer") { + console.log("offer", rtc.mediaData.candidate); + return; + } + }; + + RTCcallbacks.onError = function(e) { + console.error("ERROR:", e); + dialog.hangup(); + }; + + dialog.rtc = new $.FSRTC({ + callbacks: RTCcallbacks, + useVideo: dialog.videoStream, + useAudio: dialog.audioStream, + useStereo: dialog.params.useStereo, + videoParams: verto.options.videoParams, + audioParams: verto.options.audioParams, + iceServers: verto.options.iceServers + }); + + dialog.rtc.verto = dialog.verto; + + if (dialog.direction == $.verto.enum.direction.inbound) { + if (dialog.attach) { + dialog.answer(); + } else { + dialog.ring(); + } + } + }; + + $.verto.dialog.prototype.invite = function() { + var dialog = this; + dialog.rtc.call(); + }; + + $.verto.dialog.prototype.sendMethod = function(method, obj) { + var dialog = this; + obj.dialogParams = {}; + + for (var i in dialog.params) { + if (i == "sdp" && method != "verto.invite" && method != "verto.attach") { + continue; + } + + obj.dialogParams[i] = dialog.params[i]; + } + + dialog.verto.rpcClient.call(method, obj, + + function(e) { + /* Success */ + dialog.processReply(method, true, e); + }, + + function(e) { + /* Error */ + dialog.processReply(method, false, e); + }); + }; + + function checkStateChange(oldS, newS) { + + if (newS == $.verto.enum.state.purge || $.verto.enum.states[oldS.name][newS.name]) { + return true; + } + + return false; + } + + $.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.info("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.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]; + dialog.rtc.stop(); + break; + } + + return true; + }; + + $.verto.dialog.prototype.processReply = function(method, success, e) { + var dialog = this; + + //console.log("Response: " + method + " State:" + dialog.state.name, success, e); + + switch (method) { + + case "verto.answer": + case "verto.attach": + if (success) { + dialog.setState($.verto.enum.state.active); + } else { + dialog.hangup(); + } + break; + case "verto.invite": + if (success) { + dialog.setState($.verto.enum.state.trying); + } else { + dialog.setState($.verto.enum.state.destroy); + } + break; + + case "verto.bye": + dialog.hangup(); + break; + + case "verto.modify": + if (e.holdState) { + if (e.holdState == "held") { + if (dialog.state != $.verto.enum.state.held) { + dialog.setState($.verto.enum.state.held); + } + } else if (e.holdState == "active") { + if (dialog.state != $.verto.enum.state.active) { + dialog.setState($.verto.enum.state.active); + } + } + } + + if (success) {} + + break; + + default: + break; + } + + }; + + $.verto.dialog.prototype.hangup = function(params) { + var dialog = this; + + if (params) { + if (params.causeCode) { + dialog.causeCode = params.causeCode; + } + + if (params.cause) { + dialog.cause = params.cause; + } + } + + if (dialog.state.val > $.verto.enum.state.new.val && dialog.state.val < $.verto.enum.state.hangup.val) { + dialog.setState($.verto.enum.state.hangup); + } else if (dialog.state.val < $.verto.enum.state.destroy) { + dialog.setState($.verto.enum.state.destroy); + } + }; + + $.verto.dialog.prototype.stopRinging = function() { + var dialog = this; + if (dialog.verto.ringer) { + dialog.verto.ringer.stop(); + } + }; + + $.verto.dialog.prototype.indicateRing = function() { + var dialog = this; + + if (dialog.verto.ringer) { + dialog.verto.ringer.attr("src", dialog.verto.options.ringFile)[0].play(); + + setTimeout(function() { + dialog.stopRinging(); + if (dialog.state == $.verto.enum.state.ringing) { + dialog.indicateRing(); + } + }, + dialog.verto.options.ringSleep); + } + }; + + $.verto.dialog.prototype.ring = function() { + var dialog = this; + + dialog.setState($.verto.enum.state.ringing); + dialog.indicateRing(); + }; + + $.verto.dialog.prototype.useVideo = function(on) { + var dialog = this; + + dialog.params.useVideo = on; + + if (on) { + dialog.videoStream = dialog.audioStream; + } else { + dialog.videoStream = null; + } + + dialog.rtc.useVideo(dialog.videoStream); + + }; + + $.verto.dialog.prototype.useStereo = function(on) { + var dialog = this; + + dialog.params.useStereo = on; + dialog.rtc.useStereo(on); + }; + + $.verto.dialog.prototype.dtmf = function(digits) { + var dialog = this; + if (digits) { + dialog.sendMethod("verto.info", { + dtmf: digits + }); + } + }; + + $.verto.dialog.prototype.transfer = function(dest, params) { + var dialog = this; + if (dest) { + cur_call.sendMethod("verto.modify", { + action: "transfer", + destination: dest, + params: params + }); + } + }; + + $.verto.dialog.prototype.hold = function(params) { + var dialog = this; + + cur_call.sendMethod("verto.modify", { + action: "hold", + params: params + }); + }; + + $.verto.dialog.prototype.unhold = function(params) { + var dialog = this; + + cur_call.sendMethod("verto.modify", { + action: "unhold", + params: params + }); + }; + + $.verto.dialog.prototype.toggleHold = function(params) { + var dialog = this; + + cur_call.sendMethod("verto.modify", { + action: "toggleHold", + params: params + }); + }; + + $.verto.dialog.prototype.message = function(msg) { + var dialog = this; + var err = 0; + + msg.from = dialog.params.login; + + if (!msg.to) { + console.error("Missing To"); + err++; + } + + if (!msg.body) { + console.error("Missing Body"); + err++; + } + + if (err) { + return false; + } + + dialog.sendMethod("verto.info", { + msg: msg + }); + + return true; + }; + + $.verto.dialog.prototype.answer = function(params) { + var dialog = this; + + if (!dialog.answered) { + if (params) { + if (params.useVideo) { + dialog.useVideo(true); + } + dialog.params.callee_id_name = params.callee_id_name; + dialog.params.callee_id_number = params.callee_id_number; + } + dialog.rtc.createAnswer(dialog.params.sdp); + dialog.answered = true; + } + }; + + $.verto.dialog.prototype.handleAnswer = function(params) { + var dialog = this; + + dialog.gotAnswer = true; + + if (dialog.state.val >= $.verto.enum.state.active.val) { + return; + } + + if (dialog.state.val >= $.verto.enum.state.early.val) { + dialog.setState($.verto.enum.state.active); + } else { + if (dialog.gotEarly) { + console.log("Dialog " + dialog.callID + "Got answer while still establishing early media, delaying..."); + } else { + console.log("Dialog " + dialog.callID + "Answering Channel"); + dialog.rtc.answer(params.sdp, function() { + dialog.setState($.verto.enum.state.active); + }, function(e) { + console.error(e); + dialog.hangup(); + }); + console.log("Dialog " + dialog.callID + "ANSWER SDP", params.sdp); + } + } + }; + + $.verto.dialog.prototype.cidString = function(enc) { + var dialog = this; + var party = dialog.params.remote_caller_id_name + (enc ? " <" : " <") + dialog.params.remote_caller_id_number + (enc ? ">" : ">"); + return party; + }; + + $.verto.dialog.prototype.sendMessage = function(msg, params) { + var dialog = this; + + if (dialog.callbacks.onMessage) { + dialog.callbacks.onMessage(dialog.verto, dialog, msg, params); + } + }; + + $.verto.dialog.prototype.handleInfo = function(params) { + var dialog = this; + + dialog.sendMessage($.verto.enum.message.info, params.msg); + }; + + $.verto.dialog.prototype.handleDisplay = function(params) { + var dialog = this; + + if (params.display_name) { + dialog.params.remote_caller_id_name = params.display_name; + } + if (params.display_number) { + dialog.params.remote_caller_id_number = params.display_number; + } + + dialog.sendMessage($.verto.enum.message.display, {}); + }; + + $.verto.dialog.prototype.handleMedia = function(params) { + var dialog = this; + + if (dialog.state.val >= $.verto.enum.state.early.val) { + return; + } + + dialog.gotEarly = true; + + dialog.rtc.answer(params.sdp, function() { + console.log("Dialog " + dialog.callID + "Establishing early media"); + dialog.setState($.verto.enum.state.early); + + if (dialog.gotAnswer) { + console.log("Dialog " + dialog.callID + "Answering Channel"); + dialog.setState($.verto.enum.state.active); + } + }, function(e) { + console.error(e); + dialog.hangup(); + }); + console.log("Dialog " + dialog.callID + "EARLY SDP", params.sdp); + }; + + $.verto.ENUM = function(s) { + var i = 0, + o = {}; + s.split(" ").map(function(x) { + o[x] = { + name: x, + val: i++ + }; + }); + return Object.freeze(o); + }; + + $.verto.enum = {}; + + $.verto.enum.states = Object.freeze({ + new: { + requesting: 1, + recovering: 1, + ringing: 1, + destroy: 1, + answering: 1 + }, + requesting: { + trying: 1, + hangup: 1 + }, + recovering: { + answering: 1, + hangup: 1 + }, + trying: { + active: 1, + early: 1, + hangup: 1 + }, + ringing: { + answering: 1, + hangup: 1 + }, + answering: { + active: 1, + hangup: 1 + }, + active: { + answering: 1, + requesting: 1, + hangup: 1, + held: 1 + }, + held: { + hangup: 1, + active: 1 + }, + early: { + hangup: 1, + active: 1 + }, + hangup: { + destroy: 1 + }, + destroy: {}, + purge: { + destroy: 1 + } + }); + + $.verto.enum.state = $.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge"); + $.verto.enum.direction = $.verto.ENUM("inbound outbound"); + $.verto.enum.message = $.verto.ENUM("display info pvtEvent"); + + $.verto.enum = Object.freeze($.verto.enum); + + $.verto.saved = []; + + $(window).bind('beforeunload', function() { + for (var i in $.verto.saved) { + var verto = $.verto.saved[i]; + if (verto) { + verto.logout(); + verto.purge(); + } + } + return $.verto.warnOnUnload; + }); + +})(jQuery); From f0ec19315a70b5ea5c0ad618d9f207fc79da610a Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 3 Jan 2015 09:31:30 +0800 Subject: [PATCH 07/72] FS-7127 #comment update README again --- html5/verto/README | 1 + 1 file changed, 1 insertion(+) diff --git a/html5/verto/README b/html5/verto/README index eff93ea32e..de7d003edb 100644 --- a/html5/verto/README +++ b/html5/verto/README @@ -5,4 +5,5 @@ Do not base it on the demo because it was just tossed together. To run jshint: cd js + npm install grunt From 0bec209a9bfef8e84506c91ad96c640e7750098e Mon Sep 17 00:00:00 2001 From: Seven Du Date: Sat, 3 Jan 2015 16:06:35 +0800 Subject: [PATCH 08/72] fix fsapi in verto, the json_api_function expects cmd & arg in the data object --- src/mod/endpoints/mod_verto/mod_verto.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 7616416982..67a8dec072 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -3571,10 +3571,15 @@ static switch_bool_t jsapi_func(const char *method, cJSON *params, jsock_t *jsoc } if (jsock->allowed_fsapi && !strcmp(function, "fsapi")) { - cJSON *cmd = cJSON_GetObjectItem(params, "cmd"); - cJSON *arg = cJSON_GetObjectItem(params, "arg"); + cJSON *data = cJSON_GetObjectItem(params, "data"); + cJSON *cmd; + cJSON *arg; - if (cmd->type == cJSON_String && cmd->valuestring && !auth_api_command(jsock, cmd->valuestring, arg ? arg->valuestring : NULL)) { + if (data && + (cmd = cJSON_GetObjectItem(data, "cmd")) && + (arg = cJSON_GetObjectItem(data, "arg")) && + cmd->type == cJSON_String && cmd->valuestring && + !auth_api_command(jsock, cmd->valuestring, arg ? arg->valuestring : NULL)) { return SWITCH_FALSE; } } From 1c16d5d8b041d0fac3463f5f88eaaa1f60aec24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Dragi=C4=87?= Date: Sat, 3 Jan 2015 22:56:19 +0100 Subject: [PATCH 09/72] FS-7121 change switch_events_match() to use strcmp Use strcmp() in place of strstr() so switch_events_match() matches only full event subclass name. --- src/switch_event.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/switch_event.c b/src/switch_event.c index b108ac1be5..9491a9f383 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -240,15 +240,15 @@ static int switch_events_match(switch_event_t *event, switch_event_node_t *node) if (!strncasecmp(node->subclass_name, "file:", 5)) { char *file_header; if ((file_header = switch_event_get_header(event, "file")) != 0) { - match = strstr(node->subclass_name + 5, file_header) ? 1 : 0; + match = !strcmp(node->subclass_name + 5, file_header) ? 1 : 0; } } else if (!strncasecmp(node->subclass_name, "func:", 5)) { char *func_header; if ((func_header = switch_event_get_header(event, "function")) != 0) { - match = strstr(node->subclass_name + 5, func_header) ? 1 : 0; + match = !strcmp(node->subclass_name + 5, func_header) ? 1 : 0; } } else if (event->subclass_name && node->subclass_name) { - match = strstr(event->subclass_name, node->subclass_name) ? 1 : 0; + match = !strcmp(event->subclass_name, node->subclass_name) ? 1 : 0; } } else if ((event->subclass_name && !node->subclass_name) || (!event->subclass_name && !node->subclass_name)) { match = 1; From 2406abdb76a2c6dfb3da364a3997fb6d422e759d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Dragi=C4=87?= Date: Sat, 3 Jan 2015 23:46:19 +0100 Subject: [PATCH 10/72] FS-7128 fs_cli: ignore duplicate lines in history --- libs/esl/fs_cli.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index bab2d5b3b2..acfa0c2c3e 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -1674,6 +1674,8 @@ int main(int argc, char *argv[]) goto done; } history(myhistory, &ev, H_SETSIZE, 800); + /* Ignore duplicate lines */ + history(myhistory, &ev, H_SETUNIQUE, 1); el_set(el, EL_HIST, history, myhistory); if (use_history_file) history(myhistory, &ev, H_LOAD, hfile); el_source(el, NULL); From 959b07c06f565f7d2d8a158c3ce2f44bdae3f350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Dragi=C4=87?= Date: Sun, 4 Jan 2015 00:29:38 +0100 Subject: [PATCH 11/72] FS-7129 fs_cli: add toggle mode to function keys --- libs/esl/fs_cli.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index bab2d5b3b2..57b7756398 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -57,6 +57,8 @@ typedef struct { char pass[128]; int debug; const char *console_fnkeys[12]; + const char *console_fnkeys_toggle[12]; + int console_fnkeys_state[12]; char loglevel[128]; int log_uuid; int log_uuid_length; @@ -158,8 +160,15 @@ static void screen_size(int *x, int *y) static unsigned char console_fnkey_pressed(int i) { const char *c; + int fnkey; assert((i > 0) && (i <= 12)); - if (!(c = global_profile->console_fnkeys[i - 1])) { + fnkey = i - 1; + + if ((c = global_profile->console_fnkeys_toggle[fnkey]) && global_profile->console_fnkeys_state[fnkey]) { + global_profile->console_fnkeys_state[fnkey] = 0; + } else if ((c = global_profile->console_fnkeys[fnkey])) { + global_profile->console_fnkeys_state[fnkey] = 1; + } else { printf("\n"); esl_log(ESL_LOG_ERROR, "FUNCTION KEY F%d IS NOT BOUND, please edit your config.\n", i); return CC_REDISPLAY; @@ -1278,6 +1287,14 @@ static void read_config(const char *dft_cfile, const char *cfile) { profiles[pcount-1].console_fnkeys[i - 1] = strdup(val); } } + } else if (!strncasecmp(var, "key_toggle_F", 12)) { + char *key = var + 12; + if (key) { + int i = atoi(key); + if (i > 0 && i < 13) { + profiles[pcount-1].console_fnkeys_toggle[i - 1] = strdup(val); + } + } } else if (!strcasecmp(var, "timeout")) { timeout = atoi(val); } else if (!strcasecmp(var, "connect-timeout")) { From 2a05f8c39ceba5aa4274950b195913c60b009249 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Mon, 5 Jan 2015 07:11:40 +0000 Subject: [PATCH 12/72] Drop limit on stack size via systemd Setting the 240k hard limit here is too aggressive and causes FS to crash on startup. --- debian/freeswitch-systemd.freeswitch.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/freeswitch-systemd.freeswitch.service b/debian/freeswitch-systemd.freeswitch.service index 5612b21398..c96f1c2b3f 100644 --- a/debian/freeswitch-systemd.freeswitch.service +++ b/debian/freeswitch-systemd.freeswitch.service @@ -21,7 +21,7 @@ Group=freeswitch LimitCORE=infinity LimitNOFILE=100000 LimitNPROC=60000 -LimitSTACK=240 +;LimitSTACK=240 LimitRTPRIO=infinity LimitRTTIME=7000000 IOSchedulingClass=realtime From 4512dbc90939e8e960928ed5fd15f4cfcd4a387b Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 5 Jan 2015 12:48:40 -0600 Subject: [PATCH 13/72] fix multi screen bash history issues --- support-d/.bashrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/support-d/.bashrc b/support-d/.bashrc index 199f3d7924..595c6fccb0 100644 --- a/support-d/.bashrc +++ b/support-d/.bashrc @@ -40,7 +40,8 @@ if [ ! -f ~/.inputrc ]; then fi set -o emacs - +export PROMPT_COMMAND="history -a; history -c; history -r; ${PROMPT_COMMAND}" +export HISTSIZE=5000 export TERM=xterm-256color export LESSCHARSET="latin1" export LESS="-R" From 79df8bafa66e47bed24bfd062e86d5c5a51b60f7 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 5 Jan 2015 13:09:25 -0600 Subject: [PATCH 14/72] Auto update .bashrc if hostname contains freeswitch.org --- support-d/.bashrc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/support-d/.bashrc b/support-d/.bashrc index 595c6fccb0..05b3b38149 100644 --- a/support-d/.bashrc +++ b/support-d/.bashrc @@ -1,5 +1,5 @@ # -# /etc/profile: system-wide defaults for bash(1) login shells +# FreeSWITCH Dev .bashrc # export UNAME=`uname -s` @@ -60,7 +60,6 @@ alias mecas='emacs' alias bgit='git commit --author "Brian West "' alias mgit='git commit --author "Mike Jerris "' alias tgit='git commit --author "Anthony Minessale "' -alias igit='git commit --author "Raymond Chandler "' alias dp='emacs /usr/local/freeswitch/conf/dialplan/default.xml' alias go='/usr/local/freeswitch/bin/freeswitch -nonat' alias fstop='top -p `cat /usr/local/freeswitch/run/freeswitch.pid`' @@ -69,4 +68,18 @@ alias fscore='gdb /usr/local/freeswitch/bin/freeswitch `ls -rt core.* | tail -n1 alias emacs='emacs -nw' alias jitteron='tc qdisc add dev eth0 root handle 1: netem delay 40ms 20ms ; tc qdisc add dev eth0 parent 1:1 pfifo limit 1000' alias jitteroff='tc qdisc del dev eth0 root netem' + +# Auto Update the .bashrc if hostname contains freeswitch.org +if [[ $(hostname) =~ "freeswitch.org" ]]; then + if [ -f /usr/src/freeswitch.git/support-d/.bashrc ]; then + /usr/bin/diff --brief <(sort /usr/src/freeswitch.git/support-d/.bashrc) <(sort ~/.bashrc) >/dev/null + if [ $? -eq 1 ]; then + /bin/cp -f /usr/src/freeswitch.git/support-d/.bashrc ~/ + echo ".bashrc updated." + source ~/.bashrc + fi + fi +fi +# End Auto Update + # End of file From 825121843f91bd484e50f912d9242a0de87b1f58 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 5 Jan 2015 16:41:13 -0600 Subject: [PATCH 15/72] tweak cdquality conference defaults --- conf/vanilla/autoload_configs/conference.conf.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/vanilla/autoload_configs/conference.conf.xml b/conf/vanilla/autoload_configs/conference.conf.xml index c1c0044c48..162aa2df92 100644 --- a/conf/vanilla/autoload_configs/conference.conf.xml +++ b/conf/vanilla/autoload_configs/conference.conf.xml @@ -181,7 +181,7 @@ - + From ece5cd52db59632b861fa3028f6f885fe8e13551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Humberto=20Di=C3=B3genes?= Date: Tue, 16 Dec 2014 15:12:28 -0300 Subject: [PATCH 16/72] FS-7088 #resolve Set flag to enable core dump from non-root users. When FreeSWITCH is running as a non-privileged user, we need to enable PR_SET_DUMPABLE for it to be able to generate core dumps. Instead of a generic __linux__ check, there's a new configure.ac flag to check directly for prctl.h, which could also be used in other places in the code. --- configure.ac | 2 +- src/switch_core.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a91690aeca..160c79f72a 100644 --- a/configure.ac +++ b/configure.ac @@ -766,7 +766,7 @@ AC_SUBST(LIBTOOL_LIB_EXTEN) # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/select.h netdb.h execinfo.h]) +AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/prctl.h sys/select.h netdb.h execinfo.h]) if test x"$ac_cv_header_wchar_h" = xyes; then HAVE_WCHAR_H_DEFINE=1 diff --git a/src/switch_core.c b/src/switch_core.c index 59682df609..b2216ec2b5 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -51,6 +51,9 @@ #endif #include #include +#ifdef HAVE_SYS_PRCTL_H +#include +#endif SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 }; @@ -1029,6 +1032,12 @@ SWITCH_DECLARE(int32_t) change_user_group(const char *user, const char *group) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to change uid!\n"); return -1; } +#ifdef HAVE_SYS_PRCTL_H + if (prctl(PR_SET_DUMPABLE, 1) < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to enable core dumps!\n"); + return -1; + } +#endif } #endif return 0; From f48ec61d54b3fd4faab03addaee0e7c33aff0103 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Jan 2015 21:14:35 -0600 Subject: [PATCH 17/72] FS-7132 #resolve --- html5/verto/demo/js/verto-min.js | 3630 ++--------------------- html5/verto/demo/verto.js | 6 +- html5/verto/js/src/jquery.verto.js | 7 + src/mod/endpoints/mod_verto/mod_verto.c | 26 +- 4 files changed, 240 insertions(+), 3429 deletions(-) diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index fa2ffd0398..416710a7f2 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -1,3425 +1,207 @@ -/* - * Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * jquery.FSRTC.js - WebRTC Glue code - * - */ -(function($) { - - // Find the line in sdpLines that starts with |prefix|, and, if specified, - // contains |substr| (case-insensitive search). - function findLine(sdpLines, prefix, substr) { - return findLineInRange(sdpLines, 0, -1, prefix, substr); - } - - // Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix| - // and, if specified, contains |substr| (case-insensitive search). - function findLineInRange(sdpLines, startLine, endLine, prefix, substr) { - var realEndLine = (endLine != -1) ? endLine : sdpLines.length; - for (var i = startLine; i < realEndLine; ++i) { - if (sdpLines[i].indexOf(prefix) === 0) { - if (!substr || sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) { - return i; - } - } - } - return null; - } - - // Gets the codec payload type from an a=rtpmap:X line. - function getCodecPayloadType(sdpLine) { - var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); - var result = sdpLine.match(pattern); - return (result && result.length == 2) ? result[1] : null; - } - - // Returns a new m= line with the specified codec as the first one. - function setDefaultCodec(mLine, payload) { - var elements = mLine.split(' '); - var newLine = []; - var index = 0; - for (var i = 0; i < elements.length; i++) { - if (index === 3) { // Format of media starts from the fourth. - newLine[index++] = payload; // Put target payload to the first. - } - if (elements[i] !== payload) newLine[index++] = elements[i]; - } - return newLine.join(' '); - } - - $.FSRTC = function(options) { - this.options = $.extend({ - useVideo: null, - useStereo: false, - userData: null, - iceServers: false, - videoParams: {}, - audioParams: {}, - callbacks: { - onICEComplete: function() {}, - onICE: function() {}, - onOfferSDP: function() {} - } - }, options); - - this.mediaData = { - SDP: null, - profile: {}, - candidateList: [] - }; - - this.constraints = { - optional: [{ - 'DtlsSrtpKeyAgreement': 'true' - }], - mandatory: { - OfferToReceiveAudio: true, - OfferToReceiveVideo: this.options.useVideo ? true : false, - } - }; - - if (self.options.useVideo) { - self.options.useVideo.style.display = 'none'; - } - - setCompat(); - checkCompat(); - }; - - $.FSRTC.prototype.useVideo = function(obj) { - var self = this; - - if (obj) { - self.options.useVideo = obj; - self.constraints.mandatory.OfferToReceiveVideo = true; - } else { - self.options.useVideo = null; - self.constraints.mandatory.OfferToReceiveVideo = false; - } - - if (self.options.useVideo) { - self.options.useVideo.style.display = 'none'; - } - }; - - $.FSRTC.prototype.useStereo = function(on) { - var self = this; - self.options.useStereo = on; - }; - - // Sets Opus in stereo if stereo is enabled, by adding the stereo=1 fmtp param. - $.FSRTC.prototype.stereoHack = function(sdp) { - var self = this; - - if (!self.options.useStereo) { - return sdp; - } - - var sdpLines = sdp.split('\r\n'); - - // Find opus payload. - var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000'), - opusPayload; - if (opusIndex) { - opusPayload = getCodecPayloadType(sdpLines[opusIndex]); - } - - // Find the payload in fmtp line. - var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString()); - if (fmtpLineIndex === null) return sdp; - - // Append stereo=1 to fmtp line. - sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; stereo=1'); - - sdp = sdpLines.join('\r\n'); - return sdp; - }; - - function setCompat() { - $.FSRTC.moz = !!navigator.mozGetUserMedia; - //navigator.getUserMedia || (navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia); - if (!navigator.getUserMedia) { - navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia; - } - } - - function checkCompat() { - if (!navigator.getUserMedia) { - alert('This application cannot function in this browser.'); - return false; - } - return true; - } - - function onStreamError(self) { - console.log('There has been a problem retrieving the streams - did you allow access?'); - - } - - function onStreamSuccess(self) { - console.log("Stream Success"); - } - - function onICE(self, candidate) { - self.mediaData.candidate = candidate; - self.mediaData.candidateList.push(self.mediaData.candidate); - - doCallback(self, "onICE"); - } - - function doCallback(self, func, arg) { - if (func in self.options.callbacks) { - self.options.callbacks[func](self, arg); - } - } - - function onICEComplete(self, candidate) { - console.log("ICE Complete"); - doCallback(self, "onICEComplete"); - } - - function onChannelError(self, e) { - console.error("Channel Error", e); - doCallback(self, "onError", e); - } - - function onICESDP(self, sdp) { - self.mediaData.SDP = self.stereoHack(sdp.sdp); - console.log("ICE SDP"); - doCallback(self, "onICESDP"); - } - - function onAnswerSDP(self, sdp) { - self.answer.SDP = self.stereoHack(sdp.sdp); - console.log("ICE ANSWER SDP"); - doCallback(self, "onAnswerSDP", self.answer.SDP); - } - - function onMessage(self, msg) { - console.log("Message"); - doCallback(self, "onICESDP", msg); - } - - function onRemoteStream(self, stream) { - if (self.options.useVideo) { - self.options.useVideo.style.display = 'block'; - } - - var element = self.options.useAudio; - console.log("REMOTE STREAM", stream, element); - - if (typeof element.srcObject !== 'undefined') { - element.srcObject = stream; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = stream; - } else if (typeof element.src !== 'undefined') { - element.src = URL.createObjectURL(stream); - } else { - console.error('Error attaching stream to element.'); - } - - self.options.useAudio.play(); - self.remoteStream = stream; - } - - function onOfferSDP(self, sdp) { - self.mediaData.SDP = self.stereoHack(sdp.sdp); - console.log("Offer SDP"); - doCallback(self, "onOfferSDP"); - } - - $.FSRTC.prototype.answer = function(sdp, onSuccess, onError) { - this.peer.addAnswerSDP({ - type: "answer", - sdp: sdp - }, - onSuccess, onError); - }; - - $.FSRTC.prototype.stop = function() { - var self = this; - - if (self.options.useVideo) { - self.options.useVideo.style.display = 'none'; - } - - if (self.localStream) { - self.localStream.stop(); - self.localStream = null; - } - - if (self.peer) { - console.log("stopping peer"); - self.peer.stop(); - } - }; - - $.FSRTC.prototype.createAnswer = function(sdp) { - var self = this; - self.type = "answer"; - self.remoteSDP = sdp; - console.debug("inbound sdp: ", sdp); - - function onSuccess(stream) { - self.localStream = stream; - - self.peer = RTCPeerConnection({ - type: self.type, - attachStream: self.localStream, - onICE: function(candidate) { - return onICE(self, candidate); - }, - onICEComplete: function() { - return onICEComplete(self); - }, - onRemoteStream: function(stream) { - return onRemoteStream(self, stream); - }, - onICESDP: function(sdp) { - return onICESDP(self, sdp); - }, - onChannelError: function(e) { - return onChannelError(self, e); - }, - constraints: self.constraints, - iceServers: self.options.iceServers, - offerSDP: { - type: "offer", - sdp: self.remoteSDP - } - }); - - onStreamSuccess(self); - } - - function onError() { - onStreamError(self); - } - - getUserMedia({ - constraints: { - audio: { - mandatory: this.options.audioParams, - optional: [] - }, - video: this.options.useVideo ? { - mandatory: this.options.videoParams, - optional: [] - } : null - }, - video: this.options.useVideo ? true : false, - onsuccess: onSuccess, - onerror: onError - }); - - }; - - $.FSRTC.prototype.call = function(profile) { - checkCompat(); - - var self = this; - - self.type = "offer"; - - function onSuccess(stream) { - self.localStream = stream; - - self.peer = RTCPeerConnection({ - type: self.type, - attachStream: self.localStream, - onICE: function(candidate) { - return onICE(self, candidate); - }, - onICEComplete: function() { - return onICEComplete(self); - }, - onRemoteStream: function(stream) { - return onRemoteStream(self, stream); - }, - onOfferSDP: function(sdp) { - return onOfferSDP(self, sdp); - }, - onICESDP: function(sdp) { - return onICESDP(self, sdp); - }, - onChannelError: function(e) { - return onChannelError(self, e); - }, - constraints: self.constraints, - iceServers: self.options.iceServers, - }); - - onStreamSuccess(self); - } - - function onError() { - onStreamError(self); - } - - getUserMedia({ - constraints: { - audio: { - mandatory: this.options.audioParams, - optional: [] - }, - video: this.options.useVideo ? { - mandatory: this.options.videoParams, - optional: [] - } : null - }, - video: this.options.useVideo ? true : false, - onsuccess: onSuccess, - onerror: onError - }); - - /* - navigator.getUserMedia({ - video: this.options.useVideo, - audio: true - }, onSuccess, onError); - */ - - }; - - // DERIVED from RTCPeerConnection-v1.5 - // 2013, @muazkh - github.com/muaz-khan - // MIT License - https://www.webrtc-experiment.com/licence/ - // Documentation - https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RTCPeerConnection - window.moz = !!navigator.mozGetUserMedia; - - function RTCPeerConnection(options) { - - var w = window, - PeerConnection = w.mozRTCPeerConnection || w.webkitRTCPeerConnection, - SessionDescription = w.mozRTCSessionDescription || w.RTCSessionDescription, - IceCandidate = w.mozRTCIceCandidate || w.RTCIceCandidate; - - var STUN = { - url: !moz ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121' - }; - - var TURN = { - url: 'turn:homeo@turn.bistri.com:80', - credential: 'homeo' - }; - - var iceServers = null; - - if (options.iceServers) { - var tmp = options.iceServers; - - if (typeof(tmp) === "boolean") { - tmp = null; - } - - if (!(tmp && typeof(tmp) == "object" && tmp.constructor === Array)) { - console.warn("iceServers must be an array, reverting to default ice servers"); - tmp = null; - } - - iceServers = { - iceServers: tmp || [STUN] - }; - - if (!moz && !tmp) { - if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28) TURN = { - url: 'turn:turn.bistri.com:80', - credential: 'homeo', - username: 'homeo' - }; - - iceServers.iceServers = [STUN]; - } - } - - var optional = { - optional: [] - }; - - if (!moz) { - optional.optional = [{ - DtlsSrtpKeyAgreement: true - }, - { - RtpDataChannels: options.onChannelMessage ? true : false - }]; - } - - var peer = new PeerConnection(iceServers, optional); - - openOffererChannel(); - var x = 0; - - peer.onicecandidate = function(event) { - if (event.candidate) { - options.onICE(event.candidate); - } else { - if (options.onICEComplete) { - options.onICEComplete(); - } - - if (options.type == "offer") { - if (!moz && !x && options.onICESDP) { - options.onICESDP(peer.localDescription); - //x = 1; - /* - x = 1; - peer.createOffer(function(sessionDescription) { - sessionDescription.sdp = serializeSdp(sessionDescription.sdp); - peer.setLocalDescription(sessionDescription); - if (options.onICESDP) { - options.onICESDP(sessionDescription); - } - }, onSdpError, constraints); - */ - } - } else { - if (!x && options.onICESDP) { - options.onICESDP(peer.localDescription); - //x = 1; - /* - x = 1; - peer.createAnswer(function(sessionDescription) { - sessionDescription.sdp = serializeSdp(sessionDescription.sdp); - peer.setLocalDescription(sessionDescription); - if (options.onICESDP) { - options.onICESDP(sessionDescription); - } - }, onSdpError, constraints); - */ - } - } - } - }; - - // attachStream = MediaStream; - if (options.attachStream) peer.addStream(options.attachStream); - - // attachStreams[0] = audio-stream; - // attachStreams[1] = video-stream; - // attachStreams[2] = screen-capturing-stream; - if (options.attachStreams && options.attachStream.length) { - var streams = options.attachStreams; - for (var i = 0; i < streams.length; i++) { - peer.addStream(streams[i]); - } - } - - peer.onaddstream = function(event) { - var remoteMediaStream = event.stream; - - // onRemoteStreamEnded(MediaStream) - remoteMediaStream.onended = function() { - if (options.onRemoteStreamEnded) options.onRemoteStreamEnded(remoteMediaStream); - }; - - // onRemoteStream(MediaStream) - if (options.onRemoteStream) options.onRemoteStream(remoteMediaStream); - - //console.debug('on:add:stream', remoteMediaStream); - }; - - var constraints = options.constraints || { - optional: [], - mandatory: { - OfferToReceiveAudio: true, - OfferToReceiveVideo: true - } - }; - - // onOfferSDP(RTCSessionDescription) - function createOffer() { - if (!options.onOfferSDP) return; - - peer.createOffer(function(sessionDescription) { - sessionDescription.sdp = serializeSdp(sessionDescription.sdp); - peer.setLocalDescription(sessionDescription); - options.onOfferSDP(sessionDescription); - if (moz && options.onICESDP) { - options.onICESDP(sessionDescription); - } - }, - onSdpError, constraints); - } - - // onAnswerSDP(RTCSessionDescription) - function createAnswer() { - if (options.type != "answer") return; - - //options.offerSDP.sdp = addStereo(options.offerSDP.sdp); - peer.setRemoteDescription(new SessionDescription(options.offerSDP), onSdpSuccess, onSdpError); - peer.createAnswer(function(sessionDescription) { - sessionDescription.sdp = serializeSdp(sessionDescription.sdp); - peer.setLocalDescription(sessionDescription); - if (options.onAnswerSDP) { - options.onAnswerSDP(sessionDescription); - } - }, - onSdpError, constraints); - } - - // if Mozilla Firefox & DataChannel; offer/answer will be created later - if ((options.onChannelMessage && !moz) || !options.onChannelMessage) { - createOffer(); - createAnswer(); - } - - // DataChannel Bandwidth - function setBandwidth(sdp) { - // remove existing bandwidth lines - sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, ''); - sdp = sdp.replace(/a=mid:data\r\n/g, 'a=mid:data\r\nb=AS:1638400\r\n'); - - return sdp; - } - - // old: FF<>Chrome interoperability management - function getInteropSDP(sdp) { - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), - extractedChars = ''; - - function getChars() { - extractedChars += chars[parseInt(Math.random() * 40)] || ''; - if (extractedChars.length < 40) getChars(); - - return extractedChars; - } - - // usually audio-only streaming failure occurs out of audio-specific crypto line - // a=crypto:1 AES_CM_128_HMAC_SHA1_32 --------- kAttributeCryptoVoice - if (options.onAnswerSDP) sdp = sdp.replace(/(a=crypto:0 AES_CM_128_HMAC_SHA1_32)(.*?)(\r\n)/g, ''); - - // video-specific crypto line i.e. SHA1_80 - // a=crypto:1 AES_CM_128_HMAC_SHA1_80 --------- kAttributeCryptoVideo - var inline = getChars() + '\r\n' + (extractedChars = ''); - sdp = sdp.indexOf('a=crypto') == -1 ? sdp.replace(/c=IN/g, 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:' + inline + 'c=IN') : sdp; - - return sdp; - } - - function serializeSdp(sdp) { - //if (!moz) sdp = setBandwidth(sdp); - //sdp = getInteropSDP(sdp); - //console.debug(sdp); - return sdp; - } - - // DataChannel management - var channel; - - function openOffererChannel() { - if (!options.onChannelMessage || (moz && !options.onOfferSDP)) return; - - _openOffererChannel(); - - if (!moz) return; - navigator.mozGetUserMedia({ - audio: true, - fake: true - }, - function(stream) { - peer.addStream(stream); - createOffer(); - }, - useless); - } - - function _openOffererChannel() { - channel = peer.createDataChannel(options.channel || 'RTCDataChannel', moz ? {} : { - reliable: false - }); - - if (moz) channel.binaryType = 'blob'; - - setChannelEvents(); - } - - function setChannelEvents() { - channel.onmessage = function(event) { - if (options.onChannelMessage) options.onChannelMessage(event); - }; - - channel.onopen = function() { - if (options.onChannelOpened) options.onChannelOpened(channel); - }; - channel.onclose = function(event) { - if (options.onChannelClosed) options.onChannelClosed(event); - - console.warn('WebRTC DataChannel closed', event); - }; - channel.onerror = function(event) { - if (options.onChannelError) options.onChannelError(event); - - console.error('WebRTC DataChannel error', event); - }; - } - - if (options.onAnswerSDP && moz && options.onChannelMessage) openAnswererChannel(); - - function openAnswererChannel() { - peer.ondatachannel = function(event) { - channel = event.channel; - channel.binaryType = 'blob'; - setChannelEvents(); - }; - - if (!moz) return; - navigator.mozGetUserMedia({ - audio: true, - fake: true - }, - function(stream) { - peer.addStream(stream); - createAnswer(); - }, - useless); - } - - // fake:true is also available on chrome under a flag! - function useless() { - log('Error in fake:true'); - } - - function onSdpSuccess() {} - - function onSdpError(e) { - if (options.onChannelError) { - options.onChannelError(e); - } - console.error('sdp error:', e); - } - - return { - addAnswerSDP: function(sdp, cbSuccess, cbError) { - - peer.setRemoteDescription(new SessionDescription(sdp), cbSuccess ? cbSuccess : onSdpSuccess, cbError ? cbError : onSdpError); - }, - addICE: function(candidate) { - peer.addIceCandidate(new IceCandidate({ - sdpMLineIndex: candidate.sdpMLineIndex, - candidate: candidate.candidate - })); - }, - - peer: peer, - channel: channel, - sendData: function(message) { - if (channel) { - channel.send(message); - } - }, - - stop: function() { - peer.close(); - if (options.attachStream) { - options.attachStream.stop(); - } - } - - }; - } - - // getUserMedia - var video_constraints = { - mandatory: {}, - optional: [] - }; - - function getUserMedia(options) { - var n = navigator, - media; - n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia; - n.getMedia(options.constraints || { - audio: true, - video: video_constraints - }, - streaming, options.onerror || - function(e) { - console.error(e); - }); - - function streaming(stream) { - var video = options.video; - if (video) { - video[moz ? 'mozSrcObject' : 'src'] = moz ? stream : window.webkitURL.createObjectURL(stream); - //video.play(); - } - if (options.onsuccess) { - options.onsuccess(stream); - } - media = stream; - } - - return media; - } - -})(jQuery); -/* - * Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is jquery.jsonrpclient.js modified for Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH - * - * The Initial Developer of the Original Code is - * Textalk AB http://textalk.se/ - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * jquery.jsonrpclient.js - JSON RPC client code - * - */ -/** - * This plugin requires jquery.json.js to be available, or at least the methods $.toJSON and - * $.parseJSON. - * - * The plan is to make use of websockets if they are available, but work just as well with only - * http if not. - * - * Usage example: - * - * var foo = new $.JsonRpcClient({ ajaxUrl: '/backend/jsonrpc' }); - * foo.call( - * 'bar', [ 'A parameter', 'B parameter' ], - * function(result) { alert('Foo bar answered: ' + result.my_answer); }, - * function(error) { console.log('There was an error', error); } - * ); - * - * More examples are available in README.md - */ -(function($) { - /** - * @fn new - * @memberof $.JsonRpcClient - * - * @param options An object stating the backends: - * ajaxUrl A url (relative or absolute) to a http(s) backend. - * socketUrl A url (relative of absolute) to a ws(s) backend. - * onmessage A socket message handler for other messages (non-responses). - * getSocket A function returning a WebSocket or null. - * It must take an onmessage_cb and bind it to the onmessage event - * (or chain it before/after some other onmessage handler). - * Or, it could return null if no socket is available. - * The returned instance must have readyState <= 1, and if less than 1, - * react to onopen binding. - */ - $.JsonRpcClient = function(options) { - var self = this; - this.options = $.extend({ - ajaxUrl : null, - socketUrl : null, ///< The ws-url for default getSocket. - onmessage : null, ///< Other onmessage-handler. - login : null, /// auth login - passwd : null, /// auth passwd - sessid : null, - getSocket : function(onmessage_cb) { return self._getSocket(onmessage_cb); } - }, options); - - self.ws_cnt = 0; - - // Declare an instance version of the onmessage callback to wrap 'this'. - this.wsOnMessage = function(event) { self._wsOnMessage(event); }; - }; - - /// Holding the WebSocket on default getsocket. - $.JsonRpcClient.prototype._ws_socket = null; - - /// Object : { success_cb: cb, error_cb: cb } - $.JsonRpcClient.prototype._ws_callbacks = {}; - - /// The next JSON-RPC request id. - $.JsonRpcClient.prototype._current_id = 1; - - /** - * @fn call - * @memberof $.JsonRpcClient - * - * @param method The method to run on JSON-RPC server. - * @param params The params; an array or object. - * @param success_cb A callback for successful request. - * @param error_cb A callback for error. - */ - $.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) { - // Construct the JSON-RPC 2.0 request. - - 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++ // Increase the id counter to match request/response - }; - - if (!success_cb) { - success_cb = function(e){console.log("Success: ", e);}; - } - - if (!error_cb) { - error_cb = function(e){console.log("Error: ", e);}; - } - - // Try making a WebSocket call. - var socket = this.options.getSocket(this.wsOnMessage); - if (socket !== null) { - this._wsCall(socket, request, success_cb, error_cb); - return; - } - - // No WebSocket, and no HTTP backend? This won't work. - if (this.options.ajaxUrl === null) { - throw "$.JsonRpcClient.call used with no websocket and no http endpoint."; - } - - $.ajax({ - type : 'POST', - url : this.options.ajaxUrl, - data : $.toJSON(request), - dataType : 'json', - cache : false, - - success : function(data) { - if ('error' in data) error_cb(data.error, this); - success_cb(data.result, this); - }, - - // JSON-RPC Server could return non-200 on error - error : function(jqXHR, textStatus, errorThrown) { - try { - var response = $.parseJSON(jqXHR.responseText); - - if ('console' in window) console.log(response); - - error_cb(response.error, this); - } catch (err) { - // Perhaps the responseText wasn't really a jsonrpc-error. - error_cb({ error: jqXHR.responseText }, this); - } - } - }); - }; - - /** - * Notify sends a command to the server that won't need a response. In http, there is probably - * an empty response - that will be dropped, but in ws there should be no response at all. - * - * This is very similar to call, but has no id and no handling of callbacks. - * - * @fn notify - * @memberof $.JsonRpcClient - * - * @param method The method to run on JSON-RPC server. - * @param params The params; an array or object. - */ - $.JsonRpcClient.prototype.notify = function(method, params) { - // Construct the JSON-RPC 2.0 request. - - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - var request = { - jsonrpc: '2.0', - method: method, - params: params - }; - - // Try making a WebSocket call. - var socket = this.options.getSocket(this.wsOnMessage); - if (socket !== null) { - this._wsCall(socket, request); - return; - } - - // No WebSocket, and no HTTP backend? This won't work. - if (this.options.ajaxUrl === null) { - throw "$.JsonRpcClient.notify used with no websocket and no http endpoint."; - } - - $.ajax({ - type : 'POST', - url : this.options.ajaxUrl, - data : $.toJSON(request), - dataType : 'json', - cache : false - }); - }; - - /** - * Make a batch-call by using a callback. - * - * The callback will get an object "batch" as only argument. On batch, you can call the methods - * "call" and "notify" just as if it was a normal $.JsonRpcClient object, and all calls will be - * sent as a batch call then the callback is done. - * - * @fn batch - * @memberof $.JsonRpcClient - * - * @param callback The main function which will get a batch handler to run call and notify on. - * @param all_done_cb A callback function to call after all results have been handled. - * @param error_cb A callback function to call if there is an error from the server. - * Note, that batch calls should always get an overall success, and the - * only error - */ - $.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) { - var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb); - callback(batch); - batch._execute(); - }; - - /** - * The default getSocket handler. - * - * @param onmessage_cb The callback to be bound to onmessage events on the socket. - * - * @fn _getSocket - * @memberof $.JsonRpcClient - */ - - $.JsonRpcClient.prototype.socketReady = function() { - if (this._ws_socket === null || this._ws_socket.readyState > 1) { - return false; - } - - return true; - }; - - $.JsonRpcClient.prototype.closeSocket = function() { - if (self.socketReady()) { - this._ws_socket.onclose = function (w) {console.log("Closing Socket");}; - this._ws_socket.close(); - } - }; - - $.JsonRpcClient.prototype.loginData = function(params) { - self.options.login = params.login; - self.options.passwd = params.passwd; - }; - - $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { - var self = this; - - if (self.to) { - clearTimeout(self.to); - } - - if (!self.socketReady()) { - self.authing = false; - - if (self._ws_socket) { - delete self._ws_socket; - } - - // No socket, or dying socket, let's get a new one. - self._ws_socket = new WebSocket(self.options.socketUrl); - - if (self._ws_socket) { - // Set up onmessage handler. - self._ws_socket.onmessage = onmessage_cb; - self._ws_socket.onclose = function (w) { - if (!self.ws_sleep) { - self.ws_sleep = 1000; - } - - if (self.options.onWSClose) { - self.options.onWSClose(self); - } - - console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec"); - - self.to = setTimeout(function() { - console.log("Attempting Reconnection...."); - self.connectSocket(onmessage_cb); - }, self.ws_sleep); - - self.ws_cnt++; - - if (self.ws_sleep < 3000 && (self.ws_cnt % 10) === 0) { - self.ws_sleep += 1000; - } - }; - - // Set up sending of message for when the socket is open. - self._ws_socket.onopen = function() { - if (self.to) { - clearTimeout(self.to); - } - self.ws_sleep = 1000; - self.ws_cnt = 0; - if (self.options.onWSConnect) { - self.options.onWSConnect(self); - } - - var req; - // Send the requests. - while ((req = $.JsonRpcClient.q.pop())) { - self._ws_socket.send(req); - } - }; - } - } - - return self._ws_socket ? true : false; - }; - - $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { - // If there is no ws url set, we don't have a socket. - // Likewise, if there is no window.WebSocket. - if (this.options.socketUrl === null || !("WebSocket" in window)) return null; - - this.connectSocket(onmessage_cb); - - return this._ws_socket; - }; - - /** - * Queue to save messages delivered when websocket is not ready - */ - $.JsonRpcClient.q = []; - - /** - * Internal handler to dispatch a JRON-RPC request through a websocket. - * - * @fn _wsCall - * @memberof $.JsonRpcClient - */ - $.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) { - var request_json = $.toJSON(request); - - if (socket.readyState < 1) { - // The websocket is not open yet; we have to set sending of the message in onopen. - self = this; // In closure below, this is set to the WebSocket. Use self instead. - $.JsonRpcClient.q.push(request_json); - } else { - // We have a socket and it should be ready to send on. - socket.send(request_json); - } - - // Setup callbacks. If there is an id, this is a call and not a notify. - 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 }; - } - }; - - /** - * Internal handler for the websocket messages. It determines if the message is a JSON-RPC - * response, and if so, tries to couple it with a given callback. Otherwise, it falls back to - * given external onmessage-handler, if any. - * - * @param event The websocket onmessage-event. - */ - $.JsonRpcClient.prototype._wsOnMessage = function(event) { - // Check if this could be a JSON RPC message. - var response; - try { - response = $.parseJSON(event.data); - - /// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends. - - if (typeof response === 'object' && - 'jsonrpc' in response && - response.jsonrpc === '2.0') { - - /// @todo Handle bad response (without id). - - // If this is an object with result, it is a response. - if ('result' in response && this._ws_callbacks[response.id]) { - // Get the success callback. - var success_cb = this._ws_callbacks[response.id].success_cb; - - /* - // set the sessid if present - if ('sessid' in response.result && !this.options.sessid || (this.options.sessid != response.result.sessid)) { - this.options.sessid = response.result.sessid; - if (this.options.sessid) { - console.log("setting session UUID to: " + this.options.sessid); - } - } - */ - // Delete the callback from the storage. - delete this._ws_callbacks[response.id]; - - // Run callback with result as parameter. - success_cb(response.result, this); - return; - } else if ('error' in response && this._ws_callbacks[response.id]) { - // If this is an object with error, it is an error response. - - // Get the error callback. - var error_cb = this._ws_callbacks[response.id].error_cb; - var orig_req = this._ws_callbacks[response.id].request; - - // if this is an auth request, send the credentials and resend the failed 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}, - 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 the callback from the storage. - delete this._ws_callbacks[response.id]; - - // Run callback with the error object as parameter. - error_cb(response.error, this); - return; - } - } - } catch (err) { - // Probably an error while parsing a non json-string as json. All real JSON-RPC cases are - // handled above, and the fallback method is called below. - console.log("ERROR: "+ err); - return; - } - - // This is not a JSON-RPC response. Call the fallback message handler, if given. - if (typeof this.options.onmessage === 'function') { - event.eventData = response; - if (!event.eventData) { - event.eventData = {}; - } - - var reply = this.options.onmessage(event); - - if (reply && typeof reply === "object" && event.eventData.id) { - var msg = { - jsonrpc: "2.0", - id: event.eventData.id, - result: reply - }; - - var socket = self.options.getSocket(self.wsOnMessage); - if (socket !== null) { - socket.send($.toJSON(msg)); - } - } - } - }; - - - /************************************************************************************************ - * Batch object with methods - ************************************************************************************************/ - - /** - * Handling object for batch calls. - */ - $.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) { - // Array of objects to hold the call and notify requests. Each objects will have the request - // object, and unless it is a notify, success_cb and error_cb. - this._requests = []; - - this.jsonrpcclient = jsonrpcclient; - this.all_done_cb = all_done_cb; - this.error_cb = typeof error_cb === 'function' ? error_cb : function() {}; - - }; - - /** - * @sa $.JsonRpcClient.prototype.call - */ - $.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) { - - if (!params) { - params = {}; - } - - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - if (!success_cb) { - success_cb = function(e){console.log("Success: ", e);}; - } - - if (!error_cb) { - error_cb = function(e){console.log("Error: ", e);}; - } - - this._requests.push({ - request : { - jsonrpc : '2.0', - method : method, - params : params, - id : this.jsonrpcclient._current_id++ // Use the client's id series. - }, - success_cb : success_cb, - error_cb : error_cb - }); - }; - - /** - * @sa $.JsonRpcClient.prototype.notify - */ - $.JsonRpcClient._batchObject.prototype.notify = function(method, params) { - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - this._requests.push({ - request : { - jsonrpc : '2.0', - method : method, - params : params - } - }); - }; - - /** - * Executes the batched up calls. - */ - $.JsonRpcClient._batchObject.prototype._execute = function() { - var self = this; - - if (this._requests.length === 0) return; // All done :P - - // Collect all request data and sort handlers by request id. - var batch_request = []; - var handlers = {}; - var i = 0; - var call; - var success_cb; - var error_cb; - - // If we have a WebSocket, just send the requests individually like normal calls. - var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); - if (socket !== null) { - for (i = 0; i < this._requests.length; i++) { - call = this._requests[i]; - success_cb = ('success_cb' in call) ? call.success_cb : undefined; - error_cb = ('error_cb' in call) ? call.error_cb : undefined; - self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); - } - - if (typeof all_done_cb === 'function') all_done_cb(result); - return; - } - - for (i = 0; i < this._requests.length; i++) { - call = this._requests[i]; - batch_request.push(call.request); - - // If the request has an id, it should handle returns (otherwise it's a notify). - if ('id' in call.request) { - handlers[call.request.id] = { - success_cb : call.success_cb, - error_cb : call.error_cb - }; - } - } - - success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); }; - - // No WebSocket, and no HTTP backend? This won't work. - if (self.jsonrpcclient.options.ajaxUrl === null) { - throw "$.JsonRpcClient.batch used with no websocket and no http endpoint."; - } - - // Send request - $.ajax({ - url : self.jsonrpcclient.options.ajaxUrl, - data : $.toJSON(batch_request), - dataType : 'json', - cache : false, - type : 'POST', - - // Batch-requests should always return 200 - error : function(jqXHR, textStatus, errorThrown) { - self.error_cb(jqXHR, textStatus, errorThrown); - }, - success : success_cb - }); - }; - - /** - * Internal helper to match the result array from a batch call to their respective callbacks. - * - * @fn _batchCb - * @memberof $.JsonRpcClient - */ - $.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) { - for (var i = 0; i < result.length; i++) { - var response = result[i]; - - // Handle error - if ('error' in response) { - if (response.id === null || !(response.id in handlers)) { - // An error on a notify? Just log it to the console. - if ('console' in window) console.log(response); - } else { - handlers[response.id].error_cb(response.error, this); - } - } else { - // Here we should always have a correct id and no error. - if (!(response.id in handlers) && 'console' in window) { - console.log(response); - } else { - handlers[response.id].success_cb(response.result, this); - } - } - } - - if (typeof all_done_cb === 'function') all_done_cb(result); - }; - -})(jQuery); - -/* - * Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Verto HTML5/Javascript Telephony Signaling and Control Protocol Stack for FreeSWITCH - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * jquery.verto.js - Main interface - * - */ - -(function($) { - - var generateGUID = (typeof(window.crypto) !== 'undefined' && typeof(window.crypto.getRandomValues) !== 'undefined') ? - function() { - // If we have a cryptographically secure PRNG, use that - // http://stackoverflow.com/questions/6906916/collisions-when-generating-uuids-in-javascript - var buf = new Uint16Array(8); - window.crypto.getRandomValues(buf); - var S4 = function(num) { - var ret = num.toString(16); - while (ret.length < 4) { - ret = "0" + ret; - } - return ret; - }; - return (S4(buf[0]) + S4(buf[1]) + "-" + S4(buf[2]) + "-" + S4(buf[3]) + "-" + S4(buf[4]) + "-" + S4(buf[5]) + S4(buf[6]) + S4(buf[7])); - } - - : - - function() { - // Otherwise, just use Math.random - // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = Math.random() * 16 | 0, - v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - }; - - /// MASTER OBJ - $.verto = function(options, callbacks) { - var verto = this; - - $.verto.saved.push(verto); - - verto.options = $.extend({ - login: null, - passwd: null, - socketUrl: null, - tag: null, - videoParams: {}, - audioParams: {}, - iceServers: false, - ringSleep: 6000 - }, options); - - verto.sessid = $.cookie('verto_session_uuid') || generateGUID(); - $.cookie('verto_session_uuid', verto.sessid, { - expires: 1 - }); - - verto.dialogs = {}; - verto.callbacks = callbacks || {}; - verto.eventSUBS = {}; - - verto.rpcClient = new $.JsonRpcClient({ - login: verto.options.login, - passwd: verto.options.passwd, - socketUrl: verto.options.socketUrl, - sessid: verto.sessid, - onmessage: function(e) { - return verto.handleMessage(e.eventData); - }, - onWSConnect: function(o) { - o.call('login', {}); - }, - onWSLogin: function(success) { - if (verto.callbacks.onWSLogin) { - verto.callbacks.onWSLogin(verto, success); - } - }, - onWSClose: function(success) { - if (verto.callbacks.onWSClose) { - verto.callbacks.onWSClose(verto, success); - } - verto.purge(); - } - }); - - if (verto.options.ringFile && verto.options.tag) { - verto.ringer = $("#" + verto.options.tag); - } - - verto.rpcClient.call('login', {}); - - }; - - $.verto.prototype.iceServers = function(on) { - var verto = this; - verto.options.iceServers = on; - }; - - $.verto.prototype.loginData = function(params) { - verto.options.login = params.login; - verto.options.passwd = params.passwd; - verto.rpcClient.loginData(params); - }; - - $.verto.prototype.logout = function(msg) { - var verto = this; - verto.rpcClient.closeSocket(); - verto.purge(); - }; - - $.verto.prototype.login = function(msg) { - var verto = this; - verto.logout(); - verto.rpcClient.call('login', {}); - }; - - $.verto.prototype.message = function(msg) { - var verto = this; - var err = 0; - - if (!msg.to) { - console.error("Missing To"); - err++; - } - - if (!msg.body) { - console.error("Missing Body"); - err++; - } - - if (err) { - return false; - } - - verto.sendMethod("verto.info", { - msg: msg - }); - - return true; - }; - - $.verto.prototype.processReply = function(method, success, e) { - var verto = this; - var i; - - //console.log("Response: " + method, success, e); - - switch (method) { - case "verto.subscribe": - for (i in e.unauthorizedChannels) { - drop_bad(verto, e.unauthorizedChannels[i]); - } - for (i in e.subscribedChannels) { - mark_ready(verto, e.subscribedChannels[i]); - } - - break; - case "verto.unsubscribe": - //console.error(e); - break; - } - }; - - $.verto.prototype.sendMethod = function(method, params) { - var verto = this; - - verto.rpcClient.call(method, params, - - function(e) { - /* Success */ - verto.processReply(method, true, e); - }, - - function(e) { - /* Error */ - verto.processReply(method, false, e); - }); - }; - - function do_sub(verto, channel, obj) { - - } - - function drop_bad(verto, channel) { - console.error("drop unauthorized channel: " + channel); - delete verto.eventSUBS[channel]; - } - - function mark_ready(verto, channel) { - for (var j in verto.eventSUBS[channel]) { - verto.eventSUBS[channel][j].ready = true; - console.log("subscribed to channel: " + channel); - if (verto.eventSUBS[channel][j].readyHandler) { - verto.eventSUBS[channel][j].readyHandler(verto, channel); - } - } - } - - var SERNO = 1; - - function do_subscribe(verto, channel, subChannels, sparams) { - var params = sparams || {}; - - var local = params.local; - - var obj = { - eventChannel: channel, - userData: params.userData, - handler: params.handler, - ready: false, - readyHandler: params.readyHandler, - serno: SERNO++ - }; - - var isnew = false; - - if (!verto.eventSUBS[channel]) { - verto.eventSUBS[channel] = []; - subChannels.push(channel); - isnew = true; - } - - verto.eventSUBS[channel].push(obj); - - if (local) { - obj.ready = true; - obj.local = true; - } - - if (!isnew && verto.eventSUBS[channel][0].ready) { - obj.ready = true; - if (obj.readyHandler) { - obj.readyHandler(verto, channel); - } - } - - return { - serno: obj.serno, - eventChannel: channel - }; - - } - - $.verto.prototype.subscribe = function(channel, sparams) { - var verto = this; - var r = []; - var subChannels = []; - var params = sparams || {}; - - if (typeof(channel) === "string") { - r.push(do_subscribe(verto, channel, subChannels, params)); - } else { - for (var i in channel) { - r.push(do_subscribe(verto, channel, subChannels, params)); - } - } - - if (subChannels.length) { - verto.sendMethod("verto.subscribe", { - eventChannel: subChannels.length == 1 ? subChannels[0] : subChannels, - subParams: params.subParams - }); - } - - return r; - }; - - $.verto.prototype.unsubscribe = function(handle) { - var verto = this; - var i; - - if (!handle) { - for (i in verto.eventSUBS) { - if (verto.eventSUBS[i]) { - verto.unsubscribe(verto.eventSUBS[i]); - } - } - } else { - var unsubChannels = {}; - var sendChannels = []; - var channel; - - if (typeof(handle) == "string") { - delete verto.eventSUBS[handle]; - unsubChannels[handle]++; - } else { - for (i in handle) { - if (typeof(handle[i]) == "string") { - channel = handle[i]; - delete verto.eventSUBS[channel]; - unsubChannels[channel]++; - } else { - var repl = []; - channel = handle[i].eventChannel; - - for (var j in verto.eventSUBS[channel]) { - if (verto.eventSUBS[channel][j].serno == handle[i].serno) {} else { - repl.push(verto.eventSUBS[channel][j]); - } - } - - verto.eventSUBS[channel] = repl; - - if (verto.eventSUBS[channel].length === 0) { - delete verto.eventSUBS[channel]; - unsubChannels[channel]++; - } - } - } - } - - for (var u in unsubChannels) { - console.log("Sending Unsubscribe for: ", u); - sendChannels.push(u); - } - - if (sendChannels.length) { - verto.sendMethod("verto.unsubscribe", { - eventChannel: sendChannels.length == 1 ? sendChannels[0] : sendChannels - }); - } - } - }; - - $.verto.prototype.broadcast = function(channel, params) { - var verto = this; - var msg = { - eventChannel: channel, - data: {} - }; - for (var i in params) { - msg.data[i] = params[i]; - } - verto.sendMethod("verto.broadcast", msg); - }; - - $.verto.prototype.purge = function(callID) { - var verto = this; - var x = 0; - var i; - - for (i in verto.dialogs) { - if (!x) { - console.log("purging dialogs"); - } - x++; - verto.dialogs[i].setState($.verto.enum.state.purge); - } - - for (i in verto.eventSUBS) { - if (verto.eventSUBS[i]) { - console.log("purging subscription: " + i); - delete verto.eventSUBS[i]; - } - } - }; - - $.verto.prototype.hangup = function(callID) { - var verto = this; - if (callID) { - var dialog = verto.dialogs[callID]; - - if (dialog) { - dialog.hangup(); - } - } else { - for (var i in verto.dialogs) { - verto.dialogs[i].hangup(); - } - } - }; - - $.verto.prototype.newCall = function(args, callbacks) { - var verto = this; - - if (!verto.rpcClient.socketReady()) { - console.error("Not Connected..."); - return; - } - - var dialog = new $.verto.dialog($.verto.enum.direction.outbound, this, args); - - dialog.invite(); - - if (callbacks) { - dialog.callbacks = callbacks; - } - - return dialog; - }; - - $.verto.prototype.handleMessage = function(data) { - var verto = this; - - if (!(data && data.method)) { - console.error("Invalid Data", data); - return; - } - - if (data.params.callID) { - var dialog = verto.dialogs[data.params.callID]; - - if (dialog) { - - switch (data.method) { - case 'verto.bye': - dialog.hangup(data.params); - break; - case 'verto.answer': - dialog.handleAnswer(data.params); - break; - case 'verto.media': - dialog.handleMedia(data.params); - break; - case 'verto.display': - dialog.handleDisplay(data.params); - break; - case 'verto.info': - dialog.handleInfo(data.params); - break; - default: - console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", dialog, data.method); - break; - } - } else { - - switch (data.method) { - case 'verto.attach': - data.params.attach = true; - - if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { - data.params.useVideo = true; - } - - if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { - data.params.useStereo = true; - } - - dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); - dialog.setState($.verto.enum.state.recovering); - - break; - case 'verto.invite': - - if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { - data.params.wantVideo = true; - } - - if (data.params.sdp && data.params.sdp.indexOf("stereo=1") > 0) { - data.params.useStereo = true; - } - - dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); - break; - default: - console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED"); - break; - } - } - - return { - method: data.method - }; - } else { - switch (data.method) { - case 'verto.event': - var list = null; - var key = null; - - if (data.params) { - key = data.params.eventChannel; - } - - if (key) { - list = verto.eventSUBS[key]; - - if (!list) { - list = verto.eventSUBS[key.split(".")[0]]; - } - } - - if (!list && key && key === verto.sessid) { - if (verto.callbacks.onMessage) { - verto.callbacks.onMessage(verto, null, $.verto.enum.message.pvtEvent, data.params); - } - } else if (!list && key && verto.dialogs[key]) { - verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent, data.params); - } else if (!list) { - if (!key) { - key = "UNDEFINED"; - } - console.error("UNSUBBED or invalid EVENT " + key + " IGNORED"); - } else { - for (var i in list) { - var sub = list[i]; - - if (!sub || !sub.ready) { - console.error("invalid EVENT for " + key + " IGNORED"); - } else if (sub.handler) { - sub.handler(verto, data.params, sub.userData); - } else if (verto.callbacks.onEvent) { - verto.callbacks.onEvent(verto, data.params, sub.userData); - } else { - console.log("EVENT:", data.params); - } - } - } - - break; - - case "verto.info": - if (verto.callbacks.onMessage) { - verto.callbacks.onMessage(verto, null, $.verto.enum.message.info, data.params.msg); - } - //console.error(data); - console.debug("MESSAGE from: " + data.params.msg.from, data.params.msg.body); - - break; - - default: - console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED", data.method); - break; - } - } - }; - - var del_array = function(array, name) { - var r = []; - var len = array.length; - - for (var i = 0; i < len; i++) { - if (array[i] != name) { - r.push(array[i]); - } - } - - return r; - }; - - var hashArray = function() { - var vha = this; - - var hash = {}; - var array = []; - - vha.reorder = function(a) { - array = a; - var h = hash; - hash = {}; - - var len = array.length; - - for (var i = 0; i < len; i++) { - var key = array[i]; - if (h[key]) { - hash[key] = h[key]; - delete h[key]; - } - } - h = undefined; - }; - - vha.clear = function() { - hash = undefined; - array = undefined; - hash = {}; - array = []; - }; - - vha.add = function(name, val, insertAt) { - var redraw = false; - - if (!hash[name]) { - if (insertAt === undefined || insertAt < 0 || insertAt >= array.length) { - array.push(name); - } else { - var x = 0; - var n = []; - var len = array.length; - - for (var i = 0; i < len; i++) { - if (x++==insertAt) { - n.push(name); - } - n.push(array[i]); - } - - array = undefined; - array = n; - n = undefined; - redraw = true; - } - } - - hash[name] = val; - - return redraw; - }; - - vha.del = function(name) { - var r = false; - - if (hash[name]) { - array = del_array(array, name); - delete hash[name]; - r = true; - } else { - console.error("can't del nonexistant key " + name); - } - - return r; - }; - - vha.get = function(name) { - return hash[name]; - }; - - vha.order = function() { - return array; - }; - - vha.hash = function() { - return hash; - }; - - vha.indexOf = function(name) { - var len = array.length; - - for (var i = 0; i < len; i++) { - if (array[i] == name) { - return i; - } - } - }; - - vha.arrayLen = function() { - return array.length; - }; - - vha.asArray = function() { - var r = []; - - var len = array.length; - - for (var i = 0; i < len; i++) { - var key = array[i]; - r.push(hash[key]); - } - - return r; - }; - - vha.each = function(cb) { - var len = array.length; - - for (var i = 0; i < len; i++) { - cb(array[i], hash[array[i]]); - } - }; - - vha.dump = function(html) { - var str = ""; - - vha.each(function(name, val) { - str += "name: " + name + " val: " + JSON.stringify(val) + (html ? "
" : "\n"); - }); - - return str; - }; - - }; - - $.verto.liveArray = function(verto, context, name, config) { - var la = this; - var lastSerno = 0; - var binding = null; - var user_obj = config.userObj; - var local = false; - - // Inherit methods of hashArray - hashArray.call(la); - - // Save the hashArray add, del, reorder, clear methods so we can make our own. - la._add = la.add; - la._del = la.del; - la._reorder = la.reorder; - la._clear = la.clear; - - la.context = context; - la.name = name; - la.user_obj = user_obj; - - la.verto = verto; - la.broadcast = function(channel, obj) { - verto.broadcast(channel, obj); - }; - la.errs = 0; - - la.clear = function() { - la._clear(); - lastSerno = 0; - - if (la.onChange) { - la.onChange(la, { - action: "clear" - }); - } - }; - - la.checkSerno = function(serno) { - if (serno < 0) { - return true; - } - - if (lastSerno > 0 && serno != (lastSerno + 1)) { - if (la.onErr) { - la.onErr(la, { - lastSerno: lastSerno, - serno: serno - }); - } - la.errs++; - console.debug(la.errs); - if (la.errs < 3) { - la.bootstrap(la.user_obj); - } - return false; - } else { - lastSerno = serno; - return true; - } - }; - - la.reorder = function(serno, a) { - if (la.checkSerno(serno)) { - la._reorder(a); - if (la.onChange) { - la.onChange(la, { - serno: serno, - action: "reorder" - }); - } - } - }; - - la.init = function(serno, val, key, index) { - if (key === null || key === undefined) { - key = serno; - } - if (la.checkSerno(serno)) { - if (la.onChange) { - la.onChange(la, { - serno: serno, - action: "init", - index: index, - key: key, - data: val - }); - } - } - }; - - la.bootObj = function(serno, val) { - if (la.checkSerno(serno)) { - - //la.clear(); - for (var i in val) { - la._add(val[i][0], val[i][1]); - } - - if (la.onChange) { - la.onChange(la, { - serno: serno, - action: "bootObj", - data: val, - redraw: true - }); - } - } - }; - - // @param serno La is the serial number for la particular request. - // @param key If looking at it as a hash table, la represents the key in the hashArray object where you want to store the val object. - // @param index If looking at it as an array, la represents the position in the array where you want to store the val object. - // @param val La is the object you want to store at the key or index location in the hash table / array. - la.add = function(serno, val, key, index) { - if (key === null || key === undefined) { - key = serno; - } - if (la.checkSerno(serno)) { - var redraw = la._add(key, val, index); - if (la.onChange) { - la.onChange(la, { - serno: serno, - action: "add", - index: index, - key: key, - data: val, - redraw: redraw - }); - } - } - }; - - la.modify = function(serno, val, key, index) { - if (key === null || key === undefined) { - key = serno; - } - if (la.checkSerno(serno)) { - la._add(key, val, index); - if (la.onChange) { - la.onChange(la, { - serno: serno, - action: "modify", - key: key, - data: val, - index: index - }); - } - } - }; - - la.del = function(serno, key, index) { - if (key === null || key === undefined) { - key = serno; - } - if (la.checkSerno(serno)) { - if (index === null || index < 0 || index === undefined) { - index = la.indexOf(key); - } - var ok = la._del(key); - - if (ok && la.onChange) { - la.onChange(la, { - serno: serno, - action: "del", - key: key, - index: index - }); - } - } - }; - - var eventHandler = function(v, e, la) { - var packet = e.data; - - //console.error("READ:", packet); - - if (packet.name != la.name) { - return; - } - - switch (packet.action) { - - case "init": - la.init(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); - break; - - case "bootObj": - la.bootObj(packet.wireSerno, packet.data); - break; - case "add": - la.add(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); - break; - - case "modify": - if (! (packet.arrIndex || packet.hashKey)) { - console.error("Invalid Packet", packet); - } else { - la.modify(packet.wireSerno, packet.data, packet.hashKey, packet.arrIndex); - } - break; - case "del": - if (! (packet.arrIndex || packet.hashKey)) { - console.error("Invalid Packet", packet); - } else { - la.del(packet.wireSerno, packet.hashKey, packet.arrIndex); - } - break; - - case "clear": - la.clear(); - break; - - case "reorder": - la.reorder(packet.wireSerno, packet.order); - break; - - default: - if (la.checkSerno(packet.wireSerno)) { - if (la.onChange) { - la.onChange(la, { - serno: packet.wireSerno, - action: packet.action, - data: packet.data - }); - } - } - break; - } - }; - - if (la.context) { - binding = la.verto.subscribe(la.context, { - handler: eventHandler, - userData: la, - subParams: config.subParams - }); - } - - la.destroy = function() { - la._clear(); - la.verto.unsubscribe(binding); - }; - - la.sendCommand = function(cmd, obj) { - var self = la; - self.broadcast(self.context, { - liveArray: { - command: cmd, - context: self.context, - name: self.name, - obj: obj - } - }); - }; - - la.bootstrap = function(obj) { - var self = la; - la.sendCommand("bootstrap", obj); - //self.heartbeat(); - }; - - la.changepage = function(obj) { - var self = la; - self.clear(); - self.broadcast(self.context, { - liveArray: { - command: "changepage", - context: la.context, - name: la.name, - obj: obj - } - }); - }; - - la.heartbeat = function(obj) { - var self = la; - - var callback = function() { - self.heartbeat.call(self, obj); - }; - self.broadcast(self.context, { - liveArray: { - command: "heartbeat", - context: self.context, - name: self.name, - obj: obj - } - }); - self.hb_pid = setTimeout(callback, 30000); - }; - - la.bootstrap(la.user_obj); - }; - - $.verto.liveTable = function(verto, context, name, jq, config) { - var dt; - var la = new $.verto.liveArray(verto, context, name, { - subParams: config.subParams - }); - var lt = this; - - lt.liveArray = la; - lt.dataTable = dt; - lt.verto = verto; - - lt.destroy = function() { - if (dt) { - dt.fnDestroy(); - } - if (la) { - la.destroy(); - } - - dt = null; - la = null; - }; - - la.onErr = function(obj, args) { - console.error("Error: ", obj, args); - }; - - la.onChange = function(obj, args) { - var index = 0; - var iserr = 0; - - if (!dt) { - if (!config.aoColumns) { - if (args.action != "init") { - return; - } - - config.aoColumns = []; - - for (var i in args.data) { - config.aoColumns.push({ - "sTitle": args.data[i] - }); - } - } - - dt = jq.dataTable(config); - } - - if (dt && (args.action == "del" || args.action == "modify")) { - index = args.index; - - if (index === undefined && args.key) { - index = la.indexOf(args.key); - } - - if (index === undefined) { - console.error("INVALID PACKET Missing INDEX\n", args); - return; - } - } - - if (config.onChange) { - config.onChange(obj, args); - } - - try { - switch (args.action) { - case "bootObj": - if (!args.data) { - console.error("missing data"); - return; - } - dt.fnClearTable(); - dt.fnAddData(obj.asArray()); - dt.fnAdjustColumnSizing(); - break; - case "add": - if (!args.data) { - console.error("missing data"); - return; - } - if (args.redraw > -1) { - // specific position, more costly - dt.fnClearTable(); - dt.fnAddData(obj.asArray()); - } else { - dt.fnAddData(args.data); - } - dt.fnAdjustColumnSizing(); - break; - case "modify": - if (!args.data) { - return; - } - //console.debug(args, index); - dt.fnUpdate(args.data, index); - dt.fnAdjustColumnSizing(); - break; - case "del": - dt.fnDeleteRow(index); - dt.fnAdjustColumnSizing(); - break; - case "clear": - dt.fnClearTable(); - break; - case "reorder": - // specific position, more costly - dt.fnClearTable(); - dt.fnAddData(obj.asArray()); - break; - case "hide": - jq.hide(); - break; - - case "show": - jq.show(); - break; - - } - } catch(err) { - console.error("ERROR: " + err); - iserr++; - } - - if (iserr) { - obj.errs++; - if (obj.errs < 3) { - obj.bootstrap(obj.user_obj); - } - } else { - obj.errs = 0; - } - - }; - - la.onChange(la, { - action: "init" - }); - - }; - - var CONFMAN_SERNO = 1; - - $.verto.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++; - - function genMainMod(jq) { - var play_id = "play_" + confMan.serno; - var stop_id = "stop_" + confMan.serno; - var recording_id = "recording_" + confMan.serno; - var rec_stop_id = "recording_stop" + confMan.serno; - var div_id = "confman_" + confMan.serno; - - var html = "

" + - "" + - "" + - "" + - "" + - "

"; - - jq.html(html); - - $("#" + play_id).click(function() { - var file = prompt("Please enter file name", ""); - 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", ""); - 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 tmute_id = "tmute_" + 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 = "
" + - "" + - "" + - "" + - "" + - "" + - "
" - ; - - 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"); - confMan.modCommand("transfer", x, xten); - }); - - $("#" + kick_id).click(function() { - confMan.modCommand("kick", x); - }); - - $("#" + tmute_id).click(function() { - confMan.modCommand("tmute", x); - }); - - $("#" + volup_id).click(function() { - confMan.modCommand("volume_in", x, "up"); - }); - - $("#" + voldn_id).click(function() { - confMan.modCommand("volume_in", x, "down"); - }); - - return html; - } - - var atitle = ""; - var awidth = 0; - - //$(".jsDataTable").width(confMan.params.hasVid ? "900px" : "800px"); - - if (confMan.params.laData.role === "moderator") { - atitle = "Action"; - awidth = 200; - - if (confMan.params.mainModID) { - genMainMod($(confMan.params.mainModID)); - $(confMan.params.displayID).html("Moderator Controls Ready

"); - } else { - $(confMan.params.mainModID).html(""); - } - - verto.subscribe(confMan.params.laData.modChannel, { - handler: function(v, e) { - console.error("MODDATA:", e.data); - if (confMan.params.onBroadcast) { - confMan.params.onBroadcast(verto, confMan, e.data); - } - if (!confMan.destroyed && confMan.params.displayID) { - $(confMan.params.displayID).html(e.data.response + "

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

");}, 4000); - } - } - }); - } - - var row_callback = null; - - if (confMan.params.laData.role === "moderator") { - row_callback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { - if (!aData[5]) { - var $row = $('td:eq(5)', nRow); - genControls($row, aData); - - if (confMan.params.onLaRow) { - confMan.params.onLaRow(verto, confMan, $row, aData); - } - } - }; - } - - confMan.lt = new $.verto.liveTable(verto, confMan.params.laData.laChannel, confMan.params.laData.laName, $(confMan.params.tableID), { - subParams: { - callID: confMan.params.dialog ? confMan.params.dialog.callID : null - }, - - "onChange": function(obj, args) { - $(confMan.params.statusID).text("Conference Members: " + " (" + obj.arrayLen() + " Total)"); - if (confMan.params.onLaChange) { - confMan.params.onLaChange(verto, confMan, $.verto.enum.confEvent.laChange, obj, args); - } - }, - - "aaData": [], - "aoColumns": [ - { - "sTitle": "ID" - }, - { - "sTitle": "Number" - }, - { - "sTitle": "Name" - }, - { - "sTitle": "Codec" - }, - { - "sTitle": "Status", - "sWidth": confMan.params.hasVid ? "300px" : "150px" - }, - { - "sTitle": atitle, - "sWidth": awidth, - } - ], - "bAutoWidth": true, - "bDestroy": true, - "bSort": false, - "bInfo": false, - "bFilter": false, - "bLengthChange": false, - "bPaginate": false, - "iDisplayLength": 1000, - - "oLanguage": { - "sEmptyTable": "The Conference is Empty....." - }, - - "fnRowCallback": row_callback - - }); - }; - - $.verto.confMan.prototype.modCommand = function(cmd, id, value) { - var confMan = this; - - confMan.verto.sendMethod("verto.broadcast", { - "eventChannel": confMan.params.laData.modChannel, - "data": { - "application": "conf-control", - "command": cmd, - "id": id, - "value": value - } - }); - }; - - $.verto.confMan.prototype.destroy = function() { - var confMan = this; - - confMan.destroyed = true; - - if (confMan.lt) { - confMan.lt.destroy(); - } - - if (confMan.params.laData.modChannel) { - confMan.verto.unsubscribe(confMan.params.laData.modChannel); - } - - if (confMan.params.mainModID) { - $(confMan.params.mainModID).html(""); - } - }; - - $.verto.dialog = function(direction, verto, params) { - var dialog = this; - - dialog.params = $.extend({ - useVideo: verto.options.useVideo, - useStereo: verto.options.useStereo, - tag: verto.options.tag, - login: verto.options.login - }, params); - - dialog.verto = verto; - dialog.direction = direction; - dialog.lastState = null; - dialog.state = dialog.lastState = $.verto.enum.state.new; - dialog.callbacks = verto.callbacks; - dialog.answered = false; - dialog.attach = params.attach || false; - - if (dialog.params.callID) { - dialog.callID = dialog.params.callID; - } else { - dialog.callID = dialog.params.callID = generateGUID(); - } - - if (dialog.params.tag) { - dialog.audioStream = document.getElementById(dialog.params.tag); - - if (dialog.params.useVideo) { - dialog.videoStream = dialog.audioStream; - } - } //else conjure one TBD - - dialog.verto.dialogs[dialog.callID] = dialog; - - var RTCcallbacks = {}; - - if (dialog.direction == $.verto.enum.direction.inbound) { - if (dialog.params.display_direction === "outbound") { - dialog.params.remote_caller_id_name = dialog.params.caller_id_name; - dialog.params.remote_caller_id_number = dialog.params.caller_id_number; - } else { - dialog.params.remote_caller_id_name = dialog.params.callee_id_name; - dialog.params.remote_caller_id_number = dialog.params.callee_id_number; - } - - if (!dialog.params.remote_caller_id_name) { - dialog.params.remote_caller_id_name = "Nobody"; - } - - if (!dialog.params.remote_caller_id_number) { - dialog.params.remote_caller_id_number = "UNKNOWN"; - } - - RTCcallbacks.onMessage = function(rtc, msg) { - console.debug(msg); - }; - - RTCcallbacks.onAnswerSDP = function(rtc, sdp) { - console.error("answer sdp", sdp); - }; - } else { - dialog.params.remote_caller_id_name = "Outbound Call"; - dialog.params.remote_caller_id_number = dialog.params.destination_number; - } - - RTCcallbacks.onICESDP = function(rtc) { - - if (rtc.type == "offer") { - console.log("offer", rtc.mediaData.SDP); - - dialog.setState($.verto.enum.state.requesting); - - dialog.sendMethod("verto.invite", { - sdp: rtc.mediaData.SDP - }); - } else { //answer - dialog.setState($.verto.enum.state.answering); - - dialog.sendMethod(dialog.attach ? "verto.attach" : "verto.answer", { - sdp: dialog.rtc.mediaData.SDP - }); - } - }; - - RTCcallbacks.onICE = function(rtc) { - //console.log("cand", rtc.mediaData.candidate); - if (rtc.type == "offer") { - console.log("offer", rtc.mediaData.candidate); - return; - } - }; - - RTCcallbacks.onError = function(e) { - console.error("ERROR:", e); - dialog.hangup(); - }; - - dialog.rtc = new $.FSRTC({ - callbacks: RTCcallbacks, - useVideo: dialog.videoStream, - useAudio: dialog.audioStream, - useStereo: dialog.params.useStereo, - videoParams: verto.options.videoParams, - audioParams: verto.options.audioParams, - iceServers: verto.options.iceServers - }); - - dialog.rtc.verto = dialog.verto; - - if (dialog.direction == $.verto.enum.direction.inbound) { - if (dialog.attach) { - dialog.answer(); - } else { - dialog.ring(); - } - } - }; - - $.verto.dialog.prototype.invite = function() { - var dialog = this; - dialog.rtc.call(); - }; - - $.verto.dialog.prototype.sendMethod = function(method, obj) { - var dialog = this; - obj.dialogParams = {}; - - for (var i in dialog.params) { - if (i == "sdp" && method != "verto.invite" && method != "verto.attach") { - continue; - } - - obj.dialogParams[i] = dialog.params[i]; - } - - dialog.verto.rpcClient.call(method, obj, - - function(e) { - /* Success */ - dialog.processReply(method, true, e); - }, - - function(e) { - /* Error */ - dialog.processReply(method, false, e); - }); - }; - - function checkStateChange(oldS, newS) { - - if (newS == $.verto.enum.state.purge || $.verto.enum.states[oldS.name][newS.name]) { - return true; - } - - return false; - } - - $.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.info("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.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]; - dialog.rtc.stop(); - break; - } - - return true; - }; - - $.verto.dialog.prototype.processReply = function(method, success, e) { - var dialog = this; - - //console.log("Response: " + method + " State:" + dialog.state.name, success, e); - - switch (method) { - - case "verto.answer": - case "verto.attach": - if (success) { - dialog.setState($.verto.enum.state.active); - } else { - dialog.hangup(); - } - break; - case "verto.invite": - if (success) { - dialog.setState($.verto.enum.state.trying); - } else { - dialog.setState($.verto.enum.state.destroy); - } - break; - - case "verto.bye": - dialog.hangup(); - break; - - case "verto.modify": - if (e.holdState) { - if (e.holdState == "held") { - if (dialog.state != $.verto.enum.state.held) { - dialog.setState($.verto.enum.state.held); - } - } else if (e.holdState == "active") { - if (dialog.state != $.verto.enum.state.active) { - dialog.setState($.verto.enum.state.active); - } - } - } - - if (success) {} - - break; - - default: - break; - } - - }; - - $.verto.dialog.prototype.hangup = function(params) { - var dialog = this; - - if (params) { - if (params.causeCode) { - dialog.causeCode = params.causeCode; - } - - if (params.cause) { - dialog.cause = params.cause; - } - } - - if (dialog.state.val > $.verto.enum.state.new.val && dialog.state.val < $.verto.enum.state.hangup.val) { - dialog.setState($.verto.enum.state.hangup); - } else if (dialog.state.val < $.verto.enum.state.destroy) { - dialog.setState($.verto.enum.state.destroy); - } - }; - - $.verto.dialog.prototype.stopRinging = function() { - var dialog = this; - if (dialog.verto.ringer) { - dialog.verto.ringer.stop(); - } - }; - - $.verto.dialog.prototype.indicateRing = function() { - var dialog = this; - - if (dialog.verto.ringer) { - dialog.verto.ringer.attr("src", dialog.verto.options.ringFile)[0].play(); - - setTimeout(function() { - dialog.stopRinging(); - if (dialog.state == $.verto.enum.state.ringing) { - dialog.indicateRing(); - } - }, - dialog.verto.options.ringSleep); - } - }; - - $.verto.dialog.prototype.ring = function() { - var dialog = this; - - dialog.setState($.verto.enum.state.ringing); - dialog.indicateRing(); - }; - - $.verto.dialog.prototype.useVideo = function(on) { - var dialog = this; - - dialog.params.useVideo = on; - - if (on) { - dialog.videoStream = dialog.audioStream; - } else { - dialog.videoStream = null; - } - - dialog.rtc.useVideo(dialog.videoStream); - - }; - - $.verto.dialog.prototype.useStereo = function(on) { - var dialog = this; - - dialog.params.useStereo = on; - dialog.rtc.useStereo(on); - }; - - $.verto.dialog.prototype.dtmf = function(digits) { - var dialog = this; - if (digits) { - dialog.sendMethod("verto.info", { - dtmf: digits - }); - } - }; - - $.verto.dialog.prototype.transfer = function(dest, params) { - var dialog = this; - if (dest) { - cur_call.sendMethod("verto.modify", { - action: "transfer", - destination: dest, - params: params - }); - } - }; - - $.verto.dialog.prototype.hold = function(params) { - var dialog = this; - - cur_call.sendMethod("verto.modify", { - action: "hold", - params: params - }); - }; - - $.verto.dialog.prototype.unhold = function(params) { - var dialog = this; - - cur_call.sendMethod("verto.modify", { - action: "unhold", - params: params - }); - }; - - $.verto.dialog.prototype.toggleHold = function(params) { - var dialog = this; - - cur_call.sendMethod("verto.modify", { - action: "toggleHold", - params: params - }); - }; - - $.verto.dialog.prototype.message = function(msg) { - var dialog = this; - var err = 0; - - msg.from = dialog.params.login; - - if (!msg.to) { - console.error("Missing To"); - err++; - } - - if (!msg.body) { - console.error("Missing Body"); - err++; - } - - if (err) { - return false; - } - - dialog.sendMethod("verto.info", { - msg: msg - }); - - return true; - }; - - $.verto.dialog.prototype.answer = function(params) { - var dialog = this; - - if (!dialog.answered) { - if (params) { - if (params.useVideo) { - dialog.useVideo(true); - } - dialog.params.callee_id_name = params.callee_id_name; - dialog.params.callee_id_number = params.callee_id_number; - } - dialog.rtc.createAnswer(dialog.params.sdp); - dialog.answered = true; - } - }; - - $.verto.dialog.prototype.handleAnswer = function(params) { - var dialog = this; - - dialog.gotAnswer = true; - - if (dialog.state.val >= $.verto.enum.state.active.val) { - return; - } - - if (dialog.state.val >= $.verto.enum.state.early.val) { - dialog.setState($.verto.enum.state.active); - } else { - if (dialog.gotEarly) { - console.log("Dialog " + dialog.callID + "Got answer while still establishing early media, delaying..."); - } else { - console.log("Dialog " + dialog.callID + "Answering Channel"); - dialog.rtc.answer(params.sdp, function() { - dialog.setState($.verto.enum.state.active); - }, function(e) { - console.error(e); - dialog.hangup(); - }); - console.log("Dialog " + dialog.callID + "ANSWER SDP", params.sdp); - } - } - }; - - $.verto.dialog.prototype.cidString = function(enc) { - var dialog = this; - var party = dialog.params.remote_caller_id_name + (enc ? " <" : " <") + dialog.params.remote_caller_id_number + (enc ? ">" : ">"); - return party; - }; - - $.verto.dialog.prototype.sendMessage = function(msg, params) { - var dialog = this; - - if (dialog.callbacks.onMessage) { - dialog.callbacks.onMessage(dialog.verto, dialog, msg, params); - } - }; - - $.verto.dialog.prototype.handleInfo = function(params) { - var dialog = this; - - dialog.sendMessage($.verto.enum.message.info, params.msg); - }; - - $.verto.dialog.prototype.handleDisplay = function(params) { - var dialog = this; - - if (params.display_name) { - dialog.params.remote_caller_id_name = params.display_name; - } - if (params.display_number) { - dialog.params.remote_caller_id_number = params.display_number; - } - - dialog.sendMessage($.verto.enum.message.display, {}); - }; - - $.verto.dialog.prototype.handleMedia = function(params) { - var dialog = this; - - if (dialog.state.val >= $.verto.enum.state.early.val) { - return; - } - - dialog.gotEarly = true; - - dialog.rtc.answer(params.sdp, function() { - console.log("Dialog " + dialog.callID + "Establishing early media"); - dialog.setState($.verto.enum.state.early); - - if (dialog.gotAnswer) { - console.log("Dialog " + dialog.callID + "Answering Channel"); - dialog.setState($.verto.enum.state.active); - } - }, function(e) { - console.error(e); - dialog.hangup(); - }); - console.log("Dialog " + dialog.callID + "EARLY SDP", params.sdp); - }; - - $.verto.ENUM = function(s) { - var i = 0, - o = {}; - s.split(" ").map(function(x) { - o[x] = { - name: x, - val: i++ - }; - }); - return Object.freeze(o); - }; - - $.verto.enum = {}; - - $.verto.enum.states = Object.freeze({ - new: { - requesting: 1, - recovering: 1, - ringing: 1, - destroy: 1, - answering: 1 - }, - requesting: { - trying: 1, - hangup: 1 - }, - recovering: { - answering: 1, - hangup: 1 - }, - trying: { - active: 1, - early: 1, - hangup: 1 - }, - ringing: { - answering: 1, - hangup: 1 - }, - answering: { - active: 1, - hangup: 1 - }, - active: { - answering: 1, - requesting: 1, - hangup: 1, - held: 1 - }, - held: { - hangup: 1, - active: 1 - }, - early: { - hangup: 1, - active: 1 - }, - hangup: { - destroy: 1 - }, - destroy: {}, - purge: { - destroy: 1 - } - }); - - $.verto.enum.state = $.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge"); - $.verto.enum.direction = $.verto.ENUM("inbound outbound"); - $.verto.enum.message = $.verto.ENUM("display info pvtEvent"); - - $.verto.enum = Object.freeze($.verto.enum); - - $.verto.saved = []; - - $(window).bind('beforeunload', function() { - for (var i in $.verto.saved) { - var verto = $.verto.saved[i]; - if (verto) { - verto.logout(); - verto.purge(); - } - } - return $.verto.warnOnUnload; - }); - -})(jQuery); +(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} +function findLineInRange(sdpLines,startLine,endLine,prefix,substr){var realEndLine=(endLine!=-1)?endLine:sdpLines.length;for(var i=startLine;i=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}} +var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];} +var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;peer.onicecandidate=function(event){if(event.candidate){options.onICE(event.candidate);}else{if(options.onICEComplete){options.onICEComplete();} +if(options.type=="offer"){if(!moz&&!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i1){return false;} +return true;};$.JsonRpcClient.prototype.closeSocket=function(){if(self.socketReady()){this._ws_socket.onclose=function(w){console.log("Closing Socket");};this._ws_socket.close();}};$.JsonRpcClient.prototype.loginData=function(params){self.options.login=params.login;self.options.passwd=params.passwd;};$.JsonRpcClient.prototype.connectSocket=function(onmessage_cb){var self=this;if(self.to){clearTimeout(self.to);} +if(!self.socketReady()){self.authing=false;if(self._ws_socket){delete self._ws_socket;} +self._ws_socket=new WebSocket(self.options.socketUrl);if(self._ws_socket){self._ws_socket.onmessage=onmessage_cb;self._ws_socket.onclose=function(w){if(!self.ws_sleep){self.ws_sleep=1000;} +if(self.options.onWSClose){self.options.onWSClose(self);} +console.error("Websocket Lost "+self.ws_cnt+" sleep: "+self.ws_sleep+"msec");self.to=setTimeout(function(){console.log("Attempting Reconnection....");self.connectSocket(onmessage_cb);},self.ws_sleep);self.ws_cnt++;if(self.ws_sleep<3000&&(self.ws_cnt%10)===0){self.ws_sleep+=1000;}};self._ws_socket.onopen=function(){if(self.to){clearTimeout(self.to);} +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},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={};} +var reply=this.options.onmessage(event);if(reply&&typeof reply==="object"&&event.eventData.id){var msg={jsonrpc:"2.0",id:event.eventData.id,result:reply};var socket=self.options.getSocket(self.wsOnMessage);if(socket!==null){socket.send($.toJSON(msg));}}}};$.JsonRpcClient._batchObject=function(jsonrpcclient,all_done_cb,error_cb){this._requests=[];this.jsonrpcclient=jsonrpcclient;this.all_done_cb=all_done_cb;this.error_cb=typeof error_cb==='function'?error_cb:function(){};};$.JsonRpcClient._batchObject.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};} +if(this.options.sessid){params.sessid=this.options.sessid;} +if(!success_cb){success_cb=function(e){console.log("Success: ",e);};} +if(!error_cb){error_cb=function(e){console.log("Error: ",e);};} +this._requests.push({request:{jsonrpc:'2.0',method:method,params:params,id:this.jsonrpcclient._current_id++},success_cb:success_cb,error_cb:error_cb});};$.JsonRpcClient._batchObject.prototype.notify=function(method,params){if(this.options.sessid){params.sessid=this.options.sessid;} +this._requests.push({request:{jsonrpc:'2.0',method:method,params:params}});};$.JsonRpcClient._batchObject.prototype._execute=function(){var self=this;if(this._requests.length===0)return;var batch_request=[];var handlers={};var i=0;var call;var success_cb;var error_cb;var socket=self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage);if(socket!==null){for(i=0;i0){data.params.useVideo=true;} +if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;} +dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);dialog.setState($.verto.enum.state.recovering);break;case'verto.invite':if(data.params.sdp&&data.params.sdp.indexOf("m=video")>0){data.params.wantVideo=true;} +if(data.params.sdp&&data.params.sdp.indexOf("stereo=1")>0){data.params.useStereo=true;} +dialog=new $.verto.dialog($.verto.enum.direction.inbound,verto,data.params);break;default:console.debug("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED");break;}} +return{method:data.method};}else{switch(data.method){case'verto.punt':verto.purge();verto.logout();break;case'verto.event':var list=null;var key=null;if(data.params){key=data.params.eventChannel;} +if(key){list=verto.eventSUBS[key];if(!list){list=verto.eventSUBS[key.split(".")[0]];}} +if(!list&&key&&key===verto.sessid){if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.pvtEvent,data.params);}}else if(!list&&key&&verto.dialogs[key]){verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent,data.params);}else if(!list){if(!key){key="UNDEFINED";} +console.error("UNSUBBED or invalid EVENT "+key+" IGNORED");}else{for(var i in list){var sub=list[i];if(!sub||!sub.ready){console.error("invalid EVENT for "+key+" IGNORED");}else if(sub.handler){sub.handler(verto,data.params,sub.userData);}else if(verto.callbacks.onEvent){verto.callbacks.onEvent(verto,data.params,sub.userData);}else{console.log("EVENT:",data.params);}}} +break;case"verto.info":if(verto.callbacks.onMessage){verto.callbacks.onMessage(verto,null,$.verto.enum.message.info,data.params.msg);} +console.debug("MESSAGE from: "+data.params.msg.from,data.params.msg.body);break;default:console.error("INVALID METHOD OR NON-EXISTANT CALL REFERENCE IGNORED",data.method);break;}}};var del_array=function(array,name){var r=[];var len=array.length;for(var i=0;i=array.length){array.push(name);}else{var x=0;var n=[];var len=array.length;for(var i=0;i":"\n");});return str;};};$.verto.liveArray=function(verto,context,name,config){var la=this;var lastSerno=0;var binding=null;var user_obj=config.userObj;var local=false;hashArray.call(la);la._add=la.add;la._del=la.del;la._reorder=la.reorder;la._clear=la.clear;la.context=context;la.name=name;la.user_obj=user_obj;la.verto=verto;la.broadcast=function(channel,obj){verto.broadcast(channel,obj);};la.errs=0;la.clear=function(){la._clear();lastSerno=0;if(la.onChange){la.onChange(la,{action:"clear"});}};la.checkSerno=function(serno){if(serno<0){return true;} +if(lastSerno>0&&serno!=(lastSerno+1)){if(la.onErr){la.onErr(la,{lastSerno:lastSerno,serno:serno});} +la.errs++;console.debug(la.errs);if(la.errs<3){la.bootstrap(la.user_obj);} +return false;}else{lastSerno=serno;return true;}};la.reorder=function(serno,a){if(la.checkSerno(serno)){la._reorder(a);if(la.onChange){la.onChange(la,{serno:serno,action:"reorder"});}}};la.init=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} +if(la.checkSerno(serno)){if(la.onChange){la.onChange(la,{serno:serno,action:"init",index:index,key:key,data:val});}}};la.bootObj=function(serno,val){if(la.checkSerno(serno)){for(var i in val){la._add(val[i][0],val[i][1]);} +if(la.onChange){la.onChange(la,{serno:serno,action:"bootObj",data:val,redraw:true});}}};la.add=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} +if(la.checkSerno(serno)){var redraw=la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"add",index:index,key:key,data:val,redraw:redraw});}}};la.modify=function(serno,val,key,index){if(key===null||key===undefined){key=serno;} +if(la.checkSerno(serno)){la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"modify",key:key,data:val,index:index});}}};la.del=function(serno,key,index){if(key===null||key===undefined){key=serno;} +if(la.checkSerno(serno)){if(index===null||index<0||index===undefined){index=la.indexOf(key);} +var ok=la._del(key);if(ok&&la.onChange){la.onChange(la,{serno:serno,action:"del",key:key,index:index});}}};var eventHandler=function(v,e,la){var packet=e.data;if(packet.name!=la.name){return;} +switch(packet.action){case"init":la.init(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"bootObj":la.bootObj(packet.wireSerno,packet.data);break;case"add":la.add(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"modify":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.modify(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);} +break;case"del":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.del(packet.wireSerno,packet.hashKey,packet.arrIndex);} +break;case"clear":la.clear();break;case"reorder":la.reorder(packet.wireSerno,packet.order);break;default:if(la.checkSerno(packet.wireSerno)){if(la.onChange){la.onChange(la,{serno:packet.wireSerno,action:packet.action,data:packet.data});}} +break;}};if(la.context){binding=la.verto.subscribe(la.context,{handler:eventHandler,userData:la,subParams:config.subParams});} +la.destroy=function(){la._clear();la.verto.unsubscribe(binding);};la.sendCommand=function(cmd,obj){var self=la;self.broadcast(self.context,{liveArray:{command:cmd,context:self.context,name:self.name,obj:obj}});};la.bootstrap=function(obj){var self=la;la.sendCommand("bootstrap",obj);};la.changepage=function(obj){var self=la;self.clear();self.broadcast(self.context,{liveArray:{command:"changepage",context:la.context,name:la.name,obj:obj}});};la.heartbeat=function(obj){var self=la;var callback=function(){self.heartbeat.call(self,obj);};self.broadcast(self.context,{liveArray:{command:"heartbeat",context:self.context,name:self.name,obj:obj}});self.hb_pid=setTimeout(callback,30000);};la.bootstrap(la.user_obj);};$.verto.liveTable=function(verto,context,name,jq,config){var dt;var la=new $.verto.liveArray(verto,context,name,{subParams:config.subParams});var lt=this;lt.liveArray=la;lt.dataTable=dt;lt.verto=verto;lt.destroy=function(){if(dt){dt.fnDestroy();} +if(la){la.destroy();} +dt=null;la=null;};la.onErr=function(obj,args){console.error("Error: ",obj,args);};la.onChange=function(obj,args){var index=0;var iserr=0;if(!dt){if(!config.aoColumns){if(args.action!="init"){return;} +config.aoColumns=[];for(var i in args.data){config.aoColumns.push({"sTitle":args.data[i]});}} +dt=jq.dataTable(config);} +if(dt&&(args.action=="del"||args.action=="modify")){index=args.index;if(index===undefined&&args.key){index=la.indexOf(args.key);} +if(index===undefined){console.error("INVALID PACKET Missing INDEX\n",args);return;}} +if(config.onChange){config.onChange(obj,args);} +try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data");return;} +dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} +if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);} +dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;} +dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} +if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.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++;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="

"+""+""+""+""+"

";jq.html(html);$("#"+play_id).click(function(){var file=prompt("Please enter file name","");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","");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 tmute_id="tmute_"+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="
"+""+""+""+""+""+"
";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");confMan.modCommand("transfer",x,xten);});$("#"+kick_id).click(function(){confMan.modCommand("kick",x);});$("#"+tmute_id).click(function(){confMan.modCommand("tmute",x);});$("#"+volup_id).click(function(){confMan.modCommand("volume_in",x,"up");});$("#"+voldn_id).click(function(){confMan.modCommand("volume_in",x,"down");});return html;} +var atitle="";var awidth=0;if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=200;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready

");}else{$(confMan.params.mainModID).html("");} +verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){console.error("MODDATA:",e.data);if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);} +if(!confMan.destroyed&&confMan.params.displayID){$(confMan.params.displayID).html(e.data.response+"

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

");},4000);}}});} +var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};} +confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID"},{"sTitle":"Number"},{"sTitle":"Name"},{"sTitle":"Codec"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"300px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1000,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.sendMethod("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} +if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);} +if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,tag:verto.options.tag,login:verto.options.login},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} +if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}} +dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;} +if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="Nobody";} +if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";} +RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;} +RTCcallbacks.onICESDP=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.SDP);dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup();};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,useVideo:dialog.videoStream,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:verto.options.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;} +obj.dialogParams[i]=dialog.params[i];} +dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;} +return false;} +$.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.info("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.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];dialog.rtc.stop();break;} +return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} +break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} +break;case"verto.bye":dialog.hangup();break;case"verto.modify":if(e.holdState){if(e.holdState=="held"){if(dialog.state!=$.verto.enum.state.held){dialog.setState($.verto.enum.state.held);}}else if(e.holdState=="active"){if(dialog.state!=$.verto.enum.state.active){dialog.setState($.verto.enum.state.active);}}} +if(success){} +break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;} +if(params.cause){dialog.cause=params.cause;}} +if(dialog.state.val>$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;} +dialog.rtc.useVideo(dialog.videoStream);};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){cur_call.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;cur_call.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;} +if(!msg.body){console.error("Missing Body");err++;} +if(err){return false;} +dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(params){if(params.useVideo){dialog.useVideo(true);} +dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;} +dialog.rtc.createAnswer(dialog.params.sdp);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;} +if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+"Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+"Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} +if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;} +dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;} +dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.logout();verto.purge();}} +return $.verto.warnOnUnload;});})(jQuery); \ No newline at end of file diff --git a/html5/verto/demo/verto.js b/html5/verto/demo/verto.js index c8ae2faf3b..62158946db 100644 --- a/html5/verto/demo/verto.js +++ b/html5/verto/demo/verto.js @@ -308,10 +308,8 @@ var callbacks = { }, onWSClose: function(v, success) { - if ($('#online').is(':visible')) { - display(""); - online(false); - } + display(""); + online(false); var today = new Date(); $("#errordisplay").html("Connection Error.
Last Attempt: " + today); goto_page("main"); diff --git a/html5/verto/js/src/jquery.verto.js b/html5/verto/js/src/jquery.verto.js index 0a55dac2e7..57fda41da1 100644 --- a/html5/verto/js/src/jquery.verto.js +++ b/html5/verto/js/src/jquery.verto.js @@ -132,6 +132,9 @@ $.verto.prototype.logout = function(msg) { var verto = this; verto.rpcClient.closeSocket(); + if (verto.callbacks.onWSClose) { + verto.callbacks.onWSClose(verto, false); + } verto.purge(); }; @@ -490,6 +493,10 @@ }; } else { switch (data.method) { + case 'verto.punt': + verto.purge(); + verto.logout(); + break; case 'verto.event': var list = null; var key = null; diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 67a8dec072..20d2135774 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -305,6 +305,8 @@ static uint32_t jsock_unsub_head(jsock_t *jsock, jsock_sub_node_head_t *head) return x; } +static void detach_calls(jsock_t *jsock); + static void unsub_all_jsock(void) { switch_hash_index_t *hi; @@ -1059,8 +1061,30 @@ static jsock_t *get_jsock(const char *uuid) static void attach_jsock(jsock_t *jsock) { + jsock_t *jp; + int proceed = 1; + switch_mutex_lock(globals.jsock_mutex); - switch_core_hash_insert(globals.jsock_hash, jsock->uuid_str, jsock); + + if ((jp = switch_core_hash_find(globals.jsock_hash, jsock->uuid_str))) { + if (jp == jsock) { + proceed = 0; + } else { + cJSON *params = NULL; + cJSON *msg = NULL; + msg = jrpc_new_req("verto.punt", NULL, ¶ms); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "New connection for session %s dropping previous connection.\n", jsock->uuid_str); + switch_core_hash_delete(globals.jsock_hash, jsock->uuid_str); + ws_write_json(jp, &msg, SWITCH_TRUE); + cJSON_Delete(msg); + jp->drop = 1; + } + } + + if (proceed) { + switch_core_hash_insert(globals.jsock_hash, jsock->uuid_str, jsock); + } + switch_mutex_unlock(globals.jsock_mutex); } From 165f54216c47a5343ac0c7a6ac62fd6a9de57b5f Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Tue, 6 Jan 2015 17:17:05 +0100 Subject: [PATCH 18/72] mod_sofia: Set sip_to_tag on ringing indication for inbound channels. When bridging a call, the to-tag used in the outgoing 180 Ringing message for the inbound channel is unavailable until the channel has been answered. For the outgoing channel this value is already available through the sip_to_tag variable via the event socket. This is solved this by setting sip_to_tag to the local leg's tag when receiving a ringing indication for inbound channels. This will also make the variable available in the CHANNEL_PROGRESS event through event socket. FS-7137 #resolve --- src/mod/endpoints/mod_sofia/mod_sofia.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index e1438753be..223bb195b3 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2066,6 +2066,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); char *cid = generate_pai_str(tech_pvt); + /* Set sip_to_tag to local tag for inbound channels. */ + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { + const char* to_tag = ""; + to_tag = switch_str_nil(nta_leg_get_tag(tech_pvt->nh->nh_ds->ds_leg)); + if(to_tag) { + switch_channel_set_variable(channel, "sip_to_tag", to_tag); + } + } + switch (ring_ready_val) { case SWITCH_RING_READY_QUEUED: From c460c00b55f63ae5ea6f8c6de81d62b06b30230e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 6 Jan 2015 10:27:10 -0600 Subject: [PATCH 19/72] FS-7134 #resolve --- src/mod/endpoints/mod_sofia/sofia_presence.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index cfa900264b..550d0e874a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -4283,9 +4283,9 @@ void sofia_presence_handle_sip_i_subscribe(int status, "full_via,expires,user_agent,accept,profile_name,network_ip" " from sip_subscriptions where hostname='%q' and profile_name='%q' and " "event='message-summary' and sub_to_user='%q' " - "and (sip_host='%q' or presence_hosts like '%%%q%%')", + "and (sip_host='%q' or presence_hosts like '%%%q%%') and call_id='%q'", to_host, mod_sofia_globals.hostname, profile->name, - to_user, to_host, to_host))) { + to_user, to_host, to_host, call_id))) { if (mod_sofia_globals.debug_presence > 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, From 85b8631d621f71a5345bc00627f938eb85ffef03 Mon Sep 17 00:00:00 2001 From: Simon Ditner Date: Tue, 6 Jan 2015 12:43:16 -0500 Subject: [PATCH 20/72] Add conference member data to floor event Between v1.2 and v1.4, member data was factored out. This makes it so that one can not determine who the originator of a floor change event is. With this change, the meta data related to the conference member whom initiated the floor change event is added to the event. See FS-7136 --- src/mod/applications/mod_conference/mod_conference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index b3a5fd525e..60de0c7810 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -2578,6 +2578,7 @@ static void conference_set_floor_holder(conference_obj_t *conference, conference } if (conference->floor_holder) { + conference_add_event_member_data(conference->floor_holder, event); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->floor_holder->id); } else { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none"); From 66c425c09b430ca85e199a2a538badc76edab892 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 6 Jan 2015 15:09:50 -0600 Subject: [PATCH 21/72] add utils --- support-d/utils/bt.sh | 4 + support-d/utils/btgrep | 80 +++++ support-d/utils/hashfinder | 137 +++++++ support-d/utils/rwlock.pl | 54 +++ support-d/utils/speedtest-cli | 657 ++++++++++++++++++++++++++++++++++ 5 files changed, 932 insertions(+) create mode 100644 support-d/utils/bt.sh create mode 100755 support-d/utils/btgrep create mode 100755 support-d/utils/hashfinder create mode 100755 support-d/utils/rwlock.pl create mode 100755 support-d/utils/speedtest-cli diff --git a/support-d/utils/bt.sh b/support-d/utils/bt.sh new file mode 100644 index 0000000000..548a9f8ac6 --- /dev/null +++ b/support-d/utils/bt.sh @@ -0,0 +1,4 @@ +gdb /usr/local/freeswitch/bin/freeswitch $1 \ + --eval-command='set pagination off' \ + --eval-command='thread apply all bt' \ + --eval-command='quit' diff --git a/support-d/utils/btgrep b/support-d/utils/btgrep new file mode 100755 index 0000000000..56a70569bc --- /dev/null +++ b/support-d/utils/btgrep @@ -0,0 +1,80 @@ +#!/usr/bin/perl +# Copyright (c) 2007-2014, Anthony Minessale II +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# Neither the name of the original author; nor the names of any contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Contributors: +# +# btgrep - Search for regex in backtraces +# + +$| = 0; +$/ = undef; + +my $file = shift; +open I, $file or die; +my $i = ; +close I; + +my @all = $i =~ /Thread \d.*?\n\n/smg; + +foo: +foreach my $m (@all) { + + foreach (@ARGV) { + my $arg; + my $neg = 0; + + if (/^\-(.*)$/) { + $arg = $1; + $neg = 1; + } else { + $arg = $_; + } + + if ($neg) { + next foo if($m =~ /$arg/); + } else { + next foo unless($m =~ /$arg/); + } + } + + print "Match: $m"; +} + +# For Emacs: +# Local Variables: +# mode:perl +# indent-tabs-mode:t +# tab-width:4 +# c-basic-offset:4 +# End: +# For VIM: +# vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: diff --git a/support-d/utils/hashfinder b/support-d/utils/hashfinder new file mode 100755 index 0000000000..f6ec9df3e4 --- /dev/null +++ b/support-d/utils/hashfinder @@ -0,0 +1,137 @@ +#!/usr/bin/perl +# Copyright (c) 2007-2014, Anthony Minessale II +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# Neither the name of the original author; nor the names of any contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Contributors: +# +# hashfinder - Find origin of a particular line of code +# + + +my $file = shift; +my $regex = shift; +my $delim = " "; + +$file and $regex or die "missing params. Syntax: "; + +sub doit($$) { + my $rev = shift; + my $pattern = shift; + my $loops = shift || 0; + my $linematch = 0; + + $pattern =~ s/\(/\\\(/g; + $pattern =~ s/\)/\\\)/g; + + if ($pattern =~ /^(\d+)$/) { + $linematch = 1; + } + + open GIT, "git blame -n $file $rev|"; + + my $mc = 0; + my @matches = (); + + while () { + my $matched = 0; + + if ($linematch) { + $matched = (/^\S+\s+$pattern\s+/); + } else { + $matched = (/$pattern/); + } + + if ($matched) { + s/[\r\n]//g; + push @matches, $_; + $mc++; + } + } + + close(GIT); + + + if ($mc > 5) { + print $delim x $loops; + print "$mc matches; Maybe more specific?\n"; + + foreach (@matches) { + print "$_\n"; + } + + return; + + } + + my $x = 0; + + foreach (@matches) { + my ($hash, $lno, $author, $line); + my $done = 0; + + if (/$file/) { + ($hash, $lno, $author, $line) = /(\S+)\s+\S+\s+(\S+)\s+(\([^\)]+\))\s*(.*)/; + $done = 1; + } else { + ($hash, $lno, $author, $line) = /(\S+)\s+(\S+)\s+(\([^\)]+\))\s*(.*)/; + } + + if ($hash) { + $line =~ s/^\s+//g; + + print "\n"; + print $delim x $loops; + my $msg = `git log -1 --pretty=format:%B $hash`; + print "[$hash] [$lno] [$author] [$line]\n"; + print $delim x $loops; + print ":: $msg\n"; + doit("$hash" . "^", $line, $loops+1); + print "\n"; + } + + last if $done; + + } +} + +doit(undef, $regex); + + +# For Emacs: +# Local Variables: +# mode:perl +# indent-tabs-mode:t +# tab-width:4 +# c-basic-offset:4 +# End: +# For VIM: +# vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + diff --git a/support-d/utils/rwlock.pl b/support-d/utils/rwlock.pl new file mode 100755 index 0000000000..ca2cc61b10 --- /dev/null +++ b/support-d/utils/rwlock.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl + + +my $start = 8; +my $i = $start; +my $step = "4"; +my $wr = 0; + + printf "%s %0.4d START $list[4]\n", " " x $i, $i; + +while(<>) { + my $sub = 0; + my $indent = 0; + + next unless /ERR/; + + @list = split; + + if ($list[9] eq "ACQUIRED") { + + if ($list[7] eq "Read") { + $mark = "READLOCK "; + $i += $step; + $indent = $i; + } else { + $mark = "WRITELOCK"; + $wr = 1; + $indent = 0; + } + + } elsif($list[9] eq "CLEARED") { + if ($wr && $i <= $start) { + $mark = "WRCLEARED"; + $indent = 0; + } else { + $sub = $step; + $mark = "CLEARED "; + $indent = $i; + } + } elsif($list[9] eq "FAIL") { + $mark = "FAIL "; + $indent = $i; + } + + printf "%s %0.4d $mark $list[4]\n", " " x $indent, $indent; + + if ($sub) { + $i -= $sub; + $sub = 0; + print "\n"; + } + + +} diff --git a/support-d/utils/speedtest-cli b/support-d/utils/speedtest-cli new file mode 100755 index 0000000000..b5e9ef8ab3 --- /dev/null +++ b/support-d/utils/speedtest-cli @@ -0,0 +1,657 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2013 Matt Martz +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +__version__ = '0.2.4' + +# Some global variables we use +source = None +shutdown_event = None + +import math +import time +import os +import sys +import threading +import re +import signal +import socket + +# Used for bound_interface +socket_socket = socket.socket + +try: + import xml.etree.cElementTree as ET +except ImportError: + try: + import xml.etree.ElementTree as ET + except ImportError: + from xml.dom import minidom as DOM + ET = None + +# Begin import game to handle Python 2 and Python 3 +try: + from urllib2 import urlopen, Request, HTTPError, URLError +except ImportError: + from urllib.request import urlopen, Request, HTTPError, URLError + +try: + from Queue import Queue +except ImportError: + from queue import Queue + +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse + +try: + from urlparse import parse_qs +except ImportError: + try: + from urllib.parse import parse_qs + except ImportError: + from cgi import parse_qs + +try: + from hashlib import md5 +except ImportError: + from md5 import md5 + +try: + from argparse import ArgumentParser as ArgParser +except ImportError: + from optparse import OptionParser as ArgParser + +try: + import builtins +except ImportError: + def print_(*args, **kwargs): + """The new-style print function taken from + https://pypi.python.org/pypi/six/ + + """ + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + fp.write(data) + + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +else: + print_ = getattr(builtins, 'print') + del builtins + + +def bound_socket(*args, **kwargs): + """Bind socket to a specified source IP address""" + + global source + sock = socket_socket(*args, **kwargs) + sock.bind((source, 0)) + return sock + + +def distance(origin, destination): + """Determine distance between 2 sets of [lat,lon] in km""" + + lat1, lon1 = origin + lat2, lon2 = destination + radius = 6371 # km + + dlat = math.radians(lat2 - lat1) + dlon = math.radians(lon2 - lon1) + a = (math.sin(dlat / 2) * math.sin(dlat / 2) + math.cos(math.radians(lat1)) + * math.cos(math.radians(lat2)) * math.sin(dlon / 2) + * math.sin(dlon / 2)) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + d = radius * c + + return d + + +class FileGetter(threading.Thread): + """Thread class for retrieving a URL""" + + def __init__(self, url, start): + self.url = url + self.result = None + self.starttime = start + threading.Thread.__init__(self) + + def run(self): + self.result = [0] + try: + if (time.time() - self.starttime) <= 10: + f = urlopen(self.url) + while 1 and not shutdown_event.isSet(): + self.result.append(len(f.read(10240))) + if self.result[-1] == 0: + break + f.close() + except IOError: + pass + + +def downloadSpeed(files, quiet=False): + """Function to launch FileGetter threads and calculate download speeds""" + + start = time.time() + + def producer(q, files): + for file in files: + thread = FileGetter(file, start) + thread.start() + q.put(thread, True) + if not quiet and not shutdown_event.isSet(): + sys.stdout.write('.') + sys.stdout.flush() + + finished = [] + + def consumer(q, total_files): + while len(finished) < total_files: + thread = q.get(True) + while thread.isAlive(): + thread.join(timeout=0.1) + finished.append(sum(thread.result)) + del thread + + q = Queue(6) + prod_thread = threading.Thread(target=producer, args=(q, files)) + cons_thread = threading.Thread(target=consumer, args=(q, len(files))) + start = time.time() + prod_thread.start() + cons_thread.start() + while prod_thread.isAlive(): + prod_thread.join(timeout=0.1) + while cons_thread.isAlive(): + cons_thread.join(timeout=0.1) + return (sum(finished) / (time.time() - start)) + + +class FilePutter(threading.Thread): + """Thread class for putting a URL""" + + def __init__(self, url, start, size): + self.url = url + chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + data = chars * (int(round(int(size) / 36.0))) + self.data = ('content1=%s' % data[0:int(size) - 9]).encode() + del data + self.result = None + self.starttime = start + threading.Thread.__init__(self) + + def run(self): + try: + if ((time.time() - self.starttime) <= 10 and + not shutdown_event.isSet()): + f = urlopen(self.url, self.data) + f.read(11) + f.close() + self.result = len(self.data) + else: + self.result = 0 + except IOError: + self.result = 0 + + +def uploadSpeed(url, sizes, quiet=False): + """Function to launch FilePutter threads and calculate upload speeds""" + + start = time.time() + + def producer(q, sizes): + for size in sizes: + thread = FilePutter(url, start, size) + thread.start() + q.put(thread, True) + if not quiet and not shutdown_event.isSet(): + sys.stdout.write('.') + sys.stdout.flush() + + finished = [] + + def consumer(q, total_sizes): + while len(finished) < total_sizes: + thread = q.get(True) + while thread.isAlive(): + thread.join(timeout=0.1) + finished.append(thread.result) + del thread + + q = Queue(6) + prod_thread = threading.Thread(target=producer, args=(q, sizes)) + cons_thread = threading.Thread(target=consumer, args=(q, len(sizes))) + start = time.time() + prod_thread.start() + cons_thread.start() + while prod_thread.isAlive(): + prod_thread.join(timeout=0.1) + while cons_thread.isAlive(): + cons_thread.join(timeout=0.1) + return (sum(finished) / (time.time() - start)) + + +def getAttributesByTagName(dom, tagName): + """Retrieve an attribute from an XML document and return it in a + consistent format + + Only used with xml.dom.minidom, which is likely only to be used + with python versions older than 2.5 + """ + elem = dom.getElementsByTagName(tagName)[0] + return dict(list(elem.attributes.items())) + + +def getConfig(): + """Download the speedtest.net configuration and return only the data + we are interested in + """ + + uh = urlopen('http://www.speedtest.net/speedtest-config.php') + configxml = [] + while 1: + configxml.append(uh.read(10240)) + if len(configxml[-1]) == 0: + break + if int(uh.code) != 200: + return None + uh.close() + try: + root = ET.fromstring(''.encode().join(configxml)) + config = { + 'client': root.find('client').attrib, + 'times': root.find('times').attrib, + 'download': root.find('download').attrib, + 'upload': root.find('upload').attrib} + except AttributeError: + root = DOM.parseString(''.join(configxml)) + config = { + 'client': getAttributesByTagName(root, 'client'), + 'times': getAttributesByTagName(root, 'times'), + 'download': getAttributesByTagName(root, 'download'), + 'upload': getAttributesByTagName(root, 'upload')} + del root + del configxml + return config + + +def closestServers(client, all=False): + """Determine the 5 closest speedtest.net servers based on geographic + distance + """ + + uh = urlopen('http://www.speedtest.net/speedtest-servers.php') + serversxml = [] + while 1: + serversxml.append(uh.read(10240)) + if len(serversxml[-1]) == 0: + break + if int(uh.code) != 200: + return None + uh.close() + try: + root = ET.fromstring(''.encode().join(serversxml)) + elements = root.getiterator('server') + except AttributeError: + root = DOM.parseString(''.join(serversxml)) + elements = root.getElementsByTagName('server') + servers = {} + for server in elements: + try: + attrib = server.attrib + except AttributeError: + attrib = dict(list(server.attributes.items())) + d = distance([float(client['lat']), float(client['lon'])], + [float(attrib.get('lat')), float(attrib.get('lon'))]) + attrib['d'] = d + if d not in servers: + servers[d] = [attrib] + else: + servers[d].append(attrib) + del root + del serversxml + del elements + + closest = [] + for d in sorted(servers.keys()): + for s in servers[d]: + closest.append(s) + if len(closest) == 5 and not all: + break + else: + continue + break + + del servers + return closest + + +def getBestServer(servers): + """Perform a speedtest.net "ping" to determine which speedtest.net + server has the lowest latency + """ + + results = {} + for server in servers: + cum = [] + url = os.path.dirname(server['url']) + for i in range(0, 3): + try: + uh = urlopen('%s/latency.txt' % url) + except HTTPError: + cum.append(3600) + continue + start = time.time() + text = uh.read(9) + total = time.time() - start + if int(uh.code) == 200 and text == 'test=test'.encode(): + cum.append(total) + else: + cum.append(3600) + uh.close() + avg = round((sum(cum) / 3) * 1000000, 3) + results[avg] = server + + fastest = sorted(results.keys())[0] + best = results[fastest] + best['latency'] = fastest + + return best + + +def ctrl_c(signum, frame): + """Catch Ctrl-C key sequence and set a shutdown_event for our threaded + operations + """ + + global shutdown_event + shutdown_event.set() + raise SystemExit('\nCancelling...') + + +def version(): + """Print the version""" + + raise SystemExit(__version__) + + +def speedtest(): + """Run the full speedtest.net test""" + + global shutdown_event, source + shutdown_event = threading.Event() + + signal.signal(signal.SIGINT, ctrl_c) + + description = ( + 'Command line interface for testing internet bandwidth using ' + 'speedtest.net.\n' + '------------------------------------------------------------' + '--------------\n' + 'https://github.com/sivel/speedtest-cli') + + parser = ArgParser(description=description) + # Give optparse.OptionParser an `add_argument` method for + # compatibility with argparse.ArgumentParser + try: + parser.add_argument = parser.add_option + except AttributeError: + pass + parser.add_argument('--share', action='store_true', + help='Generate and provide a URL to the speedtest.net ' + 'share results image') + parser.add_argument('--simple', action='store_true', + help='Suppress verbose output, only show basic ' + 'information') + parser.add_argument('--list', action='store_true', + help='Display a list of speedtest.net servers ' + 'sorted by distance') + parser.add_argument('--server', help='Specify a server ID to test against') + parser.add_argument('--mini', help='URL of the Speedtest Mini server') + parser.add_argument('--source', help='Source IP address to bind to') + parser.add_argument('--version', action='store_true', + help='Show the version number and exit') + + options = parser.parse_args() + if isinstance(options, tuple): + args = options[0] + else: + args = options + del options + + # Print the version and exit + if args.version: + version() + + # If specified bind to a specific IP address + if args.source: + source = args.source + socket.socket = bound_socket + + if not args.simple: + print_('Retrieving speedtest.net configuration...') + try: + config = getConfig() + except URLError: + print_('Cannot retrieve speedtest configuration') + sys.exit(1) + + if not args.simple: + print_('Retrieving speedtest.net server list...') + if args.list or args.server: + servers = closestServers(config['client'], True) + if args.list: + serverList = [] + for server in servers: + line = ('%(id)4s) %(sponsor)s (%(name)s, %(country)s) ' + '[%(d)0.2f km]' % server) + serverList.append(line) + # Python 2.7 and newer seem to be ok with the resultant encoding + # from parsing the XML, but older versions have some issues. + # This block should detect whether we need to encode or not + try: + unicode() + print_('\n'.join(serverList).encode('utf-8', 'ignore')) + except NameError: + print_('\n'.join(serverList)) + except IOError: + pass + sys.exit(0) + else: + servers = closestServers(config['client']) + + if not args.simple: + print_('Testing from %(isp)s (%(ip)s)...' % config['client']) + + if args.server: + try: + best = getBestServer(filter(lambda x: x['id'] == args.server, + servers)) + except IndexError: + print_('Invalid server ID') + sys.exit(1) + elif args.mini: + name, ext = os.path.splitext(args.mini) + if ext: + url = os.path.dirname(args.mini) + else: + url = args.mini + urlparts = urlparse(url) + try: + f = urlopen(args.mini) + except: + print_('Invalid Speedtest Mini URL') + sys.exit(1) + else: + text = f.read() + f.close() + extension = re.findall('upload_extension: "([^"]+)"', text.decode()) + if not urlparts or not extension: + print_('Please provide the full URL of your Speedtest Mini server') + sys.exit(1) + servers = [{ + 'sponsor': 'Speedtest Mini', + 'name': urlparts[1], + 'd': 0, + 'url': '%s/speedtest/upload.%s' % (url.rstrip('/'), extension[0]), + 'latency': 0, + 'id': 0 + }] + try: + best = getBestServer(servers) + except: + best = servers[0] + else: + if not args.simple: + print_('Selecting best server based on ping...') + best = getBestServer(servers) + + if not args.simple: + # Python 2.7 and newer seem to be ok with the resultant encoding + # from parsing the XML, but older versions have some issues. + # This block should detect whether we need to encode or not + try: + unicode() + print_(('Hosted by %(sponsor)s (%(name)s) [%(d)0.2f km]: ' + '%(latency)s ms' % best).encode('utf-8', 'ignore')) + except NameError: + print_('Hosted by %(sponsor)s (%(name)s) [%(d)0.2f km]: ' + '%(latency)s ms' % best) + else: + print_('Ping: %(latency)s ms' % best) + + sizes = [350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000] + urls = [] + for size in sizes: + for i in range(0, 4): + urls.append('%s/random%sx%s.jpg' % + (os.path.dirname(best['url']), size, size)) + if not args.simple: + print_('Testing download speed', end='') + dlspeed = downloadSpeed(urls, args.simple) + if not args.simple: + print_() + print_('Download: %0.2f Mbit/s' % ((dlspeed / 1000 / 1000) * 8)) + + sizesizes = [int(.25 * 1000 * 1000), int(.5 * 1000 * 1000)] + sizes = [] + for size in sizesizes: + for i in range(0, 25): + sizes.append(size) + if not args.simple: + print_('Testing upload speed', end='') + ulspeed = uploadSpeed(best['url'], sizes, args.simple) + if not args.simple: + print_() + print_('Upload: %0.2f Mbit/s' % ((ulspeed / 1000 / 1000) * 8)) + + if args.share and args.mini: + print_('Cannot generate a speedtest.net share results image while ' + 'testing against a Speedtest Mini server') + elif args.share: + dlspeedk = int(round((dlspeed / 1000) * 8, 0)) + ping = int(round(best['latency'], 0)) + ulspeedk = int(round((ulspeed / 1000) * 8, 0)) + + # Build the request to send results back to speedtest.net + # We use a list instead of a dict because the API expects parameters + # in a certain order + apiData = [ + 'download=%s' % dlspeedk, + 'ping=%s' % ping, + 'upload=%s' % ulspeedk, + 'promo=', + 'startmode=%s' % 'pingselect', + 'recommendedserverid=%s' % best['id'], + 'accuracy=%s' % 1, + 'serverid=%s' % best['id'], + 'hash=%s' % md5(('%s-%s-%s-%s' % + (ping, ulspeedk, dlspeedk, '297aae72')) + .encode()).hexdigest()] + + req = Request('http://www.speedtest.net/api/api.php', + data='&'.join(apiData).encode()) + req.add_header('Referer', 'http://c.speedtest.net/flash/speedtest.swf') + f = urlopen(req) + response = f.read() + code = f.code + f.close() + + if int(code) != 200: + print_('Could not submit results to speedtest.net') + sys.exit(1) + + qsargs = parse_qs(response.decode()) + resultid = qsargs.get('resultid') + if not resultid or len(resultid) != 1: + print_('Could not submit results to speedtest.net') + sys.exit(1) + + print_('Share results: http://www.speedtest.net/result/%s.png' % + resultid[0]) + + +def main(): + try: + speedtest() + except KeyboardInterrupt: + print_('\nCancelling...') + + +if __name__ == '__main__': + main() + +# vim:ts=4:sw=4:expandtab From 94bb4606e3d5ad23915547ec198153b0c8605b94 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 22 Nov 2014 15:41:50 -0500 Subject: [PATCH 22/72] fixes for recent firefox changes --- html5/verto/demo/js/verto-min.js | 6 +++--- html5/verto/js/src/jquery.FSRTC.js | 14 +++++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index 416710a7f2..2f7d8b08d2 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -37,8 +37,8 @@ if(!(tmp&&typeof(tmp)=="object"&&tmp.constructor===Array)){console.warn("iceServ iceServers={iceServers:tmp||[STUN]};if(!moz&&!tmp){if(parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2])>=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}} var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];} var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;peer.onicecandidate=function(event){if(event.candidate){options.onICE(event.candidate);}else{if(options.onICEComplete){options.onICEComplete();} -if(options.type=="offer"){if(!moz&&!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i=$.verto.enum.state.active.val){return;} -if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+"Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+"Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} +if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;} dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;} dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.logout();verto.purge();}} diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index 9e973f2f24..e228ee18e6 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -484,7 +484,11 @@ } if (options.type == "offer") { - if (!moz && !x && options.onICESDP) { + /* new mozilla now tries to be like chrome but it takes them 10 seconds to complete the ICE + Booooooooo! This trickle thing is a waste of time...... We'll all have to re-code our engines + to handle partial setups to maybe save 100m + */ + if ((!moz || peer.localDescription.sdp.match(/a=candidate/)) && !x && options.onICESDP) { options.onICESDP(peer.localDescription); //x = 1; /* @@ -549,7 +553,10 @@ mandatory: { OfferToReceiveAudio: true, OfferToReceiveVideo: true - } + }, + /* spec is changed support both ways at once */ + offerToReceiveAudio: true, + offerToReceiveVideo: true }; // onOfferSDP(RTCSessionDescription) @@ -560,7 +567,8 @@ sessionDescription.sdp = serializeSdp(sessionDescription.sdp); peer.setLocalDescription(sessionDescription); options.onOfferSDP(sessionDescription); - if (moz && options.onICESDP) { + /* old mozilla behaviour the SDP was already great right away */ + if (moz && options.onICESDP && sessionDescription.match(/a=candidate/)) { options.onICESDP(sessionDescription); } }, From 41bfc18a1003bfc60d8da2b2de6eb7695b2b1c7e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 24 Nov 2014 18:38:52 -0500 Subject: [PATCH 23/72] add some stuff to verto for introp --- html5/verto/demo/js/verto-min.js | 14 +++++++------- html5/verto/js/src/jquery.FSRTC.js | 30 +++++++++++++----------------- html5/verto/js/src/jquery.verto.js | 5 +++++ 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index 2f7d8b08d2..64291c2fb1 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -6,8 +6,8 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\ function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}} var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];} var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;peer.onicecandidate=function(event){if(event.candidate){options.onICE(event.candidate);}else{if(options.onICEComplete){options.onICEComplete();} -if(options.type=="offer"){if((!moz||peer.localDescription.sdp.match(/a=candidate/))&&!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}else{if(!x&&options.onICESDP){options.onICESDP(peer.localDescription);}}}};if(options.attachStream)peer.addStream(options.attachStream);if(options.attachStreams&&options.attachStream.length){var streams=options.attachStreams;for(var i=0;i Date: Fri, 28 Nov 2014 15:54:02 -0500 Subject: [PATCH 24/72] this is why we can't have nice things.... C'mon chrome and mozilla its not that hard to both do the same spec --- html5/verto/js/src/jquery.FSRTC.js | 32 ++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index a404d006e4..a214c1f9db 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -93,10 +93,22 @@ candidateList: [] }; - this.constraints = { - offerToReceiveAudio: true, - offerToReceiveVideo: this.options.useVideo ? true : false, - }; + + if (moz) { + this.constraints = { + offerToReceiveAudio: true, + offerToReceiveVideo: this.options.useVideo ? true : false, + }; + } else { + this.constraints = { + optional: [{ + 'DtlsSrtpKeyAgreement': 'true' + }],mandatory: { + OfferToReceiveAudio: true, + OfferToReceiveVideo: this.options.useVideo ? true : false, + } + }; + } if (self.options.useVideo) { self.options.useVideo.style.display = 'none'; @@ -111,10 +123,18 @@ if (obj) { self.options.useVideo = obj; - self.constraints.offerToReceiveVideo = true; + if (moz) { + self.constraints.offerToReceiveVideo = true; + } else { + self.constraints.mandatory.OfferToReceiveVideo = true; + } } else { self.options.useVideo = null; - self.constraints.offerToReceiveVideo = false; + if (moz) { + self.constraints.offerToReceiveVideo = false; + } else { + self.constraints.mandatory.OfferToReceiveVideo = false; + } } if (self.options.useVideo) { From b79a7e185129620731e4f221a027c439d34a457a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sat, 6 Dec 2014 11:40:44 -0600 Subject: [PATCH 25/72] vid screen share placeholder --args --enable-usermedia-screen-capturing --usermedia-screen-capturing --- html5/verto/js/src/jquery.FSRTC.js | 63 +++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index a214c1f9db..8ca3602e04 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -191,8 +191,8 @@ return true; } - function onStreamError(self) { - console.log('There has been a problem retrieving the streams - did you allow access?'); + function onStreamError(self, e) { + console.log('There has been a problem retrieving the streams - did you allow access?', e); } @@ -332,19 +332,36 @@ onStreamSuccess(self); } - function onError() { - onStreamError(self); + function onError(e) { + onStreamError(self, e); } + + var audio; + + if (this.options.videoParams && this.options.videoParams.chromeMediaSource == 'screen') { + + this.options.videoParams = { + chromeMediaSource: 'screen', + maxWidth:screen.width, + maxHeight:screen.height + }; + + console.error("SCREEN SHARE"); + audio = false; + } else { + audio = { + mandatory: this.options.audioParams, + optional: [] + }; + } + console.log("Mandatory audio constraints", this.options.audioParams); console.log("Mandatory video constraints", this.options.videoParams); getUserMedia({ constraints: { - audio: { - mandatory: this.options.audioParams, - optional: [] - }, + audio: audio, video: this.options.useVideo ? { mandatory: this.options.videoParams, optional: [] @@ -395,19 +412,37 @@ onStreamSuccess(self); } - function onError() { - onStreamError(self); + function onError(e) { + onStreamError(self, e); } + + var audio; + + if (this.options.videoParams && this.options.videoParams.chromeMediaSource == 'screen') { + + this.options.videoParams = { + chromeMediaSource: 'screen', + maxWidth:screen.width, + maxHeight:screen.height + }; + + console.error("SCREEN SHARE"); + audio = false; + } else { + audio = { + mandatory: this.options.audioParams, + optional: [] + }; + } + console.log("Mandatory audio constraints", this.options.audioParams); console.log("Mandatory video constraints", this.options.videoParams); + getUserMedia({ constraints: { - audio: { - mandatory: this.options.audioParams, - optional: [] - }, + audio: audio, video: this.options.useVideo ? { mandatory: this.options.videoParams, optional: [] From b170e9e9f570d9c0ca1730a00ac742c46639928e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 6 Jan 2015 23:34:29 -0600 Subject: [PATCH 26/72] update minified js --- html5/verto/demo/js/verto-min.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index 64291c2fb1..b0a43bf585 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -6,14 +6,15 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\ function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}} var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];} @@ -200,7 +203,7 @@ if(err){return false;} dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(params){if(params.useVideo){dialog.useVideo(true);} dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;} dialog.rtc.createAnswer(dialog.params.sdp);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;} -if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} +if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+"Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+"Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;} dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;} dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.logout();verto.purge();}} From 6c1bc0e2f6d55bcc40081aec5c543c613185ab3e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 6 Jan 2015 20:12:09 -0600 Subject: [PATCH 27/72] sync ws code --- libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 9 +++++++-- libs/sofia-sip/libsofia-sip-ua/tport/ws.h | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index 51ae0f13f7..db2e39e5ab 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -309,7 +309,7 @@ int ws_handshake(wsh_t *wsh) "%s\r\n", b64, proto_buf); - + respond[511] = 0; ws_raw_write(wsh, respond, strlen(respond)); wsh->handshake = 1; @@ -322,6 +322,7 @@ int ws_handshake(wsh_t *wsh) snprintf(respond, sizeof(respond), "HTTP/1.1 400 Bad Request\r\n" "Sec-WebSocket-Version: 13\r\n\r\n"); + respond[511] = 0; ws_raw_write(wsh, respond, strlen(respond)); @@ -399,7 +400,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block) ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) { - size_t r; + ssize_t r; int sanity = 2000; int ssl_err = 0; @@ -656,7 +657,11 @@ ssize_t ws_close(wsh_t *wsh, int16_t reason) restore_socket(wsh->sock); if (wsh->close_sock && wsh->sock != ws_sock_invalid) { +#ifndef WIN32 close(wsh->sock); +#else + closesocket(wsh->sock); +#endif } wsh->sock = ws_sock_invalid; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h index 7f5f5c48b4..1dd85a5d93 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h @@ -11,11 +11,11 @@ #include #include #include +#include #else #pragma warning(disable:4996) #endif #include -#include #include #include #include @@ -26,7 +26,9 @@ #include #ifdef _MSC_VER +#ifndef strncasecmp #define strncasecmp _strnicmp +#endif #define snprintf _snprintf #ifdef _WIN64 #define WS_SSIZE_T __int64 @@ -48,8 +50,12 @@ struct ws_globals_s { extern struct ws_globals_s ws_globals; +#ifndef WIN32 typedef int ws_socket_t; -#define ws_sock_invalid -1 +#else +typedef SOCKET ws_socket_t; +#endif +#define ws_sock_invalid (ws_socket_t)-1 typedef enum { From 7c0c3ab8a6ce9872e1bea90e441edc9977383dcf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Jan 2015 02:12:48 -0600 Subject: [PATCH 28/72] sofia rebuild --- libs/sofia-sip/.update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 43989408cc..e9eed8de6c 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Fri Dec 12 10:24:52 CST 2014 +Wed Jan 7 02:12:39 CST 2015 From 23c18293822dcbbcd1c4d8d69ba1e0697f7230d1 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Wed, 7 Jan 2015 15:38:38 +0800 Subject: [PATCH 29/72] FS-7127 #comment fix regression from a80c739, thanks Mike The second hunk in this patch isn't right. In the past, if tmp was null, it would not pass the if. --- html5/verto/demo/js/verto-min.js | 4 ++-- html5/verto/js/src/jquery.FSRTC.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index b0a43bf585..4718b16a03 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -36,7 +36,7 @@ console.log("Mandatory audio constraints",this.options.audioParams);console.log( function onError(e){onStreamError(self,e);} var audio;if(this.options.videoParams&&this.options.videoParams.chromeMediaSource=='screen'){this.options.videoParams={chromeMediaSource:'screen',maxWidth:screen.width,maxHeight:screen.height};console.error("SCREEN SHARE");audio=false;}else{audio={mandatory:this.options.audioParams,optional:[]};} console.log("Mandatory audio constraints",this.options.audioParams);console.log("Mandatory video constraints",this.options.videoParams);getUserMedia({constraints:{audio:audio,video:this.options.useVideo?{mandatory:this.options.videoParams,optional:[]}:null},video:this.options.useVideo?true:false,onsuccess:onSuccess,onerror:onError});};window.moz=!!navigator.mozGetUserMedia;function RTCPeerConnection(options){var w=window,PeerConnection=w.mozRTCPeerConnection||w.webkitRTCPeerConnection,SessionDescription=w.mozRTCSessionDescription||w.RTCSessionDescription,IceCandidate=w.mozRTCIceCandidate||w.RTCIceCandidate;var STUN={url:!moz?'stun:stun.l.google.com:19302':'stun:23.21.150.121'};var TURN={url:'turn:homeo@turn.bistri.com:80',credential:'homeo'};var iceServers=null;if(options.iceServers){var tmp=options.iceServers;if(typeof(tmp)==="boolean"){tmp=null;} -if(!(tmp&&typeof(tmp)=="object"&&tmp.constructor===Array)){console.warn("iceServers must be an array, reverting to default ice servers");tmp=null;} +if(tmp&&!(typeof(tmp)=="object"&&tmp.constructor===Array)){console.warn("iceServers must be an array, reverting to default ice servers");tmp=null;} iceServers={iceServers:tmp||[STUN]};if(!moz&&!tmp){if(parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2])>=28)TURN={url:'turn:turn.bistri.com:80',credential:'homeo',username:'homeo'};iceServers.iceServers=[STUN];}} var optional={optional:[]};if(!moz){optional.optional=[{DtlsSrtpKeyAgreement:true},{RtpDataChannels:options.onChannelMessage?true:false}];} var peer=new PeerConnection(iceServers,optional);openOffererChannel();var x=0;peer.onicecandidate=function(event){if(event.candidate){options.onICE(event.candidate);}else{if(options.onICEComplete){options.onICEComplete();} @@ -203,7 +203,7 @@ if(err){return false;} dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(params){if(params.useVideo){dialog.useVideo(true);} dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;} dialog.rtc.createAnswer(dialog.params.sdp);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;} -if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+"Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+"Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} +if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;} dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;} dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$(window).bind('beforeunload',function(){for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.logout();verto.purge();}} diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index 8ca3602e04..70f515cbd4 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -493,7 +493,7 @@ tmp = null; } - if (!(tmp && typeof(tmp) == "object" && tmp.constructor === Array)) { + if (tmp && !(typeof(tmp) == "object" && tmp.constructor === Array)) { console.warn("iceServers must be an array, reverting to default ice servers"); tmp = null; } From 51f2442a9e3e3478b38bfab882c7cfe4bfc37d92 Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 31 Dec 2014 11:52:06 -0800 Subject: [PATCH 30/72] resolve an automake warning about subdirs on latest automake Latest automake will detect then warn if the Makefile uses source files that are in subdirectories, but the subdirs option is not set. In the FreeSWITCH build system the current expected behavior is to expect the subdirs option to be enabled. FS-7122 #resolve --- libs/broadvoice/Makefile.am | 1 + libs/broadvoice/src/Makefile.am | 1 + libs/freetdm/Makefile.am | 2 +- libs/libcodec2/Makefile.am | 2 +- libs/libcodec2/src/Makefile.am | 2 +- libs/libcodec2/unittest/Makefile.am | 2 +- libs/libdingaling/Makefile.am | 2 +- libs/libzrtp/Makefile.am | 1 + libs/silk/Makefile.am | 2 +- libs/sofia-sip/Makefile.am | 2 +- libs/sofia-sip/s2check/Makefile.am | 2 ++ libs/srtp/Makefile.am | 2 +- libs/srtp/test/Makefile.am | 2 +- 13 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libs/broadvoice/Makefile.am b/libs/broadvoice/Makefile.am index f99395399c..a681b8d450 100644 --- a/libs/broadvoice/Makefile.am +++ b/libs/broadvoice/Makefile.am @@ -20,6 +20,7 @@ AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) +AUTOMAKE_OPTIONS = subdir-objects noinst_SCRIPTS = broadvoice.spec diff --git a/libs/broadvoice/src/Makefile.am b/libs/broadvoice/src/Makefile.am index 9b197ba891..c96590e472 100644 --- a/libs/broadvoice/src/Makefile.am +++ b/libs/broadvoice/src/Makefile.am @@ -21,6 +21,7 @@ AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) +AUTOMAKE_OPTIONS = subdir-objects MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = libbroadvoice.dsp \ diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index f6211e58e8..5d2317f5b8 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -30,7 +30,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ACLOCAL_AMFLAGS = -I build -AUTOMAKE_OPTIONS = foreign +AUTOMAKE_OPTIONS = foreign subdir-objects SRC = src diff --git a/libs/libcodec2/Makefile.am b/libs/libcodec2/Makefile.am index f4b1bfb68e..8c24f42fe4 100644 --- a/libs/libcodec2/Makefile.am +++ b/libs/libcodec2/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = -Isrc -fPIC -Wall -O3 -lm -AUTOMAKE_OPTS = gnu +AUTOMAKE_OPTIONS = gnu subdir-objects NAME = codec2 AM_CPPFLAGS = $(AM_CFLAGS) diff --git a/libs/libcodec2/src/Makefile.am b/libs/libcodec2/src/Makefile.am index 5dae366d8b..f06c42e0f6 100644 --- a/libs/libcodec2/src/Makefile.am +++ b/libs/libcodec2/src/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = -I../src -fPIC -Wall -O3 -g -AUTOMAKE_OPTS = gnu +AUTOMAKE_OPTIONS = gnu subdir-objects NAME = codec2 AM_CPPFLAGS = $(AM_CFLAGS) diff --git a/libs/libcodec2/unittest/Makefile.am b/libs/libcodec2/unittest/Makefile.am index 9e3494895d..e9a216d48e 100644 --- a/libs/libcodec2/unittest/Makefile.am +++ b/libs/libcodec2/unittest/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = -I../src -I$(abs_srcdir)/../src -fPIC -g -DFLOATING_POINT -DVAR_ARRAYS -O2 -Wall -AUTOMAKE_OPTS = gnu +AUTOMAKE_OPTIONS = gnu subdir-objects NAME = libcodec2 AM_CPPFLAGS = $(AM_CFLAGS) diff --git a/libs/libdingaling/Makefile.am b/libs/libdingaling/Makefile.am index 37bf42cb31..5da1715ef4 100644 --- a/libs/libdingaling/Makefile.am +++ b/libs/libdingaling/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = SUBDIRS = -AUTOMAKE_OPTIONS = foreign +AUTOMAKE_OPTIONS = foreign subdir-objects NAME=dingaling PREFIX=$(prefix) TOUCH_TARGET=@if test -f "$@" ; then touch "$@" ; fi ; diff --git a/libs/libzrtp/Makefile.am b/libs/libzrtp/Makefile.am index 2d3b82421d..ff5002a69e 100644 --- a/libs/libzrtp/Makefile.am +++ b/libs/libzrtp/Makefile.am @@ -4,6 +4,7 @@ # # Viktor Krikun # +AUTOMAKE_OPTIONS = subdir-objects libzrtp_includedir=$(includedir)/libzrtp libzrtp_include_HEADERS = \ diff --git a/libs/silk/Makefile.am b/libs/silk/Makefile.am index f61fb02b22..a410e96998 100644 --- a/libs/silk/Makefile.am +++ b/libs/silk/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = -Isrc -I$(abs_srcdir)/src -Iinterface -I$(abs_srcdir)/interface -fPIC -O3 -AUTOMAKE_OPTIONS = gnu +AUTOMAKE_OPTIONS = gnu subdir-objects NAME = libSKP_SILK_SDK AM_CPPFLAGS = $(AM_CFLAGS) diff --git a/libs/sofia-sip/Makefile.am b/libs/sofia-sip/Makefile.am index 7279695865..3a5bbb0baf 100644 --- a/libs/sofia-sip/Makefile.am +++ b/libs/sofia-sip/Makefile.am @@ -5,7 +5,7 @@ # Contact: Pekka Pessi # Licensed under LGPL. See file COPYING. -AUTOMAKE_OPTIONS = foreign 1.7 +AUTOMAKE_OPTIONS = foreign 1.7 subdir-objects SUBDIRS = libsofia-sip-ua $(GLIB_SUBDIRS) packages # tests s2check utils DIST_SUBDIRS = s2check libsofia-sip-ua libsofia-sip-ua-glib utils packages \ diff --git a/libs/sofia-sip/s2check/Makefile.am b/libs/sofia-sip/s2check/Makefile.am index b2851c591e..179b13e3ba 100644 --- a/libs/sofia-sip/s2check/Makefile.am +++ b/libs/sofia-sip/s2check/Makefile.am @@ -5,6 +5,8 @@ # Contact: Pekka Pessi # Licensed under LGPL. See file COPYING. +AUTOMAKE_OPTIONS = subdir-objects + # ---------------------------------------------------------------------- # Header paths diff --git a/libs/srtp/Makefile.am b/libs/srtp/Makefile.am index 88be99b4e0..4e89d96f26 100644 --- a/libs/srtp/Makefile.am +++ b/libs/srtp/Makefile.am @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = gnu +AUTOMAKE_OPTIONS = gnu subdir-objects NAME=srtp AM_CFLAGS = $(new_AM_CFLAGS) -I./src -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include diff --git a/libs/srtp/test/Makefile.am b/libs/srtp/test/Makefile.am index 2651f2714f..4af9005ac3 100644 --- a/libs/srtp/test/Makefile.am +++ b/libs/srtp/test/Makefile.am @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = gnu +AUTOMAKE_OPTIONS = gnu subdir-objects AM_CFLAGS = $(new_AM_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)/crypto/include AM_CPPFLAGS = $(AM_CFLAGS) AM_LDFLAGS = $(new_AM_LDFLAGS) -L$(srcdir) -lsrtp From 5187aaed79e0b6b49c6551210b3f42be5e1638a0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Jan 2015 11:17:31 -0600 Subject: [PATCH 31/72] FS-7117 #comment revert bf5210bf72d6c4b0d9b599a5a07ee59a9c947436 and implement it in ws.c please be sure to learn to use git commit hooks to properly associate commits with jiras --- libs/sofia-sip/libsofia-sip-ua/tport/ws.c | 27 ++++++++++++++++++----- src/mod/endpoints/mod_verto/mod_verto.c | 15 +------------ src/mod/endpoints/mod_verto/ws.c | 27 ++++++++++++++++++----- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index db2e39e5ab..e990f7f815 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -311,7 +311,10 @@ int ws_handshake(wsh_t *wsh) proto_buf); respond[511] = 0; - ws_raw_write(wsh, respond, strlen(respond)); + if (ws_raw_write(wsh, respond, strlen(respond)) != strlen(respond)) { + goto err; + } + wsh->handshake = 1; return 0; @@ -403,10 +406,16 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) ssize_t r; int sanity = 2000; int ssl_err = 0; + ssize_t wrote = 0; if (wsh->ssl) { do { - r = SSL_write(wsh->ssl, data, bytes); + r = SSL_write(wsh->ssl, (void *)((unsigned char *)data + wrote), bytes - wrote); + + if (r > 0) { + wrote += r; + } + if (sanity < 2000) { ms_sleep(1); } @@ -415,7 +424,7 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) ssl_err = SSL_get_error(wsh->ssl, r); } - } while (--sanity > 0 && r == -1 && ssl_err == SSL_ERROR_WANT_WRITE); + } while (--sanity > 0 && ((r == -1 && ssl_err == SSL_ERROR_WANT_WRITE) || (wsh->block && wrote < bytes))); if (ssl_err) { r = ssl_err * -1; @@ -425,12 +434,18 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) } do { - r = send(wsh->sock, data, bytes, 0); + r = send(wsh->sock, (void *)((unsigned char *)data + wrote), bytes - wrote, 0); + + if (r > 0) { + wrote += r; + } + if (sanity < 2000) { ms_sleep(1); } - } while (--sanity > 0 && r == -1 && xp_is_blocking(xp_errno())); - + + } while (--sanity > 0 && ((r == -1 && xp_is_blocking(xp_errno())) || (wsh->block && wrote < bytes))); + //if (r<0) { //printf("wRITE FAIL: %s\n", strerror(errno)); //} diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 20d2135774..55411371c6 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -1480,9 +1480,6 @@ static void http_static_handler(switch_http_request_t *request, verto_vhost_t *v for (;;) { switch_status_t status; - ssize_t written = 0; - ssize_t ret = 0; - int sanity = 3; flen = sizeof(chunk); status = switch_file_read(fd, chunk, &flen); @@ -1491,17 +1488,7 @@ static void http_static_handler(switch_http_request_t *request, verto_vhost_t *v break; } -again: - ret = ws_raw_write(&jsock->ws, chunk + written, flen); - if (ret == -1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error write %" SWITCH_SIZE_T_FMT " bytes!\n", flen); - ws_close(&jsock->ws, WS_NONE); - } else if (ret > 0 && ret < flen && sanity > 0) { - switch_yield(1000); - flen -= ret; - written += ret; - goto again; - } + ws_raw_write(&jsock->ws, chunk, flen); } switch_file_close(fd); } else { diff --git a/src/mod/endpoints/mod_verto/ws.c b/src/mod/endpoints/mod_verto/ws.c index db2e39e5ab..e990f7f815 100644 --- a/src/mod/endpoints/mod_verto/ws.c +++ b/src/mod/endpoints/mod_verto/ws.c @@ -311,7 +311,10 @@ int ws_handshake(wsh_t *wsh) proto_buf); respond[511] = 0; - ws_raw_write(wsh, respond, strlen(respond)); + if (ws_raw_write(wsh, respond, strlen(respond)) != strlen(respond)) { + goto err; + } + wsh->handshake = 1; return 0; @@ -403,10 +406,16 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) ssize_t r; int sanity = 2000; int ssl_err = 0; + ssize_t wrote = 0; if (wsh->ssl) { do { - r = SSL_write(wsh->ssl, data, bytes); + r = SSL_write(wsh->ssl, (void *)((unsigned char *)data + wrote), bytes - wrote); + + if (r > 0) { + wrote += r; + } + if (sanity < 2000) { ms_sleep(1); } @@ -415,7 +424,7 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) ssl_err = SSL_get_error(wsh->ssl, r); } - } while (--sanity > 0 && r == -1 && ssl_err == SSL_ERROR_WANT_WRITE); + } while (--sanity > 0 && ((r == -1 && ssl_err == SSL_ERROR_WANT_WRITE) || (wsh->block && wrote < bytes))); if (ssl_err) { r = ssl_err * -1; @@ -425,12 +434,18 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes) } do { - r = send(wsh->sock, data, bytes, 0); + r = send(wsh->sock, (void *)((unsigned char *)data + wrote), bytes - wrote, 0); + + if (r > 0) { + wrote += r; + } + if (sanity < 2000) { ms_sleep(1); } - } while (--sanity > 0 && r == -1 && xp_is_blocking(xp_errno())); - + + } while (--sanity > 0 && ((r == -1 && xp_is_blocking(xp_errno())) || (wsh->block && wrote < bytes))); + //if (r<0) { //printf("wRITE FAIL: %s\n", strerror(errno)); //} From 19a0a0fb00ae2dc4a674ef6f23c87c1f8220ebdc Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Jan 2015 17:18:21 -0600 Subject: [PATCH 32/72] sofia rebuild --- libs/sofia-sip/.update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index e9eed8de6c..cb4f5e11bc 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Jan 7 02:12:39 CST 2015 +Wed Jan 7 17:18:14 CST 2015 From fe305074f1b2cf9d02efec214f699e44ce0c1e3f Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 7 Jan 2015 11:30:15 -0600 Subject: [PATCH 33/72] escape pattern unless it's prefixed with ~ --- support-d/utils/hashfinder | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/support-d/utils/hashfinder b/support-d/utils/hashfinder index f6ec9df3e4..88df4ce5cc 100755 --- a/support-d/utils/hashfinder +++ b/support-d/utils/hashfinder @@ -48,8 +48,11 @@ sub doit($$) { my $loops = shift || 0; my $linematch = 0; - $pattern =~ s/\(/\\\(/g; - $pattern =~ s/\)/\\\)/g; + if ($pattern =~ /^\~(.*)/) { + $pattern = $1; + } else { + $pattern = quotemeta $pattern; + } if ($pattern =~ /^(\d+)$/) { $linematch = 1; From 16f7177c3d9ac4c3932d45e125498a1b5495dce6 Mon Sep 17 00:00:00 2001 From: William King Date: Wed, 31 Dec 2014 11:52:06 -0800 Subject: [PATCH 34/72] resolve an automake warning about subdirs on latest automake The file 'libs/sofia-sip/s2check/exit77.c' was moved in order to silence the warning and to keep the build working. There might be a build problem that results from this file move, but after serveral build tests I have not found one. The contents of the file are specifically for the make check target, so I believe it would be highly unlikely to cause problems with any production feature. FS-7122 #resolve --- libs/sofia-sip/.update | 2 +- libs/sofia-sip/libsofia-sip-ua/nta/Makefile.am | 2 +- libs/sofia-sip/{s2check => libsofia-sip-ua/nta}/exit77.c | 0 libs/sofia-sip/s2check/Makefile.am | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename libs/sofia-sip/{s2check => libsofia-sip-ua/nta}/exit77.c (100%) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index cb4f5e11bc..3d6072b228 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Jan 7 17:18:14 CST 2015 +Wed Jan 7 11:24:56 PST 2015 diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/Makefile.am b/libs/sofia-sip/libsofia-sip-ua/nta/Makefile.am index 07ca4a440b..9beb3bb139 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nta/Makefile.am +++ b/libs/sofia-sip/libsofia-sip-ua/nta/Makefile.am @@ -76,7 +76,7 @@ check_nta_SOURCES = check_nta.c check_nta.h \ check_nta_LDADD = ${LDADD} @CHECK_LIBS@ else -check_nta_SOURCES = $(top_srcdir)/s2check/exit77.c +check_nta_SOURCES = exit77.c endif # ---------------------------------------------------------------------- diff --git a/libs/sofia-sip/s2check/exit77.c b/libs/sofia-sip/libsofia-sip-ua/nta/exit77.c similarity index 100% rename from libs/sofia-sip/s2check/exit77.c rename to libs/sofia-sip/libsofia-sip-ua/nta/exit77.c diff --git a/libs/sofia-sip/s2check/Makefile.am b/libs/sofia-sip/s2check/Makefile.am index 179b13e3ba..ae4d7502b2 100644 --- a/libs/sofia-sip/s2check/Makefile.am +++ b/libs/sofia-sip/s2check/Makefile.am @@ -30,7 +30,7 @@ libs2_a_SOURCES = s2check.h s2tcase.c \ # ---------------------------------------------------------------------- # Install and distribution rules -EXTRA_DIST = exit77.c +EXTRA_DIST = # ---------------------------------------------------------------------- # Tests From 6afc2b5a2ebe862d8e6ec047ff0d95a51d9ff60a Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 7 Jan 2015 17:41:19 -0500 Subject: [PATCH 35/72] FS-6688: #resolve fix resubscribe through proxy with record route when the resub does not have a record route and the route has uri params --- src/mod/endpoints/mod_sofia/sofia_presence.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 550d0e874a..5520e6ec76 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -3906,8 +3906,8 @@ void sofia_presence_handle_sip_i_subscribe(int status, if (strstr(buf, "fs_path=") && !strstr(contact_str, "fs_path=")) { char *e = strchr(buf,';'); - size_t l = e ? buf-e : strlen(buf); - if (strncmp(contact_str,buf,l)) { + size_t l = e ? e-buf : strlen(buf); + if (!strncmp(contact_str,buf,l)) { contact = buf; } } From 1ed290e9304a687df1519c67c0a1fb868691db58 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Thu, 8 Jan 2015 11:38:53 +0800 Subject: [PATCH 36/72] follow commit 0bec209a, we should still allow NULL arg --- src/mod/endpoints/mod_verto/mod_verto.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 55411371c6..08f4a5095c 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -3583,15 +3583,14 @@ static switch_bool_t jsapi_func(const char *method, cJSON *params, jsock_t *jsoc if (jsock->allowed_fsapi && !strcmp(function, "fsapi")) { cJSON *data = cJSON_GetObjectItem(params, "data"); - cJSON *cmd; - cJSON *arg; + if (data) { + cJSON *cmd = cJSON_GetObjectItem(data, "cmd"); + cJSON *arg = cJSON_GetObjectItem(data, "arg"); - if (data && - (cmd = cJSON_GetObjectItem(data, "cmd")) && - (arg = cJSON_GetObjectItem(data, "arg")) && - cmd->type == cJSON_String && cmd->valuestring && - !auth_api_command(jsock, cmd->valuestring, arg ? arg->valuestring : NULL)) { - return SWITCH_FALSE; + if (cmd && cmd->type == cJSON_String && cmd->valuestring && + !auth_api_command(jsock, cmd->valuestring, arg ? arg->valuestring : NULL)) { + return SWITCH_FALSE; + } } } } From d199060249dba691630b6008c867f0d1a2ea14f3 Mon Sep 17 00:00:00 2001 From: Seven Du Date: Fri, 9 Jan 2015 08:00:13 +0800 Subject: [PATCH 37/72] FS-7036 #resolve #comment fixed in master originate takes care of new thread on outgoging calls, extra thread_launch causes race --- src/mod/endpoints/mod_rtmp/mod_rtmp.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.c b/src/mod/endpoints/mod_rtmp/mod_rtmp.c index 928ec58fe9..9e29601b4f 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.c +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.c @@ -672,11 +672,6 @@ switch_call_cause_t rtmp_outgoing_channel(switch_core_session_t *session, switch rtmp_set_channel_variables(*newsession); switch_core_hash_insert_wrlock(rsession->session_hash, switch_core_session_get_uuid(*newsession), tech_pvt, rsession->session_rwlock); - - if (switch_core_session_thread_launch(tech_pvt->session) == SWITCH_STATUS_FALSE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't spawn thread\n"); - goto fail; - } if (rsession) { rtmp_session_rwunlock(rsession); From a2b5356daec8cd4e3381fee77a196840cc3ca5db Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 9 Jan 2015 21:47:28 -0600 Subject: [PATCH 38/72] FS-7131 #comment please test --- src/switch_rtp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index d6dcf9cd22..48c90b9bdc 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -3938,6 +3938,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio switch_port_t port = 0; char bufc[30]; + READ_INC(rtp_session); if (proto == IPR_RTP) { ice = &rtp_session->ice; @@ -4006,6 +4007,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio switch_rtp_break(rtp_session); } + READ_DEC(rtp_session); + return SWITCH_STATUS_SUCCESS; } From d82611af0b6f3bae32137bd18ec618fd4d9406d6 Mon Sep 17 00:00:00 2001 From: William King Date: Fri, 9 Jan 2015 14:21:05 -0800 Subject: [PATCH 39/72] Fix build of freetdm on CentOS Revert the build change to freetdm since it broke the build of that modules on CentOS. Once a working change is finished, then it'll be committed against FS-7122. FS-7142 #resolve --- libs/freetdm/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 5d2317f5b8..f6211e58e8 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -30,7 +30,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ACLOCAL_AMFLAGS = -I build -AUTOMAKE_OPTIONS = foreign subdir-objects +AUTOMAKE_OPTIONS = foreign SRC = src From 3e6ffbcf06dcc6b11bdd9bf2906f6ff676e7ab7a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 12 Jan 2015 12:55:42 -0600 Subject: [PATCH 40/72] FS-7144 #resolve --- src/switch_rtp.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 48c90b9bdc..264e9b7ad6 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -235,6 +235,7 @@ typedef struct { uint8_t rready; int missed_count; char last_sent_id[13]; + switch_time_t last_ok; } switch_rtp_ice_t; struct switch_rtp; @@ -1014,7 +1015,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d //ice->ice_params->cands[ice->ice_params->chosen][ice->proto].priority; for (j = 0; j < 2; j++) { for (i = 0; i < icep[j]->ice_params->cand_idx; i++) { - if (icep[j]->ice_params->cands[i][icep[j]->proto].priority == *pri) { + if (icep[j]->ice_params && icep[j]->ice_params->cands[i][icep[j]->proto].priority == *pri) { if (j == IPR_RTP) { icep[j]->ice_params->chosen[j] = i; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Change candidate index to %d\n", i); @@ -1099,6 +1100,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_sockaddr_t *from_addr = rtp_session->from_addr; switch_socket_t *sock_output = rtp_session->sock_output; uint8_t hosts_set = 0; + switch_time_t now = switch_micro_time_now(); if (is_rtcp) { from_addr = rtp_session->rtcp_from_addr; @@ -1120,12 +1122,16 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d remote_ip = switch_get_addr(ipbuf, sizeof(ipbuf), from_addr); switch_stun_packet_attribute_add_xor_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr)); - if (!switch_cmp_addr(from_addr, ice->addr)) { - hosts_set++; - host = switch_get_addr(buf, sizeof(buf), from_addr); - port = switch_sockaddr_get_port(from_addr); - host2 = switch_get_addr(buf2, sizeof(buf2), ice->addr); - port2 = switch_sockaddr_get_port(ice->addr); + if (switch_cmp_addr(from_addr, ice->addr)) { + ice->last_ok = now; + } else { + if (!ice->last_ok || (now - ice->last_ok) > 1000000) { + hosts_set++; + host = switch_get_addr(buf, sizeof(buf), from_addr); + port = switch_sockaddr_get_port(from_addr); + host2 = switch_get_addr(buf2, sizeof(buf2), ice->addr); + port2 = switch_sockaddr_get_port(ice->addr); + } } if ((ice->type & ICE_VANILLA)) { From 403d32ce907234056356051f9bcfb616c01bbc05 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 12 Jan 2015 23:20:39 -0600 Subject: [PATCH 41/72] FS-7148 #resolve #comment declinatio mortuus obfirmo! --- src/switch_ivr_async.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 21180d789f..204b8fbe5c 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1141,6 +1141,7 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void * switch_yield(20000); continue; } else if ((!rh->thread_ready || switch_channel_down_nosig(channel)) && !inuse) { + switch_mutex_unlock(rh->buffer_mutex); break; } From 38d25f151d946bed7f80555d1ca27bc5de3c737e Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 13 Jan 2015 13:40:16 -0600 Subject: [PATCH 42/72] FS-7149 #comment Linux part complete. --- src/mod/asr_tts/mod_flite/Makefile.am | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/asr_tts/mod_flite/Makefile.am b/src/mod/asr_tts/mod_flite/Makefile.am index d26f774366..db5235db71 100644 --- a/src/mod/asr_tts/mod_flite/Makefile.am +++ b/src/mod/asr_tts/mod_flite/Makefile.am @@ -1,10 +1,10 @@ include $(top_srcdir)/build/modmake.rulesam MODNAME=mod_flite -FLITE=flite-1.5.4 +FLITE=flite-2.0.0 -FLITE_DIR=$(switch_srcdir)/libs/$(FLITE)-current -FLITE_BUILDDIR=$(switch_builddir)/libs/$(FLITE)-current +FLITE_DIR=$(switch_srcdir)/libs/$(FLITE)-release +FLITE_BUILDDIR=$(switch_builddir)/libs/$(FLITE)-release FLITE_LIBDIR=$(FLITE_BUILDDIR)/build/libs FLITE_A=$(FLITE_LIBDIR)/libflite_cmu_us_awb.a \ @@ -23,7 +23,7 @@ mod_flite_la_LDFLAGS = -avoid-version -module -no-undefined -shared BUILT_SOURCES= $(FLITE_A) $(FLITE_DIR): - $(GETLIB) $(FLITE)-current.tar.bz2 + $(GETLIB) $(FLITE)-release.tar.bz2 $(FLITE_BUILDDIR)/.stamp-configure: $(FLITE_DIR) mkdir -p $(FLITE_BUILDDIR) From 85fbddc655ec30b887dc5d6db9beea1afc491147 Mon Sep 17 00:00:00 2001 From: Chris Rienzo Date: Tue, 13 Jan 2015 16:01:02 -0500 Subject: [PATCH 43/72] FS-7150 #resolve #comment [mod_rayo] added param add-variables-to-events which will add channel variables to , , , and if set to true. Default is false. --- conf/rayo/autoload_configs/rayo.conf.xml | 2 + .../conf/autoload_configs/rayo.conf.xml | 2 + src/mod/event_handlers/mod_rayo/mod_rayo.c | 90 +++++++++++++------ 3 files changed, 67 insertions(+), 27 deletions(-) diff --git a/conf/rayo/autoload_configs/rayo.conf.xml b/conf/rayo/autoload_configs/rayo.conf.xml index a5f8748416..54aa388675 100644 --- a/conf/rayo/autoload_configs/rayo.conf.xml +++ b/conf/rayo/autoload_configs/rayo.conf.xml @@ -10,6 +10,8 @@ + + diff --git a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml index a5f8748416..54aa388675 100644 --- a/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml +++ b/src/mod/event_handlers/mod_rayo/conf/autoload_configs/rayo.conf.xml @@ -10,6 +10,8 @@ + + diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 4a840fd610..aa213ff168 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -235,6 +235,8 @@ static struct { int offline_logged; /** if true, channel variables are added to offer */ int add_variables_to_offer; + /** if true, channel variables are added to answered, ringing, end events */ + int add_variables_to_events; } globals; /** @@ -471,6 +473,54 @@ static void add_header(iks *node, const char *name, const char *value) } } +/** + * Add SIP
s to node + * @param node to add
to + * @param event source + * @param add_variables true if channel variables should be added + */ +static void add_headers_to_event(iks *node, switch_event_t *event, int add_variables) +{ + switch_event_header_t *header; + /* get all variables prefixed with sip_h_ */ + for (header = event->headers; header; header = header->next) { + if (!strncmp("variable_sip_h_", header->name, 15)) { + if (!zstr(header->name)) { + add_header(node, header->name + 15, header->value); + } + } else if (add_variables && !strncmp("variable_", header->name, 9)) { + if (!zstr(header->name)) { + char header_name[1024]; + snprintf(header_name, 1024, "variable-%s", header->name + 9); + add_header(node, header_name, header->value); + } + } + } +} + +/** + * Add SIP
s to node + * @param node to add
to + * @param add_variables true if channel variables should be added + */ +static void add_channel_headers_to_event(iks *node, switch_channel_t *channel, int add_variables) +{ + switch_event_header_t *var; + + /* add all SIP header variables and (if configured) all other variables */ + for (var = switch_channel_variable_first(channel); var; var = var->next) { + if (!strncmp("sip_h_", var->name, 6)) { + add_header(node, var->name + 6, var->value); + } + if (add_variables) { + char var_name[1024]; + snprintf(var_name, 1024, "variable-%s", var->name); + add_header(node, var_name, var->value); + } + } + switch_channel_variable_last(channel); +} + static void pause_inbound_calling(void) { int32_t arg = 1; @@ -1093,13 +1143,7 @@ static void rayo_call_send_end(struct rayo_call *call, switch_event_t *event, in /* add signaling headers */ if (event) { - switch_event_header_t *header; - /* get all variables prefixed with sip_h_ */ - for (header = event->headers; header; header = header->next) { - if (!strncmp("variable_sip_h_", header->name, 15)) { - add_header(end, header->name + 15, header->value); - } - } + add_headers_to_event(end, event, globals.add_variables_to_events); } /* send to all offered clients */ @@ -3403,6 +3447,7 @@ static void on_call_answer_event(struct rayo_client *rclient, switch_event_t *ev iks *revent = iks_new_presence("answered", RAYO_NS, switch_event_get_header(event, "variable_rayo_call_jid"), switch_event_get_header(event, "variable_rayo_dcp_jid")); + add_headers_to_event(iks_find(revent, "answered"), event, globals.add_variables_to_events); RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); } else if (!call->answer_event) { /* delay sending this event until the rayo APP has started */ @@ -3429,6 +3474,7 @@ static void on_call_ringing_event(struct rayo_client *rclient, switch_event_t *e iks *revent = iks_new_presence("ringing", RAYO_NS, switch_event_get_header(event, "variable_rayo_call_jid"), switch_event_get_header(event, "variable_rayo_dcp_jid")); + add_headers_to_event(iks_find(revent, "ringing"), event, globals.add_variables_to_events); call->ringing_sent = 1; RAYO_SEND_MESSAGE(call, RAYO_JID(rclient), revent); } @@ -3710,26 +3756,10 @@ static iks *rayo_create_offer(struct rayo_call *call, switch_core_session_t *ses iks_insert_attrib(offer, "to", profile->destination_number); } - /* add headers to offer */ - { - switch_event_header_t *var; - add_header(offer, "from", switch_channel_get_variable(channel, "sip_full_from")); - add_header(offer, "to", switch_channel_get_variable(channel, "sip_full_to")); - add_header(offer, "via", switch_channel_get_variable(channel, "sip_full_via")); - - /* add all SIP header variables and (if configured) all other variables */ - for (var = switch_channel_variable_first(channel); var; var = var->next) { - if (!strncmp("sip_h_", var->name, 6)) { - add_header(offer, var->name + 6, var->value); - } - if (globals.add_variables_to_offer) { - char var_name[1024]; - snprintf(var_name, 1024, "variable-%s", var->name); - add_header(offer, var_name, var->value); - } - } - switch_channel_variable_last(channel); - } + add_header(offer, "from", switch_channel_get_variable(channel, "sip_full_from")); + add_header(offer, "to", switch_channel_get_variable(channel, "sip_full_to")); + add_header(offer, "via", switch_channel_get_variable(channel, "sip_full_via")); + add_channel_headers_to_event(offer, channel, globals.add_variables_to_offer); return presence; } @@ -4127,6 +4157,7 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ globals.offer_uri = 1; globals.pause_when_offline = 0; globals.add_variables_to_offer = 0; + globals.add_variables_to_events = 0; /* get params */ { @@ -4167,6 +4198,11 @@ static switch_status_t do_config(switch_memory_pool_t *pool, const char *config_ if (switch_true(val)) { globals.add_variables_to_offer = 1; } + } else if (!strcasecmp(var, "add-variables-to-events")) { + if (switch_true(val)) { + globals.add_variables_to_offer = 1; + globals.add_variables_to_events = 1; + } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var); } From 59a9669485695f38ef24fbbb175c3636802711ab Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 13 Jan 2015 15:49:43 -0600 Subject: [PATCH 44/72] prevent crash when calling mediaStats JSON function in certian circumstances --- src/mod/applications/mod_commands/mod_commands.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 75d8625af2..7215084977 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3173,8 +3173,13 @@ SWITCH_STANDARD_JSON_API(json_stats_function) audio_stats = switch_core_media_get_stats(tsession, SWITCH_MEDIA_TYPE_AUDIO, switch_core_session_get_pool(tsession)); video_stats = switch_core_media_get_stats(tsession, SWITCH_MEDIA_TYPE_VIDEO, switch_core_session_get_pool(tsession)); - jsonify_stats(reply, "audio", audio_stats); - jsonify_stats(reply, "video", video_stats); + if (audio_stats) { + jsonify_stats(reply, "audio", audio_stats); + } + + if (video_stats) { + jsonify_stats(reply, "video", video_stats); + } if (true_enough(cdata) && switch_ivr_generate_json_cdr(tsession, &jevent, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { cJSON_AddItemToObject(reply, "channelData", jevent); From 378d35058fec4aaa471dced8112a69f0e779b45a Mon Sep 17 00:00:00 2001 From: Flavio Grossi Date: Tue, 13 Jan 2015 15:30:39 +0100 Subject: [PATCH 45/72] FS-7004 mod_sndfile: use correct permissions to create new files libsndfile's sf_open() function doesn't allow to pass file permissions. To fix this, new files are created with the correct mode before passing them to libsndfile. --- src/mod/formats/mod_sndfile/mod_sndfile.c | 27 ++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index 5d8d0865b5..6c714af11e 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -54,6 +54,8 @@ struct sndfile_context { typedef struct sndfile_context sndfile_context; +static switch_status_t sndfile_perform_open(sndfile_context *context, const char *path, int mode, switch_file_handle_t *handle); + static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const char *path) { sndfile_context *context; @@ -181,7 +183,7 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha ldup = strdup(last); switch_assert(ldup); switch_snprintf(last, alt_len - (last - alt_path), "%d%s%s", handle->samplerate, SWITCH_PATH_SEPARATOR, ldup); - if ((context->handle = sf_open(alt_path, mode, &context->sfinfo))) { + if (sndfile_perform_open(context, alt_path, mode, handle) == SWITCH_STATUS_SUCCESS) { path = alt_path; } else { /* Try to find the file at the highest rate possible if we can't find one that matches the exact rate. @@ -189,7 +191,7 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha */ for (i = 3; i >= 0; i--) { switch_snprintf(last, alt_len - (last - alt_path), "%d%s%s", rates[i], SWITCH_PATH_SEPARATOR, ldup); - if ((context->handle = sf_open(alt_path, mode, &context->sfinfo))) { + if (sndfile_perform_open(context, alt_path, mode, handle) == SWITCH_STATUS_SUCCESS) { path = alt_path; break; } @@ -198,7 +200,7 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha } if (!context->handle) { - if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) { + if (sndfile_perform_open(context, path, mode, handle) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening File [%s] [%s]\n", path, sf_strerror(context->handle)); status = SWITCH_STATUS_GENERR; goto end; @@ -236,6 +238,25 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha return status; } +static switch_status_t sndfile_perform_open(sndfile_context *context, const char *path, int mode, switch_file_handle_t *handle) { + if ((mode == SFM_WRITE) || (mode == SFM_RDWR)) { + if (switch_file_exists(path, handle->memory_pool) != SWITCH_STATUS_SUCCESS) { + switch_file_t *newfile; + unsigned int flags = SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE; + if ((switch_file_open(&newfile, path, flags, SWITCH_FPROT_OS_DEFAULT, handle->memory_pool) != SWITCH_STATUS_SUCCESS)) { + return SWITCH_STATUS_FALSE; + } + if ((switch_file_close(newfile) != SWITCH_STATUS_SUCCESS)) { + return SWITCH_STATUS_FALSE; + } + } + } + if ((context->handle = sf_open(path, mode, &context->sfinfo)) == 0) { + return SWITCH_STATUS_FALSE; + } + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t sndfile_file_truncate(switch_file_handle_t *handle, int64_t offset) { sndfile_context *context = handle->private_info; From adb0de93c531f6158f812157be27d36732a199b4 Mon Sep 17 00:00:00 2001 From: Brian West Date: Wed, 14 Jan 2015 11:08:50 -0600 Subject: [PATCH 46/72] #comment update debian utils for flite 2.0.0 #resolve --- debian/util.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/util.sh b/debian/util.sh index 67ff3b91ae..830947765f 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -101,7 +101,7 @@ getlibs () { getlib http://downloads.mongodb.org/cxx-driver/mongodb-linux-x86_64-v1.8-latest.tgz getlib http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz getlib http://files.freeswitch.org/downloads/libs/soundtouch-1.7.1.tar.gz - getlib http://files.freeswitch.org/downloads/libs/flite-1.5.4-current.tar.bz2 + getlib http://files.freeswitch.org/downloads/libs/flite-2.0.0-release.tar.bz2 getlib http://files.freeswitch.org/downloads/libs/sphinxbase-0.8.tar.gz getlib http://files.freeswitch.org/downloads/libs/pocketsphinx-0.8.tar.gz getlib http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz From 5c5b9fcd2174adcff0d9ca235d41864a062144fe Mon Sep 17 00:00:00 2001 From: Markus Lindenberg Date: Thu, 15 Jan 2015 09:21:32 +0100 Subject: [PATCH 47/72] If available, use libjpeg-turbo in Debian build dependencies Debian is transitioning to libjepg-turbo in Jessie. See the libjpeg-turbo transition plan for details: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754988 FS-7151 #resolve --- debian/bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 2267411cd3..7458934d43 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -308,7 +308,7 @@ Build-Depends: libogg-dev, libspeex-dev, libspeexdsp-dev, # configure options libssl-dev, unixodbc-dev, libpq-dev, - libncurses5-dev, libjpeg62-dev | libjpeg8-dev, + libncurses5-dev, libjpeg62-turbo-dev | libjpeg62-dev | libjpeg8-dev, python-dev, erlang-dev, # documentation doxygen, From acbeaec1bd23a79e939e3c8d8fd85816213b43f1 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 16 Jan 2015 09:28:28 -0600 Subject: [PATCH 48/72] #resolve FS-7162 #comment test --- src/mod/event_handlers/mod_format_cdr/mod_format_cdr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/event_handlers/mod_format_cdr/mod_format_cdr.c b/src/mod/event_handlers/mod_format_cdr/mod_format_cdr.c index 74278fc75d..fc353661e3 100644 --- a/src/mod/event_handlers/mod_format_cdr/mod_format_cdr.c +++ b/src/mod/event_handlers/mod_format_cdr/mod_format_cdr.c @@ -359,19 +359,19 @@ static switch_status_t my_on_reporting_cb(switch_core_session_t *session, cdr_pr switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist); } - if (profile->ssl_cert_file) { + if (!zstr(profile->ssl_cert_file)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, profile->ssl_cert_file); } - if (profile->ssl_key_file) { + if (!zstr(profile->ssl_key_file)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, profile->ssl_key_file); } - if (profile->ssl_key_password) { + if (!zstr(profile->ssl_key_password)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, profile->ssl_key_password); } - if (profile->ssl_version) { + if (!zstr(profile->ssl_version)) { if (!strcasecmp(profile->ssl_version, "SSLv3")) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); } else if (!strcasecmp(profile->ssl_version, "TLSv1")) { @@ -379,7 +379,7 @@ static switch_status_t my_on_reporting_cb(switch_core_session_t *session, cdr_pr } } - if (profile->ssl_cacert_file) { + if (!zstr(profile->ssl_cacert_file)) { switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, profile->ssl_cacert_file); } From c880f9a9dda7f7844be5d18a9c242e5ac557e908 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 16 Jan 2015 09:29:10 -0600 Subject: [PATCH 49/72] FS-7156 #resolve --- src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c index ecce4427b8..5bda3d7c18 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c @@ -337,19 +337,19 @@ static void process_cdr(cdr_data_t *data) switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist); } - if (globals.ssl_cert_file) { + if (!zstr(globals.ssl_cert_file)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, globals.ssl_cert_file); } - if (globals.ssl_key_file) { + if (!zstr(globals.ssl_key_file)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, globals.ssl_key_file); } - if (globals.ssl_key_password) { + if (!zstr(globals.ssl_key_password)) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, globals.ssl_key_password); } - if (globals.ssl_version) { + if (!zstr(globals.ssl_version)) { if (!strcasecmp(globals.ssl_version, "SSLv3")) { switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3); } else if (!strcasecmp(globals.ssl_version, "TLSv1")) { @@ -357,7 +357,7 @@ static void process_cdr(cdr_data_t *data) } } - if (globals.ssl_cacert_file) { + if (!zstr(globals.ssl_cacert_file)) { switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, globals.ssl_cacert_file); } From e408f409fedfeb0d93609d0d8426f7793d2e1c30 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 16 Jan 2015 09:31:08 -0600 Subject: [PATCH 50/72] FS-7157 #resolve --- src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c index 5bda3d7c18..098bd52a0e 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c @@ -399,8 +399,9 @@ static void process_cdr(cdr_data_t *data) switch_assert(globals.url_count <= MAX_URLS); if (globals.url_index >= globals.url_count) { globals.url_index = 0; - } - switch_log_printf(SWITCH_CHANNEL_UUID_LOG(data->uuid), SWITCH_LOG_ERROR, "Retry will be with url [%s]\n", globals.urls[globals.url_index]); + } else { + switch_log_printf(SWITCH_CHANNEL_UUID_LOG(data->uuid), SWITCH_LOG_ERROR, "Retry will be with url [%s]\n", globals.urls[globals.url_index]); + } } } switch_curl_easy_cleanup(curl_handle); From dc00863d5e6cdd80edda527c3d0a8ed747210a27 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Jan 2015 09:47:40 -0600 Subject: [PATCH 51/72] fix parsing error in verto --- src/mod/endpoints/mod_verto/mod_verto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 08f4a5095c..58b66a9b61 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -3612,7 +3612,7 @@ static switch_bool_t fsapi_func(const char *method, cJSON *params, jsock_t *jsoc arg = cJSON_GetObjectItem(params, "arg"); - if (jsock->allowed_fsapi) { + if (cmd && jsock->allowed_fsapi) { if (cmd->type == cJSON_String && cmd->valuestring && !auth_api_command(jsock, cmd->valuestring, arg ? arg->valuestring : NULL)) { return SWITCH_FALSE; } From 46cf8a4dce0599ce428dd129b99603ced0b682f4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Jan 2015 18:22:27 -0600 Subject: [PATCH 52/72] fix seg in ice rtp code --- src/switch_rtp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 264e9b7ad6..e4850bd135 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1014,6 +1014,9 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d //ice->ice_params->cands[ice->ice_params->chosen][ice->proto].priority; for (j = 0; j < 2; j++) { + if (!icep[j] || !icep[j]->ice_params) { + continue; + } for (i = 0; i < icep[j]->ice_params->cand_idx; i++) { if (icep[j]->ice_params && icep[j]->ice_params->cands[i][icep[j]->proto].priority == *pri) { if (j == IPR_RTP) { From 07d09b78693e2add0b5e7a2ec1234eab2200f2fa Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 20 Jan 2015 11:48:00 -0500 Subject: [PATCH 53/72] FS-7180: add --enable-sytem-lua configure arg to allow building mod_lua against system lua and allow mod_lua to build against lua 5.1 or 5.2 --- configure.ac | 3 +++ src/mod/languages/mod_lua/Makefile.am | 26 +++++++++------------- src/mod/languages/mod_lua/freeswitch_lua.h | 3 +++ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/configure.ac b/configure.ac index 160c79f72a..0c30551993 100644 --- a/configure.ac +++ b/configure.ac @@ -517,6 +517,9 @@ AC_SUBST(SYS_XMLRPC_CFLAGS) AC_SUBST(SYS_XMLRPC_LDFLAGS) AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"]) +AC_ARG_ENABLE([system-lua],[AS_HELP_STRING([--enable-system-lua],[use system lib for lua])],,[enable_system_lua="no"]) +AM_CONDITIONAL([SYSTEM_LUA],[test "${enable_system_lua}" = "yes"]) + AC_ARG_ENABLE(srtp, [AC_HELP_STRING([--disable-srtp],[build without srtp support])],[enable_srtp="$enableval"],[enable_srtp="yes"]) diff --git a/src/mod/languages/mod_lua/Makefile.am b/src/mod/languages/mod_lua/Makefile.am index 2a0b51e933..57a2c6b213 100644 --- a/src/mod/languages/mod_lua/Makefile.am +++ b/src/mod/languages/mod_lua/Makefile.am @@ -3,26 +3,22 @@ include $(top_srcdir)/build/modmake.rulesam MODNAME=mod_lua -LUA_DIR=$(switch_srcdir)/src/mod/languages/mod_lua/lua -LIBLUA_A=$(LUA_DIR)/liblua.a - AM_CFLAGS += $(CFLAGS) -D_GNU_SOURCE mod_LTLIBRARIES = mod_lua.la -mod_lua_la_SOURCES = mod_lua.cpp freeswitch_lua.cpp mod_lua_wrap.cpp lua/lapi.c lua/lcode.c lua/lctype.c lua/ldebug.c lua/ldo.c lua/ldump.c lua/lfunc.c lua/lgc.c lua/llex.c lua/lmem.c lua/lobject.c lua/lopcodes.c lua/lparser.c lua/lstate.c lua/lstring.c lua/ltable.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c lua/lauxlib.c lua/lbaselib.c lua/lbitlib.c lua/lcorolib.c lua/ldblib.c lua/liolib.c lua/lmathlib.c lua/loslib.c lua/lstrlib.c lua/ltablib.c lua/loadlib.c lua/linit.c +mod_lua_la_SOURCES = mod_lua.cpp freeswitch_lua.cpp mod_lua_wrap.cpp + +if SYSTEM_LUA +mod_lua_la_CXXFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) +mod_lua_la_CFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) +else +mod_lua_la_SOURCES += lua/lapi.c lua/lcode.c lua/lctype.c lua/ldebug.c lua/ldo.c lua/ldump.c lua/lfunc.c lua/lgc.c lua/llex.c lua/lmem.c lua/lobject.c lua/lopcodes.c lua/lparser.c lua/lstate.c lua/lstring.c lua/ltable.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c lua/lauxlib.c lua/lbaselib.c lua/lbitlib.c lua/lcorolib.c lua/ldblib.c lua/liolib.c lua/lmathlib.c lua/loslib.c lua/lstrlib.c lua/ltablib.c lua/loadlib.c lua/linit.c +LUA_DIR=$(switch_srcdir)/src/mod/languages/mod_lua/lua mod_lua_la_CXXFLAGS = -I$(LUA_DIR) $(AM_CPPFLAGS) -DLUA_USE_LINUX mod_lua_la_CFLAGS = -I$(LUA_DIR) $(AM_CPPFLAGS) -DLUA_USE_LINUX -mod_lua_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm $(AM_LDFLAGS) $(SOLINK) #$(LIBLUA_A) +endif -#BUILT_SOURCES = $(LIBLUA_A) -#$(mod_lua_la_SOURCES) : $(BUILT_SOURCES) -# -#$(LIBLUA_A): -# cd $(LUA_DIR) && $(MAKE) CC="$(CC)" AR="$(AR) rcu" CFLAGS="$(AM_CFLAGS) -DLUA_USE_LINUX -w" liblua.a -#luaclean: -# cd $(LUA_DIR) && $(MAKE) clean -# -#allclean: clean luaclean +mod_lua_la_LIBADD = $(switch_builddir)/libfreeswitch.la +mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -llua $(AM_LDFLAGS) $(SOLINK) reswig: swigclean lua_wrap diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index a1a289a70b..780fc2e545 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -9,6 +9,9 @@ extern "C" { } #include +#ifndef lua_pushglobaltable +#define lua_pushglobaltable(L) lua_pushvalue(L,LUA_GLOBALSINDEX) +#endif typedef struct{ lua_State* L; From 749ced5f6074c84b58e5a084f89fa86f4a93a043 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 20 Jan 2015 13:03:06 -0500 Subject: [PATCH 54/72] FS-7180: add --enable-sytem-lua configure arg to allow building mod_lua against system lua and allow mod_lua to build against lua 5.1 or 5.2 --- src/mod/languages/mod_lua/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mod/languages/mod_lua/Makefile.am b/src/mod/languages/mod_lua/Makefile.am index 57a2c6b213..18001c2a23 100644 --- a/src/mod/languages/mod_lua/Makefile.am +++ b/src/mod/languages/mod_lua/Makefile.am @@ -18,7 +18,11 @@ mod_lua_la_CFLAGS = -I$(LUA_DIR) $(AM_CPPFLAGS) -DLUA_USE_LINUX endif mod_lua_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -llua $(AM_LDFLAGS) $(SOLINK) +mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm $(AM_LDFLAGS) $(SOLINK) + +if SYSTEM_LUA +mod_lua_la_LDFLAGS += -llua +endif reswig: swigclean lua_wrap From 1d361b6108e4dfe75acd2f620615a4bd31c18481 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Jan 2015 12:26:57 -0600 Subject: [PATCH 55/72] FS-7180: let esl lua module build against lua 5.1 or 5.2 (requires newer swig) --- libs/esl/lua/Makefile | 2 +- libs/esl/lua/esl_wrap.cpp | 867 +++++++++++++++++++++----------------- 2 files changed, 485 insertions(+), 384 deletions(-) diff --git a/libs/esl/lua/Makefile b/libs/esl/lua/Makefile index c33853bfa7..872888dff5 100644 --- a/libs/esl/lua/Makefile +++ b/libs/esl/lua/Makefile @@ -5,7 +5,7 @@ WRAP_GCC_WARNING_SILENCE=-Wno-unused-function all: ESL.so esl_wrap.cpp: - swig -module ESL -lua -c++ -DMULTIPLICITY -I../src/include -o esl_wrap.cpp ../ESL.i + swig2.0 -module ESL -lua -c++ -DMULTIPLICITY -I../src/include -o esl_wrap.cpp ../ESL.i esl_wrap.o: esl_wrap.cpp $(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(LOCAL_CFLAGS) $(WRAP_GCC_WARNING_SILENCE) -c esl_wrap.cpp -o esl_wrap.o diff --git a/libs/esl/lua/esl_wrap.cpp b/libs/esl/lua/esl_wrap.cpp index 9dac86544d..8d781383fd 100644 --- a/libs/esl/lua/esl_wrap.cpp +++ b/libs/esl/lua/esl_wrap.cpp @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.35 + * Version 2.0.7 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -8,20 +8,27 @@ * interface file instead. * ----------------------------------------------------------------------------- */ +#define SWIGLUA +#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_LUA +#define SWIG_LUA_MODULE_GLOBAL + #ifdef __cplusplus +/* SwigValueWrapper is described in swig.swg */ template class SwigValueWrapper { - T *tt; + struct SwigMovePointer { + T *ptr; + SwigMovePointer(T *p) : ptr(p) { } + ~SwigMovePointer() { delete ptr; } + SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } + } pointer; + SwigValueWrapper& operator=(const SwigValueWrapper& rhs); + SwigValueWrapper(const SwigValueWrapper& rhs); public: - SwigValueWrapper() : tt(0) { } - SwigValueWrapper(const SwigValueWrapper& rhs) : tt(new T(*rhs.tt)) { } - SwigValueWrapper(const T& t) : tt(new T(t)) { } - ~SwigValueWrapper() { delete tt; } - SwigValueWrapper& operator=(const T& t) { delete tt; tt = new T(t); return *this; } - operator T&() const { return *tt; } - T *operator&() { return tt; } -private: - SwigValueWrapper& operator=(const SwigValueWrapper& rhs); + SwigValueWrapper() : pointer(0) { } + SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } + operator T&() const { return *pointer.ptr; } + T *operator&() { return pointer.ptr; } }; template T SwigValueInit() { @@ -71,6 +78,12 @@ template T SwigValueInit() { # endif #endif +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) @@ -135,7 +148,7 @@ template T SwigValueInit() { /* ----------------------------------------------------------------------------- * swigrun.swg * - * This file contains generic CAPI SWIG runtime support for pointer + * This file contains generic C API SWIG runtime support for pointer * type checking. * ----------------------------------------------------------------------------- */ @@ -154,11 +167,11 @@ template T SwigValueInit() { /* You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the swig runtime code. - In 99.9% of the cases, swig just needs to declare them as 'static'. + creating a static or dynamic library from the SWIG runtime code. + In 99.9% of the cases, SWIG just needs to declare them as 'static'. - But only do this if is strictly necessary, ie, if you have problems - with your compiler or so. + But only do this if strictly necessary, ie, if you have problems + with your compiler or suchlike. */ #ifndef SWIGRUNTIME @@ -185,14 +198,14 @@ template T SwigValueInit() { /* Flags/methods for returning states. - The swig conversion methods, as ConvertPtr, return and integer + The SWIG conversion methods, as ConvertPtr, return an integer that tells if the conversion was successful or not. And if not, an error code can be returned (see swigerrors.swg for the codes). Use the following macros/flags to set or process the returning states. - In old swig versions, you usually write code as: + In old versions of SWIG, code such as the following was usually written: if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { // success code @@ -200,7 +213,7 @@ template T SwigValueInit() { //fail code } - Now you can be more explicit as: + Now you can be more explicit: int res = SWIG_ConvertPtr(obj,vptr,ty.flags); if (SWIG_IsOK(res)) { @@ -209,7 +222,7 @@ template T SwigValueInit() { // fail code } - that seems to be the same, but now you can also do + which is the same really, but now you can also do Type *ptr; int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); @@ -227,7 +240,7 @@ template T SwigValueInit() { I.e., now SWIG_ConvertPtr can return new objects and you can identify the case and take care of the deallocation. Of course that - requires also to SWIG_ConvertPtr to return new result values, as + also requires SWIG_ConvertPtr to return new result values, such as int SWIG_ConvertPtr(obj, ptr,...) { if () { @@ -245,7 +258,7 @@ template T SwigValueInit() { Of course, returning the plain '0(success)/-1(fail)' still works, but you can be more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - swig errors code. + SWIG errors code. Finally, if the SWIG_CASTRANK_MODE is enabled, the result code allows to return the 'cast rank', for example, if you have this @@ -259,9 +272,8 @@ template T SwigValueInit() { fooi(1) // cast rank '0' just use the SWIG_AddCast()/SWIG_CheckState() +*/ - - */ #define SWIG_OK (0) #define SWIG_ERROR (-1) #define SWIG_IsOK(r) (r >= 0) @@ -286,7 +298,6 @@ template T SwigValueInit() { #define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) #define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - /* Cast-Rank Mode */ #if defined(SWIG_CASTRANK_MODE) # ifndef SWIG_TypeRank @@ -309,8 +320,6 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { #endif - - #include #ifdef __cplusplus @@ -407,40 +416,58 @@ SWIG_TypeCompare(const char *nb, const char *tb) { } -/* think of this as a c++ template<> or a scheme macro */ -#define SWIG_TypeCheck_Template(comparison, ty) \ - if (ty) { \ - swig_cast_info *iter = ty->cast; \ - while (iter) { \ - if (comparison) { \ - if (iter == ty->cast) return iter; \ - /* Move iter to the top of the linked list */ \ - iter->prev->next = iter->next; \ - if (iter->next) \ - iter->next->prev = iter->prev; \ - iter->next = ty->cast; \ - iter->prev = 0; \ - if (ty->cast) ty->cast->prev = iter; \ - ty->cast = iter; \ - return iter; \ - } \ - iter = iter->next; \ - } \ - } \ - return 0 - /* Check the typename */ SWIGRUNTIME swig_cast_info * SWIG_TypeCheck(const char *c, swig_type_info *ty) { - SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (strcmp(iter->type->name, c) == 0) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; } -/* Same as previous function, except strcmp is replaced with a pointer comparison */ +/* + Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison +*/ SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { - SWIG_TypeCheck_Template(iter->type == from, into); +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (iter->type == from) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; } /* @@ -703,9 +730,6 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { #endif /* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * * luarun.swg * * This file contains the runtime support for Lua modules @@ -722,6 +746,62 @@ extern "C" { #include /* for malloc */ #include /* for a few sanity tests */ +/* ----------------------------------------------------------------------------- + * Lua flavors + * ----------------------------------------------------------------------------- */ + +#define SWIG_LUA_FLAVOR_LUA 1 +#define SWIG_LUA_FLAVOR_ELUA 2 +#define SWIG_LUA_FLAVOR_ELUAC 3 + +#if !defined(SWIG_LUA_TARGET) +# error SWIG_LUA_TARGET not defined +#endif + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) +# define SWIG_LUA_CONSTTAB_INT(B, C) LSTRKEY(B), LNUMVAL(C) +# define SWIG_LUA_CONSTTAB_FLOAT(B, C) LSTRKEY(B), LNUMVAL(C) +# define SWIG_LUA_CONSTTAB_STRING(B, C) LSTRKEY(B), LSTRVAL(C) +# define SWIG_LUA_CONSTTAB_CHAR(B, C) LSTRKEY(B), LNUMVAL(C) +#else /* SWIG_LUA_FLAVOR_LUA */ +# define SWIG_LUA_CONSTTAB_INT(B, C) SWIG_LUA_INT, (char *)B, (long)C, 0, 0, 0 +# define SWIG_LUA_CONSTTAB_FLOAT(B, C) SWIG_LUA_FLOAT, (char *)B, 0, (double)C, 0, 0 +# define SWIG_LUA_CONSTTAB_STRING(B, C) SWIG_LUA_STRING, (char *)B, 0, 0, (void *)C, 0 +# define SWIG_LUA_CONSTTAB_CHAR(B, C) SWIG_LUA_CHAR, (char *)B, (long)C, 0, 0, 0 +#endif + +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC) +# define LRO_STRVAL(v) {{.p = (char *) v}, LUA_TSTRING} +# define LSTRVAL LRO_STRVAL +#endif + +/* ----------------------------------------------------------------------------- + * compatibility defines + * ----------------------------------------------------------------------------- */ + +/* History of Lua C API length functions: In Lua 5.0 (and before?) + there was "lua_strlen". In Lua 5.1, this was renamed "lua_objlen", + but a compatibility define of "lua_strlen" was added. In Lua 5.2, + this function was again renamed, to "lua_rawlen" (to emphasize that + it doesn't call the "__len" metamethod), and the compatibility + define of lua_strlen was removed. All SWIG uses have been updated + to "lua_rawlen", and we add our own defines of that here for older + versions of Lua. */ +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 +# define lua_rawlen lua_strlen +#elif LUA_VERSION_NUM == 501 +# define lua_rawlen lua_objlen +#endif + + +/* lua_pushglobaltable is the recommended "future-proof" way to get + the global table for Lua 5.2 and later. Here we define + lua_pushglobaltable ourselves for Lua versions before 5.2. */ +#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 +# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) +#endif + + /* ----------------------------------------------------------------------------- * global swig types * ----------------------------------------------------------------------------- */ @@ -783,7 +863,7 @@ typedef struct { /* this is the struct for wrapping arbitary packed binary data (currently it is only used for member function pointers) the data ordering is similar to swig_lua_userdata, but it is currently not possible -to tell the two structures apart within Swig, other than by looking at the type +to tell the two structures apart within SWIG, other than by looking at the type */ typedef struct { swig_type_info *type; @@ -888,12 +968,24 @@ SWIGINTERN int SWIG_Lua_module_get(lua_State* L) lua_tostring(L,2)); */ /* get the metatable */ - assert(lua_istable(L,1)); /* just in case */ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) + assert(lua_isrotable(L,1)); /* just in case */ +#else + assert(lua_istable(L,1)); /* default Lua action */ +#endif lua_getmetatable(L,1); /* get the metatable */ - assert(lua_istable(L,-1)); /* just in case */ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) + assert(lua_isrotable(L,-1)); /* just in case */ +#else + assert(lua_istable(L,-1)); +#endif SWIG_Lua_get_table(L,".get"); /* get the .get table */ lua_remove(L,3); /* remove metatable */ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) + if (lua_isrotable(L,-1)) +#else if (lua_istable(L,-1)) +#endif { /* look for the key in the .get table */ lua_pushvalue(L,2); /* key */ @@ -908,7 +1000,7 @@ SWIGINTERN int SWIG_Lua_module_get(lua_State* L) } lua_pop(L,1); /* remove the .get */ lua_pushnil(L); /* return a nil */ - return 1; + return 1; } /* the module.set method used for setting linked data */ @@ -920,12 +1012,24 @@ SWIGINTERN int SWIG_Lua_module_set(lua_State* L) (3) any for the new value */ /* get the metatable */ - assert(lua_istable(L,1)); /* just in case */ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) + assert(lua_isrotable(L,1)); /* just in case */ +#else + assert(lua_istable(L,1)); /* default Lua action */ +#endif lua_getmetatable(L,1); /* get the metatable */ - assert(lua_istable(L,-1)); /* just in case */ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) + assert(lua_isrotable(L,-1)); /* just in case */ +#else + assert(lua_istable(L,-1)); +#endif SWIG_Lua_get_table(L,".set"); /* get the .set table */ lua_remove(L,4); /* remove metatable */ +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) + if (lua_isrotable(L,-1)) +#else if (lua_istable(L,-1)) +#endif { /* look for the key in the .set table */ lua_pushvalue(L,2); /* key */ @@ -937,6 +1041,11 @@ SWIGINTERN int SWIG_Lua_module_set(lua_State* L) lua_call(L,1,0); return 0; } +#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) + else { + return 0; // Exits stoically if an invalid key is initialized. + } +#endif } lua_settop(L,3); /* reset back to start */ /* we now have the table, key & new value, so just set directly */ @@ -944,7 +1053,8 @@ SWIGINTERN int SWIG_Lua_module_set(lua_State* L) return 0; } -/* registering a module in lua */ +#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) +/* registering a module in lua. Pushes the module table on the stack. */ SWIGINTERN void SWIG_Lua_module_begin(lua_State* L,const char* name) { assert(lua_istable(L,-1)); /* just in case */ @@ -961,8 +1071,16 @@ SWIGINTERN void SWIG_Lua_module_begin(lua_State* L,const char* name) lua_newtable(L); /* the .set table */ lua_rawset(L,-3); /* add .set into metatable */ lua_setmetatable(L,-2); /* sets meta table in module */ +#ifdef SWIG_LUA_MODULE_GLOBAL + /* If requested, install the module directly into the global namespace. */ lua_rawset(L,-3); /* add module into parent */ SWIG_Lua_get_table(L,name); /* get the table back out */ +#else + /* Do not install the module table as global name. The stack top has + the module table with the name below. We pop the top and replace + the name with it. */ + lua_replace(L,-2); +#endif } /* ending the register */ @@ -990,6 +1108,7 @@ SWIGINTERN void SWIG_Lua_module_add_variable(lua_State* L,const char* name,lua_C } lua_pop(L,1); /* tidy stack (remove meta) */ } +#endif /* adding a function module */ SWIGINTERN void SWIG_Lua_module_add_function(lua_State* L,const char* name,lua_CFunction fn) @@ -1119,6 +1238,39 @@ SWIGINTERN int SWIG_Lua_class_destruct(lua_State* L) return 0; } +/* the class.__tostring method called by the interpreter and print */ +SWIGINTERN int SWIG_Lua_class_tostring(lua_State* L) +{ +/* there should be 1 param passed in + (1) userdata (not the metatable) */ + assert(lua_isuserdata(L,1)); /* just in case */ + unsigned long userData = (unsigned long)lua_touserdata(L,1); /* get the userdata address for later */ + lua_getmetatable(L,1); /* get the meta table */ + assert(lua_istable(L,-1)); /* just in case */ + + lua_getfield(L, -1, ".type"); + const char* className = lua_tostring(L, -1); + + char output[256]; + sprintf(output, "<%s userdata: %lX>", className, userData); + + lua_pushstring(L, (const char*)output); + return 1; +} + +/* to manually disown some userdata */ +SWIGINTERN int SWIG_Lua_class_disown(lua_State* L) +{ +/* there should be 1 params passed in + (1) userdata (not the meta table) */ + swig_lua_userdata* usr; + assert(lua_isuserdata(L,-1)); /* just in case */ + usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */ + + usr->own = 0; /* clear our ownership */ + return 0; +} + /* gets the swig class registry (or creates it) */ SWIGINTERN void SWIG_Lua_get_class_registry(lua_State* L) { @@ -1244,11 +1396,15 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss) /* add a table called ".fn" */ lua_pushstring(L,".fn"); lua_newtable(L); + /* add manual disown method */ + SWIG_Lua_add_function(L,"__disown",SWIG_Lua_class_disown); lua_rawset(L,-3); /* add accessor fns for using the .get,.set&.fn */ SWIG_Lua_add_function(L,"__index",SWIG_Lua_class_get); SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_class_set); SWIG_Lua_add_function(L,"__gc",SWIG_Lua_class_destruct); + /* add tostring method for better output */ + SWIG_Lua_add_function(L,"__tostring",SWIG_Lua_class_tostring); /* add it */ lua_rawset(L,-3); /* metatable into registry */ lua_pop(L,1); /* tidy stack (remove registry) */ @@ -1291,7 +1447,9 @@ SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State* L,void* ptr,swig_type_info *t usr->ptr=ptr; /* set the ptr */ usr->type=type; usr->own=own; +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) _SWIG_Lua_AddMetatable(L,type); /* add metatable */ +#endif } /* takes a object from the lua stack & converts it into an object of the correct type @@ -1368,7 +1526,7 @@ SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp) swig_lua_userdata* usr; if (lua_isuserdata(L,tp)) { - usr=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ + usr=(swig_lua_userdata*)lua_touserdata(L,tp); /* get data */ if (usr && usr->type && usr->type->str) return usr->type->str; return "userdata (unknown type)"; @@ -1404,6 +1562,7 @@ SWIGRUNTIME int SWIG_Lua_equal(lua_State* L) * global variable support code: class/struct typemap functions * ----------------------------------------------------------------------------- */ +#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) /* Install Constants */ SWIGINTERN void SWIG_Lua_InstallConstants(lua_State* L, swig_lua_const_info constants[]) { @@ -1445,6 +1604,7 @@ SWIG_Lua_InstallConstants(lua_State* L, swig_lua_const_info constants[]) { } } } +#endif /* ----------------------------------------------------------------------------- * executing lua code from within the wrapper @@ -1501,7 +1661,6 @@ static swig_module_info swig_module = {swig_types, 4, 0, 0, 0, 0}; #define SWIG_LUACODE luaopen_ESL_luacode - namespace swig { typedef struct{} LANGUAGE_OBJ; } @@ -1510,17 +1669,25 @@ typedef struct{} LANGUAGE_OBJ; #include "esl.h" #include "esl_oop.h" + +SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) { + int ret = lua_isstring(L, idx); + if (!ret) + ret = lua_isnil(L, idx); + return ret; +} + #ifdef __cplusplus extern "C" { #endif static int _wrap_ESLevent_event_set(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; esl_event_t *arg2 = (esl_event_t *) 0 ; - SWIG_check_num_args("event",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("event",1,"ESLevent *"); - if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("event",2,"esl_event_t *"); + SWIG_check_num_args("ESLevent::event",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::event",1,"ESLevent *"); + if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("ESLevent::event",2,"esl_event_t *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_event_set",1,SWIGTYPE_p_ESLevent); @@ -1533,8 +1700,6 @@ static int _wrap_ESLevent_event_set(lua_State* L) { if (arg1) (arg1)->event = arg2; - SWIG_arg=0; - return SWIG_arg; if(0) SWIG_fail; @@ -1546,19 +1711,18 @@ fail: static int _wrap_ESLevent_event_get(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; esl_event_t *result = 0 ; - SWIG_check_num_args("event",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("event",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::event",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::event",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_event_get",1,SWIGTYPE_p_ESLevent); } result = (esl_event_t *) ((arg1)->event); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_esl_event_t,0); SWIG_arg++; return SWIG_arg; @@ -1571,13 +1735,13 @@ fail: static int _wrap_ESLevent_serialized_string_set(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; - SWIG_check_num_args("serialized_string",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("serialized_string",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("serialized_string",2,"char *"); + SWIG_check_num_args("ESLevent::serialized_string",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::serialized_string",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::serialized_string",2,"char *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_serialized_string_set",1,SWIGTYPE_p_ESLevent); @@ -1585,7 +1749,7 @@ static int _wrap_ESLevent_serialized_string_set(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); { - if (arg1->serialized_string) delete [] arg1->serialized_string; + delete [] arg1->serialized_string; if (arg2) { arg1->serialized_string = (char *) (new char[strlen((const char *)arg2)+1]); strcpy((char *)arg1->serialized_string, (const char *)arg2); @@ -1593,7 +1757,6 @@ static int _wrap_ESLevent_serialized_string_set(lua_State* L) { arg1->serialized_string = 0; } } - SWIG_arg=0; return SWIG_arg; @@ -1606,20 +1769,19 @@ fail: static int _wrap_ESLevent_serialized_string_get(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *result = 0 ; - SWIG_check_num_args("serialized_string",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("serialized_string",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::serialized_string",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::serialized_string",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_serialized_string_get",1,SWIGTYPE_p_ESLevent); } result = (char *) ((arg1)->serialized_string); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -1631,13 +1793,13 @@ fail: static int _wrap_ESLevent_mine_set(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; int arg2 ; - SWIG_check_num_args("mine",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("mine",1,"ESLevent *"); - if(!lua_isnumber(L,2)) SWIG_fail_arg("mine",2,"int"); + SWIG_check_num_args("ESLevent::mine",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::mine",1,"ESLevent *"); + if(!lua_isnumber(L,2)) SWIG_fail_arg("ESLevent::mine",2,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_mine_set",1,SWIGTYPE_p_ESLevent); @@ -1646,8 +1808,6 @@ static int _wrap_ESLevent_mine_set(lua_State* L) { arg2 = (int)lua_tonumber(L, 2); if (arg1) (arg1)->mine = arg2; - SWIG_arg=0; - return SWIG_arg; if(0) SWIG_fail; @@ -1659,19 +1819,18 @@ fail: static int _wrap_ESLevent_mine_get(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; int result; - SWIG_check_num_args("mine",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("mine",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::mine",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::mine",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_mine_get",1,SWIGTYPE_p_ESLevent); } result = (int) ((arg1)->mine); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -1684,20 +1843,19 @@ fail: static int _wrap_new_ESLevent__SWIG_0(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; char *arg1 = (char *) 0 ; char *arg2 = (char *) NULL ; ESLevent *result = 0 ; - SWIG_check_num_args("ESLevent",1,2) - if(!lua_isstring(L,1)) SWIG_fail_arg("ESLevent",1,"char const *"); - if(lua_gettop(L)>=2 && !lua_isstring(L,2)) SWIG_fail_arg("ESLevent",2,"char const *"); + SWIG_check_num_args("ESLevent::ESLevent",1,2) + if(!SWIG_lua_isnilstring(L,1)) SWIG_fail_arg("ESLevent::ESLevent",1,"char const *"); + if(lua_gettop(L)>=2 && !SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::ESLevent",2,"char const *"); arg1 = (char *)lua_tostring(L, 1); if(lua_gettop(L)>=2){ arg2 = (char *)lua_tostring(L, 2); } result = (ESLevent *)new ESLevent((char const *)arg1,(char const *)arg2); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -1710,14 +1868,14 @@ fail: static int _wrap_new_ESLevent__SWIG_1(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; esl_event_t *arg1 = (esl_event_t *) 0 ; int arg2 = (int) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("ESLevent",1,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent",1,"esl_event_t *"); - if(lua_gettop(L)>=2 && !lua_isnumber(L,2)) SWIG_fail_arg("ESLevent",2,"int"); + SWIG_check_num_args("ESLevent::ESLevent",1,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::ESLevent",1,"esl_event_t *"); + if(lua_gettop(L)>=2 && !lua_isnumber(L,2)) SWIG_fail_arg("ESLevent::ESLevent",2,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_esl_event_t,0))){ SWIG_fail_ptr("new_ESLevent",1,SWIGTYPE_p_esl_event_t); @@ -1727,7 +1885,6 @@ static int _wrap_new_ESLevent__SWIG_1(lua_State* L) { arg2 = (int)lua_tonumber(L, 2); } result = (ESLevent *)new ESLevent(arg1,arg2); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -1740,19 +1897,18 @@ fail: static int _wrap_new_ESLevent__SWIG_2(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("ESLevent",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::ESLevent",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::ESLevent",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("new_ESLevent",1,SWIGTYPE_p_ESLevent); } result = (ESLevent *)new ESLevent(arg1); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -1810,14 +1966,14 @@ static int _wrap_new_ESLevent(lua_State* L) { if ((argc >= 1) && (argc <= 2)) { int _v; { - _v = lua_isstring(L,argv[0]); + _v = SWIG_lua_isnilstring(L,argv[0]); } if (_v) { if (argc <= 1) { return _wrap_new_ESLevent__SWIG_0(L); } { - _v = lua_isstring(L,argv[1]); + _v = SWIG_lua_isnilstring(L,argv[1]); } if (_v) { return _wrap_new_ESLevent__SWIG_0(L); @@ -1825,45 +1981,24 @@ static int _wrap_new_ESLevent(lua_State* L) { } } - lua_pushstring(L,"No matching function for overloaded 'new_ESLevent'"); + lua_pushstring(L,"Wrong arguments for overloaded function 'new_ESLevent'\n" + " Possible C/C++ prototypes are:\n" + " ESLevent::ESLevent(char const *,char const *)\n" + " ESLevent::ESLevent(esl_event_t *,int)\n" + " ESLevent::ESLevent(ESLevent *)\n"); lua_error(L);return 0; } -static int _wrap_delete_ESLevent(lua_State* L) { - int SWIG_arg = -1; - ESLevent *arg1 = (ESLevent *) 0 ; - - SWIG_check_num_args("ESLevent",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent",1,"ESLevent *"); - - if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,SWIG_POINTER_DISOWN))){ - SWIG_fail_ptr("delete_ESLevent",1,SWIGTYPE_p_ESLevent); - } - - delete arg1; - - SWIG_arg=0; - - return SWIG_arg; - - if(0) SWIG_fail; - -fail: - lua_error(L); - return SWIG_arg; -} - - static int _wrap_ESLevent_serialize(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) NULL ; char *result = 0 ; - SWIG_check_num_args("serialize",1,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("serialize",1,"ESLevent *"); - if(lua_gettop(L)>=2 && !lua_isstring(L,2)) SWIG_fail_arg("serialize",2,"char const *"); + SWIG_check_num_args("ESLevent::serialize",1,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::serialize",1,"ESLevent *"); + if(lua_gettop(L)>=2 && !SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::serialize",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_serialize",1,SWIGTYPE_p_ESLevent); @@ -1873,8 +2008,7 @@ static int _wrap_ESLevent_serialize(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); } result = (char *)(arg1)->serialize((char const *)arg2); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -1886,15 +2020,15 @@ fail: static int _wrap_ESLevent_setPriority(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; esl_priority_t arg2 = (esl_priority_t) ESL_PRIORITY_NORMAL ; - bool result; esl_priority_t *argp2 ; + bool result; - SWIG_check_num_args("setPriority",1,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("setPriority",1,"ESLevent *"); - if(lua_gettop(L)>=2 && !lua_isuserdata(L,2)) SWIG_fail_arg("setPriority",2,"esl_priority_t"); + SWIG_check_num_args("ESLevent::setPriority",1,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::setPriority",1,"ESLevent *"); + if(lua_gettop(L)>=2 && !lua_isuserdata(L,2)) SWIG_fail_arg("ESLevent::setPriority",2,"esl_priority_t"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_setPriority",1,SWIGTYPE_p_ESLevent); @@ -1907,8 +2041,7 @@ static int _wrap_ESLevent_setPriority(lua_State* L) { arg2 = *argp2; } result = (bool)(arg1)->setPriority(arg2); - SWIG_arg=0; - lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + lua_pushboolean(L,(int)(result!=0)); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -1920,16 +2053,16 @@ fail: static int _wrap_ESLevent_getHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; int arg3 = (int) -1 ; char *result = 0 ; - SWIG_check_num_args("getHeader",2,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("getHeader",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("getHeader",2,"char const *"); - if(lua_gettop(L)>=3 && !lua_isnumber(L,3)) SWIG_fail_arg("getHeader",3,"int"); + SWIG_check_num_args("ESLevent::getHeader",2,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::getHeader",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::getHeader",2,"char const *"); + if(lua_gettop(L)>=3 && !lua_isnumber(L,3)) SWIG_fail_arg("ESLevent::getHeader",3,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_getHeader",1,SWIGTYPE_p_ESLevent); @@ -1940,8 +2073,7 @@ static int _wrap_ESLevent_getHeader(lua_State* L) { arg3 = (int)lua_tonumber(L, 3); } result = (char *)(arg1)->getHeader((char const *)arg2,arg3); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -1953,20 +2085,19 @@ fail: static int _wrap_ESLevent_getBody(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *result = 0 ; - SWIG_check_num_args("getBody",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("getBody",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::getBody",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::getBody",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_getBody",1,SWIGTYPE_p_ESLevent); } result = (char *)(arg1)->getBody(); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -1978,20 +2109,19 @@ fail: static int _wrap_ESLevent_getType(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *result = 0 ; - SWIG_check_num_args("getType",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("getType",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::getType",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::getType",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_getType",1,SWIGTYPE_p_ESLevent); } result = (char *)(arg1)->getType(); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2003,14 +2133,14 @@ fail: static int _wrap_ESLevent_addBody(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; bool result; - SWIG_check_num_args("addBody",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("addBody",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("addBody",2,"char const *"); + SWIG_check_num_args("ESLevent::addBody",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::addBody",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::addBody",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_addBody",1,SWIGTYPE_p_ESLevent); @@ -2018,8 +2148,7 @@ static int _wrap_ESLevent_addBody(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); result = (bool)(arg1)->addBody((char const *)arg2); - SWIG_arg=0; - lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + lua_pushboolean(L,(int)(result!=0)); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2031,16 +2160,16 @@ fail: static int _wrap_ESLevent_addHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; bool result; - SWIG_check_num_args("addHeader",3,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("addHeader",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("addHeader",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("addHeader",3,"char const *"); + SWIG_check_num_args("ESLevent::addHeader",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::addHeader",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::addHeader",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLevent::addHeader",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_addHeader",1,SWIGTYPE_p_ESLevent); @@ -2049,8 +2178,7 @@ static int _wrap_ESLevent_addHeader(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (bool)(arg1)->addHeader((char const *)arg2,(char const *)arg3); - SWIG_arg=0; - lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + lua_pushboolean(L,(int)(result!=0)); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2062,16 +2190,16 @@ fail: static int _wrap_ESLevent_pushHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; bool result; - SWIG_check_num_args("pushHeader",3,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("pushHeader",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("pushHeader",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("pushHeader",3,"char const *"); + SWIG_check_num_args("ESLevent::pushHeader",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::pushHeader",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::pushHeader",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLevent::pushHeader",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_pushHeader",1,SWIGTYPE_p_ESLevent); @@ -2080,8 +2208,7 @@ static int _wrap_ESLevent_pushHeader(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (bool)(arg1)->pushHeader((char const *)arg2,(char const *)arg3); - SWIG_arg=0; - lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + lua_pushboolean(L,(int)(result!=0)); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2093,16 +2220,16 @@ fail: static int _wrap_ESLevent_unshiftHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; bool result; - SWIG_check_num_args("unshiftHeader",3,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("unshiftHeader",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("unshiftHeader",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("unshiftHeader",3,"char const *"); + SWIG_check_num_args("ESLevent::unshiftHeader",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::unshiftHeader",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::unshiftHeader",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLevent::unshiftHeader",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_unshiftHeader",1,SWIGTYPE_p_ESLevent); @@ -2111,8 +2238,7 @@ static int _wrap_ESLevent_unshiftHeader(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (bool)(arg1)->unshiftHeader((char const *)arg2,(char const *)arg3); - SWIG_arg=0; - lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + lua_pushboolean(L,(int)(result!=0)); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2124,14 +2250,14 @@ fail: static int _wrap_ESLevent_delHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *arg2 = (char *) 0 ; bool result; - SWIG_check_num_args("delHeader",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("delHeader",1,"ESLevent *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("delHeader",2,"char const *"); + SWIG_check_num_args("ESLevent::delHeader",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::delHeader",1,"ESLevent *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLevent::delHeader",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_delHeader",1,SWIGTYPE_p_ESLevent); @@ -2139,8 +2265,7 @@ static int _wrap_ESLevent_delHeader(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); result = (bool)(arg1)->delHeader((char const *)arg2); - SWIG_arg=0; - lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + lua_pushboolean(L,(int)(result!=0)); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2152,20 +2277,19 @@ fail: static int _wrap_ESLevent_firstHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *result = 0 ; - SWIG_check_num_args("firstHeader",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("firstHeader",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::firstHeader",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::firstHeader",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_firstHeader",1,SWIGTYPE_p_ESLevent); } result = (char *)(arg1)->firstHeader(); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2177,20 +2301,19 @@ fail: static int _wrap_ESLevent_nextHeader(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLevent *arg1 = (ESLevent *) 0 ; char *result = 0 ; - SWIG_check_num_args("nextHeader",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("nextHeader",1,"ESLevent *"); + SWIG_check_num_args("ESLevent::nextHeader",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLevent::nextHeader",1,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLevent,0))){ SWIG_fail_ptr("ESLevent_nextHeader",1,SWIGTYPE_p_ESLevent); } result = (char *)(arg1)->nextHeader(); - SWIG_arg=0; - lua_pushstring(L,(const char*)result); SWIG_arg++; + lua_pushstring(L,(const char *)result); SWIG_arg++; return SWIG_arg; if(0) SWIG_fail; @@ -2231,24 +2354,23 @@ static const char *swig_ESLevent_base_names[] = {0}; static swig_lua_class _wrap_class_ESLevent = { "ESLevent", &SWIGTYPE_p_ESLevent,_wrap_new_ESLevent, swig_delete_ESLevent, swig_ESLevent_methods, swig_ESLevent_attributes, swig_ESLevent_bases, swig_ESLevent_base_names }; static int _wrap_new_ESLconnection__SWIG_0(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; char *arg1 = (char *) 0 ; int arg2 ; char *arg3 = (char *) 0 ; char *arg4 = (char *) 0 ; ESLconnection *result = 0 ; - SWIG_check_num_args("ESLconnection",4,4) - if(!lua_isstring(L,1)) SWIG_fail_arg("ESLconnection",1,"char const *"); - if(!lua_isnumber(L,2)) SWIG_fail_arg("ESLconnection",2,"int const"); - if(!lua_isstring(L,3)) SWIG_fail_arg("ESLconnection",3,"char const *"); - if(!lua_isstring(L,4)) SWIG_fail_arg("ESLconnection",4,"char const *"); + SWIG_check_num_args("ESLconnection::ESLconnection",4,4) + if(!SWIG_lua_isnilstring(L,1)) SWIG_fail_arg("ESLconnection::ESLconnection",1,"char const *"); + if(!lua_isnumber(L,2)) SWIG_fail_arg("ESLconnection::ESLconnection",2,"int const"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::ESLconnection",3,"char const *"); + if(!SWIG_lua_isnilstring(L,4)) SWIG_fail_arg("ESLconnection::ESLconnection",4,"char const *"); arg1 = (char *)lua_tostring(L, 1); arg2 = (int const)lua_tonumber(L, 2); arg3 = (char *)lua_tostring(L, 3); arg4 = (char *)lua_tostring(L, 4); result = (ESLconnection *)new ESLconnection((char const *)arg1,arg2,(char const *)arg3,(char const *)arg4); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLconnection,1); SWIG_arg++; return SWIG_arg; @@ -2261,21 +2383,20 @@ fail: static int _wrap_new_ESLconnection__SWIG_1(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; char *arg1 = (char *) 0 ; int arg2 ; char *arg3 = (char *) 0 ; ESLconnection *result = 0 ; - SWIG_check_num_args("ESLconnection",3,3) - if(!lua_isstring(L,1)) SWIG_fail_arg("ESLconnection",1,"char const *"); - if(!lua_isnumber(L,2)) SWIG_fail_arg("ESLconnection",2,"int const"); - if(!lua_isstring(L,3)) SWIG_fail_arg("ESLconnection",3,"char const *"); + SWIG_check_num_args("ESLconnection::ESLconnection",3,3) + if(!SWIG_lua_isnilstring(L,1)) SWIG_fail_arg("ESLconnection::ESLconnection",1,"char const *"); + if(!lua_isnumber(L,2)) SWIG_fail_arg("ESLconnection::ESLconnection",2,"int const"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::ESLconnection",3,"char const *"); arg1 = (char *)lua_tostring(L, 1); arg2 = (int const)lua_tonumber(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (ESLconnection *)new ESLconnection((char const *)arg1,arg2,(char const *)arg3); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLconnection,1); SWIG_arg++; return SWIG_arg; @@ -2288,24 +2409,23 @@ fail: static int _wrap_new_ESLconnection__SWIG_2(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; char *arg4 = (char *) 0 ; ESLconnection *result = 0 ; - SWIG_check_num_args("ESLconnection",4,4) - if(!lua_isstring(L,1)) SWIG_fail_arg("ESLconnection",1,"char const *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("ESLconnection",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("ESLconnection",3,"char const *"); - if(!lua_isstring(L,4)) SWIG_fail_arg("ESLconnection",4,"char const *"); + SWIG_check_num_args("ESLconnection::ESLconnection",4,4) + if(!SWIG_lua_isnilstring(L,1)) SWIG_fail_arg("ESLconnection::ESLconnection",1,"char const *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::ESLconnection",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::ESLconnection",3,"char const *"); + if(!SWIG_lua_isnilstring(L,4)) SWIG_fail_arg("ESLconnection::ESLconnection",4,"char const *"); arg1 = (char *)lua_tostring(L, 1); arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); arg4 = (char *)lua_tostring(L, 4); result = (ESLconnection *)new ESLconnection((char const *)arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLconnection,1); SWIG_arg++; return SWIG_arg; @@ -2318,21 +2438,20 @@ fail: static int _wrap_new_ESLconnection__SWIG_3(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; char *arg1 = (char *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; ESLconnection *result = 0 ; - SWIG_check_num_args("ESLconnection",3,3) - if(!lua_isstring(L,1)) SWIG_fail_arg("ESLconnection",1,"char const *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("ESLconnection",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("ESLconnection",3,"char const *"); + SWIG_check_num_args("ESLconnection::ESLconnection",3,3) + if(!SWIG_lua_isnilstring(L,1)) SWIG_fail_arg("ESLconnection::ESLconnection",1,"char const *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::ESLconnection",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::ESLconnection",3,"char const *"); arg1 = (char *)lua_tostring(L, 1); arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (ESLconnection *)new ESLconnection((char const *)arg1,(char const *)arg2,(char const *)arg3); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLconnection,1); SWIG_arg++; return SWIG_arg; @@ -2345,15 +2464,14 @@ fail: static int _wrap_new_ESLconnection__SWIG_4(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; int arg1 ; ESLconnection *result = 0 ; - SWIG_check_num_args("ESLconnection",1,1) - if(!lua_isnumber(L,1)) SWIG_fail_arg("ESLconnection",1,"int"); + SWIG_check_num_args("ESLconnection::ESLconnection",1,1) + if(!lua_isnumber(L,1)) SWIG_fail_arg("ESLconnection::ESLconnection",1,"int"); arg1 = (int)lua_tonumber(L, 1); result = (ESLconnection *)new ESLconnection(arg1); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLconnection,1); SWIG_arg++; return SWIG_arg; @@ -2384,7 +2502,7 @@ static int _wrap_new_ESLconnection(lua_State* L) { if (argc == 3) { int _v; { - _v = lua_isstring(L,argv[0]); + _v = SWIG_lua_isnilstring(L,argv[0]); } if (_v) { { @@ -2392,7 +2510,7 @@ static int _wrap_new_ESLconnection(lua_State* L) { } if (_v) { { - _v = lua_isstring(L,argv[2]); + _v = SWIG_lua_isnilstring(L,argv[2]); } if (_v) { return _wrap_new_ESLconnection__SWIG_1(L); @@ -2403,15 +2521,15 @@ static int _wrap_new_ESLconnection(lua_State* L) { if (argc == 3) { int _v; { - _v = lua_isstring(L,argv[0]); + _v = SWIG_lua_isnilstring(L,argv[0]); } if (_v) { { - _v = lua_isstring(L,argv[1]); + _v = SWIG_lua_isnilstring(L,argv[1]); } if (_v) { { - _v = lua_isstring(L,argv[2]); + _v = SWIG_lua_isnilstring(L,argv[2]); } if (_v) { return _wrap_new_ESLconnection__SWIG_3(L); @@ -2422,7 +2540,7 @@ static int _wrap_new_ESLconnection(lua_State* L) { if (argc == 4) { int _v; { - _v = lua_isstring(L,argv[0]); + _v = SWIG_lua_isnilstring(L,argv[0]); } if (_v) { { @@ -2430,11 +2548,11 @@ static int _wrap_new_ESLconnection(lua_State* L) { } if (_v) { { - _v = lua_isstring(L,argv[2]); + _v = SWIG_lua_isnilstring(L,argv[2]); } if (_v) { { - _v = lua_isstring(L,argv[3]); + _v = SWIG_lua_isnilstring(L,argv[3]); } if (_v) { return _wrap_new_ESLconnection__SWIG_0(L); @@ -2446,19 +2564,19 @@ static int _wrap_new_ESLconnection(lua_State* L) { if (argc == 4) { int _v; { - _v = lua_isstring(L,argv[0]); + _v = SWIG_lua_isnilstring(L,argv[0]); } if (_v) { { - _v = lua_isstring(L,argv[1]); + _v = SWIG_lua_isnilstring(L,argv[1]); } if (_v) { { - _v = lua_isstring(L,argv[2]); + _v = SWIG_lua_isnilstring(L,argv[2]); } if (_v) { { - _v = lua_isstring(L,argv[3]); + _v = SWIG_lua_isnilstring(L,argv[3]); } if (_v) { return _wrap_new_ESLconnection__SWIG_2(L); @@ -2468,50 +2586,30 @@ static int _wrap_new_ESLconnection(lua_State* L) { } } - lua_pushstring(L,"No matching function for overloaded 'new_ESLconnection'"); + lua_pushstring(L,"Wrong arguments for overloaded function 'new_ESLconnection'\n" + " Possible C/C++ prototypes are:\n" + " ESLconnection::ESLconnection(char const *,int const,char const *,char const *)\n" + " ESLconnection::ESLconnection(char const *,int const,char const *)\n" + " ESLconnection::ESLconnection(char const *,char const *,char const *,char const *)\n" + " ESLconnection::ESLconnection(char const *,char const *,char const *)\n" + " ESLconnection::ESLconnection(int)\n"); lua_error(L);return 0; } -static int _wrap_delete_ESLconnection(lua_State* L) { - int SWIG_arg = -1; - ESLconnection *arg1 = (ESLconnection *) 0 ; - - SWIG_check_num_args("ESLconnection",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection",1,"ESLconnection *"); - - if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,SWIG_POINTER_DISOWN))){ - SWIG_fail_ptr("delete_ESLconnection",1,SWIGTYPE_p_ESLconnection); - } - - delete arg1; - - SWIG_arg=0; - - return SWIG_arg; - - if(0) SWIG_fail; - -fail: - lua_error(L); - return SWIG_arg; -} - - static int _wrap_ESLconnection_socketDescriptor(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; int result; - SWIG_check_num_args("socketDescriptor",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("socketDescriptor",1,"ESLconnection *"); + SWIG_check_num_args("ESLconnection::socketDescriptor",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::socketDescriptor",1,"ESLconnection *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_socketDescriptor",1,SWIGTYPE_p_ESLconnection); } result = (int)(arg1)->socketDescriptor(); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -2524,19 +2622,18 @@ fail: static int _wrap_ESLconnection_connected(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; int result; - SWIG_check_num_args("connected",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("connected",1,"ESLconnection *"); + SWIG_check_num_args("ESLconnection::connected",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::connected",1,"ESLconnection *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_connected",1,SWIGTYPE_p_ESLconnection); } result = (int)(arg1)->connected(); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -2549,19 +2646,18 @@ fail: static int _wrap_ESLconnection_getInfo(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("getInfo",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("getInfo",1,"ESLconnection *"); + SWIG_check_num_args("ESLconnection::getInfo",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::getInfo",1,"ESLconnection *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_getInfo",1,SWIGTYPE_p_ESLconnection); } result = (ESLevent *)(arg1)->getInfo(); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2574,14 +2670,14 @@ fail: static int _wrap_ESLconnection_send(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; int result; - SWIG_check_num_args("send",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("send",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("send",2,"char const *"); + SWIG_check_num_args("ESLconnection::send",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::send",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::send",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_send",1,SWIGTYPE_p_ESLconnection); @@ -2589,7 +2685,6 @@ static int _wrap_ESLconnection_send(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); result = (int)(arg1)->send((char const *)arg2); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -2602,14 +2697,14 @@ fail: static int _wrap_ESLconnection_sendRecv(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("sendRecv",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("sendRecv",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("sendRecv",2,"char const *"); + SWIG_check_num_args("ESLconnection::sendRecv",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::sendRecv",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::sendRecv",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_sendRecv",1,SWIGTYPE_p_ESLconnection); @@ -2617,7 +2712,6 @@ static int _wrap_ESLconnection_sendRecv(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); result = (ESLevent *)(arg1)->sendRecv((char const *)arg2); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2630,16 +2724,16 @@ fail: static int _wrap_ESLconnection_api(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) NULL ; ESLevent *result = 0 ; - SWIG_check_num_args("api",2,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("api",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("api",2,"char const *"); - if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("api",3,"char const *"); + SWIG_check_num_args("ESLconnection::api",2,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::api",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::api",2,"char const *"); + if(lua_gettop(L)>=3 && !SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::api",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_api",1,SWIGTYPE_p_ESLconnection); @@ -2650,7 +2744,6 @@ static int _wrap_ESLconnection_api(lua_State* L) { arg3 = (char *)lua_tostring(L, 3); } result = (ESLevent *)(arg1)->api((char const *)arg2,(char const *)arg3); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2663,18 +2756,18 @@ fail: static int _wrap_ESLconnection_bgapi(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) NULL ; char *arg4 = (char *) NULL ; ESLevent *result = 0 ; - SWIG_check_num_args("bgapi",2,4) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("bgapi",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("bgapi",2,"char const *"); - if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("bgapi",3,"char const *"); - if(lua_gettop(L)>=4 && !lua_isstring(L,4)) SWIG_fail_arg("bgapi",4,"char const *"); + SWIG_check_num_args("ESLconnection::bgapi",2,4) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::bgapi",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::bgapi",2,"char const *"); + if(lua_gettop(L)>=3 && !SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::bgapi",3,"char const *"); + if(lua_gettop(L)>=4 && !SWIG_lua_isnilstring(L,4)) SWIG_fail_arg("ESLconnection::bgapi",4,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_bgapi",1,SWIGTYPE_p_ESLconnection); @@ -2688,7 +2781,6 @@ static int _wrap_ESLconnection_bgapi(lua_State* L) { arg4 = (char *)lua_tostring(L, 4); } result = (ESLevent *)(arg1)->bgapi((char const *)arg2,(char const *)arg3,(char const *)arg4); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2701,14 +2793,14 @@ fail: static int _wrap_ESLconnection_sendEvent(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; ESLevent *arg2 = (ESLevent *) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("sendEvent",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("sendEvent",1,"ESLconnection *"); - if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("sendEvent",2,"ESLevent *"); + SWIG_check_num_args("ESLconnection::sendEvent",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::sendEvent",1,"ESLconnection *"); + if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("ESLconnection::sendEvent",2,"ESLevent *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_sendEvent",1,SWIGTYPE_p_ESLconnection); @@ -2720,7 +2812,6 @@ static int _wrap_ESLconnection_sendEvent(lua_State* L) { } result = (ESLevent *)(arg1)->sendEvent(arg2); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2733,16 +2824,16 @@ fail: static int _wrap_ESLconnection_sendMSG(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; ESLevent *arg2 = (ESLevent *) 0 ; char *arg3 = (char *) NULL ; int result; - SWIG_check_num_args("sendMSG",2,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("sendMSG",1,"ESLconnection *"); - if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("sendMSG",2,"ESLevent *"); - if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("sendMSG",3,"char const *"); + SWIG_check_num_args("ESLconnection::sendMSG",2,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::sendMSG",1,"ESLconnection *"); + if(!SWIG_isptrtype(L,2)) SWIG_fail_arg("ESLconnection::sendMSG",2,"ESLevent *"); + if(lua_gettop(L)>=3 && !SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::sendMSG",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_sendMSG",1,SWIGTYPE_p_ESLconnection); @@ -2757,7 +2848,6 @@ static int _wrap_ESLconnection_sendMSG(lua_State* L) { arg3 = (char *)lua_tostring(L, 3); } result = (int)(arg1)->sendMSG(arg2,(char const *)arg3); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -2770,19 +2860,18 @@ fail: static int _wrap_ESLconnection_recvEvent(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("recvEvent",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("recvEvent",1,"ESLconnection *"); + SWIG_check_num_args("ESLconnection::recvEvent",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::recvEvent",1,"ESLconnection *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_recvEvent",1,SWIGTYPE_p_ESLconnection); } result = (ESLevent *)(arg1)->recvEvent(); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2795,14 +2884,14 @@ fail: static int _wrap_ESLconnection_recvEventTimed(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; int arg2 ; ESLevent *result = 0 ; - SWIG_check_num_args("recvEventTimed",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("recvEventTimed",1,"ESLconnection *"); - if(!lua_isnumber(L,2)) SWIG_fail_arg("recvEventTimed",2,"int"); + SWIG_check_num_args("ESLconnection::recvEventTimed",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::recvEventTimed",1,"ESLconnection *"); + if(!lua_isnumber(L,2)) SWIG_fail_arg("ESLconnection::recvEventTimed",2,"int"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_recvEventTimed",1,SWIGTYPE_p_ESLconnection); @@ -2810,7 +2899,6 @@ static int _wrap_ESLconnection_recvEventTimed(lua_State* L) { arg2 = (int)lua_tonumber(L, 2); result = (ESLevent *)(arg1)->recvEventTimed(arg2); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2823,16 +2911,16 @@ fail: static int _wrap_ESLconnection_filter(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; ESLevent *result = 0 ; - SWIG_check_num_args("filter",3,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("filter",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("filter",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("filter",3,"char const *"); + SWIG_check_num_args("ESLconnection::filter",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::filter",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::filter",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::filter",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_filter",1,SWIGTYPE_p_ESLconnection); @@ -2841,7 +2929,6 @@ static int _wrap_ESLconnection_filter(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (ESLevent *)(arg1)->filter((char const *)arg2,(char const *)arg3); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2854,16 +2941,16 @@ fail: static int _wrap_ESLconnection_events(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; int result; - SWIG_check_num_args("events",3,3) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("events",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("events",2,"char const *"); - if(!lua_isstring(L,3)) SWIG_fail_arg("events",3,"char const *"); + SWIG_check_num_args("ESLconnection::events",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::events",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::events",2,"char const *"); + if(!SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::events",3,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_events",1,SWIGTYPE_p_ESLconnection); @@ -2872,7 +2959,6 @@ static int _wrap_ESLconnection_events(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); arg3 = (char *)lua_tostring(L, 3); result = (int)(arg1)->events((char const *)arg2,(char const *)arg3); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -2885,18 +2971,18 @@ fail: static int _wrap_ESLconnection_execute(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) NULL ; char *arg4 = (char *) NULL ; ESLevent *result = 0 ; - SWIG_check_num_args("execute",2,4) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("execute",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("execute",2,"char const *"); - if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("execute",3,"char const *"); - if(lua_gettop(L)>=4 && !lua_isstring(L,4)) SWIG_fail_arg("execute",4,"char const *"); + SWIG_check_num_args("ESLconnection::execute",2,4) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::execute",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::execute",2,"char const *"); + if(lua_gettop(L)>=3 && !SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::execute",3,"char const *"); + if(lua_gettop(L)>=4 && !SWIG_lua_isnilstring(L,4)) SWIG_fail_arg("ESLconnection::execute",4,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_execute",1,SWIGTYPE_p_ESLconnection); @@ -2910,7 +2996,6 @@ static int _wrap_ESLconnection_execute(lua_State* L) { arg4 = (char *)lua_tostring(L, 4); } result = (ESLevent *)(arg1)->execute((char const *)arg2,(char const *)arg3,(char const *)arg4); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2923,18 +3008,18 @@ fail: static int _wrap_ESLconnection_executeAsync(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) NULL ; char *arg4 = (char *) NULL ; ESLevent *result = 0 ; - SWIG_check_num_args("executeAsync",2,4) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("executeAsync",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("executeAsync",2,"char const *"); - if(lua_gettop(L)>=3 && !lua_isstring(L,3)) SWIG_fail_arg("executeAsync",3,"char const *"); - if(lua_gettop(L)>=4 && !lua_isstring(L,4)) SWIG_fail_arg("executeAsync",4,"char const *"); + SWIG_check_num_args("ESLconnection::executeAsync",2,4) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::executeAsync",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::executeAsync",2,"char const *"); + if(lua_gettop(L)>=3 && !SWIG_lua_isnilstring(L,3)) SWIG_fail_arg("ESLconnection::executeAsync",3,"char const *"); + if(lua_gettop(L)>=4 && !SWIG_lua_isnilstring(L,4)) SWIG_fail_arg("ESLconnection::executeAsync",4,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_executeAsync",1,SWIGTYPE_p_ESLconnection); @@ -2948,7 +3033,6 @@ static int _wrap_ESLconnection_executeAsync(lua_State* L) { arg4 = (char *)lua_tostring(L, 4); } result = (ESLevent *)(arg1)->executeAsync((char const *)arg2,(char const *)arg3,(char const *)arg4); - SWIG_arg=0; SWIG_NewPointerObj(L,result,SWIGTYPE_p_ESLevent,1); SWIG_arg++; return SWIG_arg; @@ -2961,14 +3045,14 @@ fail: static int _wrap_ESLconnection_setAsyncExecute(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; int result; - SWIG_check_num_args("setAsyncExecute",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("setAsyncExecute",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("setAsyncExecute",2,"char const *"); + SWIG_check_num_args("ESLconnection::setAsyncExecute",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::setAsyncExecute",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::setAsyncExecute",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_setAsyncExecute",1,SWIGTYPE_p_ESLconnection); @@ -2976,7 +3060,6 @@ static int _wrap_ESLconnection_setAsyncExecute(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); result = (int)(arg1)->setAsyncExecute((char const *)arg2); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -2989,14 +3072,14 @@ fail: static int _wrap_ESLconnection_setEventLock(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; char *arg2 = (char *) 0 ; int result; - SWIG_check_num_args("setEventLock",2,2) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("setEventLock",1,"ESLconnection *"); - if(!lua_isstring(L,2)) SWIG_fail_arg("setEventLock",2,"char const *"); + SWIG_check_num_args("ESLconnection::setEventLock",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::setEventLock",1,"ESLconnection *"); + if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("ESLconnection::setEventLock",2,"char const *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_setEventLock",1,SWIGTYPE_p_ESLconnection); @@ -3004,7 +3087,6 @@ static int _wrap_ESLconnection_setEventLock(lua_State* L) { arg2 = (char *)lua_tostring(L, 2); result = (int)(arg1)->setEventLock((char const *)arg2); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -3017,19 +3099,18 @@ fail: static int _wrap_ESLconnection_disconnect(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; ESLconnection *arg1 = (ESLconnection *) 0 ; int result; - SWIG_check_num_args("disconnect",1,1) - if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("disconnect",1,"ESLconnection *"); + SWIG_check_num_args("ESLconnection::disconnect",1,1) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("ESLconnection::disconnect",1,"ESLconnection *"); if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_ESLconnection,0))){ SWIG_fail_ptr("ESLconnection_disconnect",1,SWIGTYPE_p_ESLconnection); } result = (int)(arg1)->disconnect(); - SWIG_arg=0; lua_pushnumber(L, (lua_Number) result); SWIG_arg++; return SWIG_arg; @@ -3074,14 +3155,13 @@ static const char *swig_ESLconnection_base_names[] = {0}; static swig_lua_class _wrap_class_ESLconnection = { "ESLconnection", &SWIGTYPE_p_ESLconnection,_wrap_new_ESLconnection, swig_delete_ESLconnection, swig_ESLconnection_methods, swig_ESLconnection_attributes, swig_ESLconnection_bases, swig_ESLconnection_base_names }; static int _wrap_eslSetLogLevel(lua_State* L) { - int SWIG_arg = -1; + int SWIG_arg = 0; int arg1 ; SWIG_check_num_args("eslSetLogLevel",1,1) if(!lua_isnumber(L,1)) SWIG_fail_arg("eslSetLogLevel",1,"int"); arg1 = (int)lua_tonumber(L, 1); eslSetLogLevel(arg1); - SWIG_arg=0; return SWIG_arg; @@ -3097,7 +3177,7 @@ fail: } #endif -static const struct luaL_reg swig_commands[] = { +static const struct luaL_Reg swig_commands[] = { { "eslSetLogLevel", _wrap_eslSetLogLevel}, {0,0} }; @@ -3386,16 +3466,24 @@ extern "C" { #endif /* this is the initialization function added at the very end of the code - the function is always called SWIG_init, but an eariler #define will rename it + the function is always called SWIG_init, but an earlier #define will rename it */ -SWIGEXPORT int SWIG_init(lua_State* L) +#if ((SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)) +LUALIB_API int SWIG_init(lua_State* L) +#else +SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */ +#endif { +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) /* valid for both Lua and eLua */ int i; /* start with global table */ - lua_pushvalue(L,LUA_GLOBALSINDEX); + lua_pushglobaltable (L); /* SWIG's internal initalisation */ SWIG_InitializeModule((void*)L); SWIG_PropagateClientData(); +#endif + +#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) /* add a global fn */ SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type); SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal); @@ -3409,7 +3497,10 @@ SWIGEXPORT int SWIG_init(lua_State* L) for (i = 0; swig_variables[i].name; i++){ SWIG_Lua_module_add_variable(L,swig_variables[i].name,swig_variables[i].get,swig_variables[i].set); } - /* set up base class pointers (the hierachy) */ +#endif + +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) + /* set up base class pointers (the hierarchy) */ for (i = 0; swig_types[i]; i++){ if (swig_types[i]->clientdata){ SWIG_Lua_init_base_class(L,(swig_lua_class*)(swig_types[i]->clientdata)); @@ -3421,14 +3512,24 @@ SWIGEXPORT int SWIG_init(lua_State* L) SWIG_Lua_class_register(L,(swig_lua_class*)(swig_types[i]->clientdata)); } } +#endif + +#if ((SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUA) && (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC)) /* constants */ SWIG_Lua_InstallConstants(L,swig_constants); +#endif + +#if (SWIG_LUA_TARGET != SWIG_LUA_FLAVOR_ELUAC) /* invoke user-specific initialization */ SWIG_init_user(L); /* end module */ - lua_pop(L,1); /* tidy stack (remove module table)*/ - lua_pop(L,1); /* tidy stack (remove global table)*/ + /* Note: We do not clean up the stack here (Lua will do this for us). At this + point, we have the globals table and out module table on the stack. Returning + one value makes the module table the result of the require command. */ return 1; +#else + return 0; +#endif } #ifdef __cplusplus From 861961bd4daf0666285659fc1f14d29e22c23b88 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Jan 2015 13:18:12 -0600 Subject: [PATCH 56/72] FS-7180: when using system lua, properly link against reanmed library versions on debian for mod_lua --- configure.ac | 12 ++++++++++++ src/mod/languages/mod_lua/Makefile.am | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 0c30551993..b483f8f8e7 100644 --- a/configure.ac +++ b/configure.ac @@ -518,6 +518,18 @@ AC_SUBST(SYS_XMLRPC_LDFLAGS) AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"]) AC_ARG_ENABLE([system-lua],[AS_HELP_STRING([--enable-system-lua],[use system lib for lua])],,[enable_system_lua="no"]) +if test "${enable_system_lua}" = "yes" ; then + PKG_CHECK_MODULES([LUA],[lua5.2],[have_lua=yes],[have_lua=no]) + if test "${have_lua}" = "no" ; then + PKG_CHECK_MODULES([LUA],[lua5.1],[have_lua=yes],[have_lua=no]) + fi + if test "${have_lua}" = "no" ; then + PKG_CHECK_MODULES([LUA],[lua],[have_lua=yes],[have_lua=no]) + fi + if test x"${LUA_LIBS}" = x"" ; then + LUA_LIBS="-llua" + fi +fi AM_CONDITIONAL([SYSTEM_LUA],[test "${enable_system_lua}" = "yes"]) AC_ARG_ENABLE(srtp, diff --git a/src/mod/languages/mod_lua/Makefile.am b/src/mod/languages/mod_lua/Makefile.am index 18001c2a23..717f4f6fad 100644 --- a/src/mod/languages/mod_lua/Makefile.am +++ b/src/mod/languages/mod_lua/Makefile.am @@ -8,8 +8,8 @@ mod_LTLIBRARIES = mod_lua.la mod_lua_la_SOURCES = mod_lua.cpp freeswitch_lua.cpp mod_lua_wrap.cpp if SYSTEM_LUA -mod_lua_la_CXXFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -mod_lua_la_CFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) +mod_lua_la_CXXFLAGS = $(AM_CPPFLAGS) $(LUA_CFLAGS) $(CPPFLAGS) +mod_lua_la_CFLAGS = $(AM_CPPFLAGS) $(LUA_CFLAGS) $(CPPFLAGS) else mod_lua_la_SOURCES += lua/lapi.c lua/lcode.c lua/lctype.c lua/ldebug.c lua/ldo.c lua/ldump.c lua/lfunc.c lua/lgc.c lua/llex.c lua/lmem.c lua/lobject.c lua/lopcodes.c lua/lparser.c lua/lstate.c lua/lstring.c lua/ltable.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c lua/lauxlib.c lua/lbaselib.c lua/lbitlib.c lua/lcorolib.c lua/ldblib.c lua/liolib.c lua/lmathlib.c lua/loslib.c lua/lstrlib.c lua/ltablib.c lua/loadlib.c lua/linit.c LUA_DIR=$(switch_srcdir)/src/mod/languages/mod_lua/lua @@ -21,7 +21,7 @@ mod_lua_la_LIBADD = $(switch_builddir)/libfreeswitch.la mod_lua_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm $(AM_LDFLAGS) $(SOLINK) if SYSTEM_LUA -mod_lua_la_LDFLAGS += -llua +mod_lua_la_LDFLAGS += $(LUA_LIBS) endif reswig: swigclean lua_wrap From c36196db3f5e7c4dd4c7b5af3fec5654e5860c22 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 20 Jan 2015 14:32:36 -0500 Subject: [PATCH 57/72] FS-7180: when using system lua, properly link against renamed library versions on debian for esl luamod --- libs/esl/Makefile.am | 2 +- libs/esl/lua/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/esl/Makefile.am b/libs/esl/Makefile.am index 3b1563eaed..b59c7f24f1 100644 --- a/libs/esl/Makefile.am +++ b/libs/esl/Makefile.am @@ -74,7 +74,7 @@ phpmod: $(MYLIB) $(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C php luamod: $(MYLIB) - $(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C lua + $(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" LUA_CFLAGS="$(LUA_CFLAGS)" LUA_LIBS="$(LUA_LIBS)" -C lua pymod: $(MYLIB) $(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python diff --git a/libs/esl/lua/Makefile b/libs/esl/lua/Makefile index 872888dff5..24b6fbd18e 100644 --- a/libs/esl/lua/Makefile +++ b/libs/esl/lua/Makefile @@ -1,5 +1,5 @@ LOCAL_CFLAGS= -LOCAL_LDFLAGS=-llua -lpthread +LOCAL_LDFLAGS=$(LUA_LIBS) -lpthread WRAP_GCC_WARNING_SILENCE=-Wno-unused-function all: ESL.so @@ -8,7 +8,7 @@ esl_wrap.cpp: swig2.0 -module ESL -lua -c++ -DMULTIPLICITY -I../src/include -o esl_wrap.cpp ../ESL.i esl_wrap.o: esl_wrap.cpp - $(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(LOCAL_CFLAGS) $(WRAP_GCC_WARNING_SILENCE) -c esl_wrap.cpp -o esl_wrap.o + $(CXX) $(CXX_CFLAGS) $(LUA_CFLAGS) $(CXXFLAGS) $(LOCAL_CFLAGS) $(WRAP_GCC_WARNING_SILENCE) -c esl_wrap.cpp -o esl_wrap.o ESL.so: esl_wrap.o $(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(LOCAL_LDFLAGS) -o ESL.so -L. $(LIBS) From 8fc19a60374867b3fd18cf1f2193bf82002fda11 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Tue, 20 Jan 2015 14:37:43 -0500 Subject: [PATCH 58/72] FS-7180: properly build esl luamod when not using the --enable-system-lua configure arg --- configure.ac | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index b483f8f8e7..2e61464d58 100644 --- a/configure.ac +++ b/configure.ac @@ -518,17 +518,15 @@ AC_SUBST(SYS_XMLRPC_LDFLAGS) AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"]) AC_ARG_ENABLE([system-lua],[AS_HELP_STRING([--enable-system-lua],[use system lib for lua])],,[enable_system_lua="no"]) -if test "${enable_system_lua}" = "yes" ; then - PKG_CHECK_MODULES([LUA],[lua5.2],[have_lua=yes],[have_lua=no]) - if test "${have_lua}" = "no" ; then - PKG_CHECK_MODULES([LUA],[lua5.1],[have_lua=yes],[have_lua=no]) - fi - if test "${have_lua}" = "no" ; then - PKG_CHECK_MODULES([LUA],[lua],[have_lua=yes],[have_lua=no]) - fi - if test x"${LUA_LIBS}" = x"" ; then - LUA_LIBS="-llua" - fi +PKG_CHECK_MODULES([LUA],[lua5.2],[have_lua=yes],[have_lua=no]) +if test "${have_lua}" = "no" ; then + PKG_CHECK_MODULES([LUA],[lua5.1],[have_lua=yes],[have_lua=no]) +fi +if test "${have_lua}" = "no" ; then + PKG_CHECK_MODULES([LUA],[lua],[have_lua=yes],[have_lua=no]) +fi +if test x"${LUA_LIBS}" = x"" ; then + LUA_LIBS="-llua" fi AM_CONDITIONAL([SYSTEM_LUA],[test "${enable_system_lua}" = "yes"]) From b74448462d731186ea5d41b9d056fcfb1da4bcb6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Jan 2015 13:56:00 -0600 Subject: [PATCH 59/72] FS-7173 #resolve #comment please verify fix in master --- src/include/private/switch_core_pvt.h | 2 -- src/switch_core_media_bug.c | 31 ++++++++++----------------- src/switch_ivr_async.c | 23 +++++++++++--------- 3 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index d7933b4880..5411d26332 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -174,8 +174,6 @@ struct switch_core_session { uint32_t soft_lock; switch_ivr_dmachine_t *dmachine[2]; plc_state_t *plc; - uint8_t recur_buffer[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_size_t recur_buffer_len; switch_media_handle_t *media_handle; uint32_t decoder_errors; diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index 6dffffe06b..3718dfb3a4 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -372,7 +372,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(switch_media_bug_t *b } frame->datalen = (uint32_t)bytes; - frame->samples = (uint32_t)(bytes / sizeof(int16_t)); + frame->samples = (uint32_t)(bytes / sizeof(int16_t) / read_impl.number_of_channels); frame->rate = read_impl.actual_samples_per_second; frame->codec = NULL; @@ -380,22 +380,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_read(switch_media_bug_t *b frame->datalen *= 2; frame->channels = 2; } else { - frame->channels = 1; - } - - memcpy(bug->session->recur_buffer, frame->data, frame->datalen); - bug->session->recur_buffer_len = frame->datalen; - - if (has_read) { - switch_mutex_lock(bug->read_mutex); - do_read = switch_buffer_inuse(bug->raw_read_buffer); - switch_mutex_unlock(bug->read_mutex); - } - - if (has_write) { - switch_mutex_lock(bug->write_mutex); - do_write = switch_buffer_inuse(bug->raw_write_buffer); - switch_mutex_unlock(bug->write_mutex); + frame->channels = read_impl.number_of_channels; } return SWITCH_STATUS_SUCCESS; @@ -589,11 +574,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch if (orig_session->bugs) { switch_channel_t *new_channel = switch_core_session_get_channel(new_session); - const char *save = switch_channel_get_variable(new_channel, "record_append"); - + switch_channel_t *orig_channel = switch_core_session_get_channel(orig_session); + const char *save_append = switch_channel_get_variable(new_channel, "record_append"); + const char *save_stereo = switch_channel_get_variable(new_channel, "record_stereo"); + const char *orig_stereo = switch_channel_get_variable(orig_channel, "record_stereo"); + const char *new_stereo = orig_stereo; + switch_thread_rwlock_wrlock(orig_session->bug_rwlock); switch_channel_set_variable(new_channel, "record_append", "true"); + switch_channel_set_variable(new_channel, "record_stereo", new_stereo); for (bp = orig_session->bugs; bp; bp = bp->next) { if (!strcmp(bp->function, "session_record")) { @@ -614,7 +604,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch switch_ivr_record_session(new_session, list[i], stop_times[i], NULL); } - switch_channel_set_variable(new_channel, "record_append", save); + switch_channel_set_variable(new_channel, "record_append", save_append); + switch_channel_set_variable(new_channel, "record_stereo", save_stereo); } diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 204b8fbe5c..792dba257b 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1122,7 +1122,7 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void * struct record_helper *rh; switch_size_t bsize = SWITCH_RECOMMENDED_BUFFER_SIZE, samples = 0, inuse = 0; unsigned char *data = switch_core_session_alloc(session, bsize); - int channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : 1; + int channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : rh->read_impl.number_of_channels; if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { return NULL; @@ -2125,16 +2125,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t flags |= SMBF_READ_STREAM; } - if ((p = switch_channel_get_variable(channel, "RECORD_STEREO")) && switch_true(p)) { - flags |= SMBF_STEREO; - flags &= ~SMBF_STEREO_SWAP; - channels = 2; - } + if (channels == 1) { /* if leg is already stereo this feature is not available */ + if ((p = switch_channel_get_variable(channel, "RECORD_STEREO")) && switch_true(p)) { + flags |= SMBF_STEREO; + flags &= ~SMBF_STEREO_SWAP; + channels = 2; + } - if ((p = switch_channel_get_variable(channel, "RECORD_STEREO_SWAP")) && switch_true(p)) { - flags |= SMBF_STEREO; - flags |= SMBF_STEREO_SWAP; - channels = 2; + if ((p = switch_channel_get_variable(channel, "RECORD_STEREO_SWAP")) && switch_true(p)) { + flags |= SMBF_STEREO; + flags |= SMBF_STEREO_SWAP; + channels = 2; + } } if ((p = switch_channel_get_variable(channel, "RECORD_ANSWER_REQ")) && switch_true(p)) { @@ -2230,6 +2232,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t if ((ext = strrchr(file, '.'))) { ext++; + if (switch_core_file_open(fh, file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file); if (hangup_on_error) { From 95a8efb174bfa580617af8eac1da551c1d6590d1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Jan 2015 20:21:18 -0500 Subject: [PATCH 60/72] up the ice failover val to 3 sec --- src/switch_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index e4850bd135..0761948c5a 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1128,7 +1128,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d if (switch_cmp_addr(from_addr, ice->addr)) { ice->last_ok = now; } else { - if (!ice->last_ok || (now - ice->last_ok) > 1000000) { + if (!ice->last_ok || (now - ice->last_ok) > 3000000) { hosts_set++; host = switch_get_addr(buf, sizeof(buf), from_addr); port = switch_sockaddr_get_port(from_addr); From 90ab1d16f57746392d7068ce137f76edd6da08ba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Jan 2015 02:01:54 -0600 Subject: [PATCH 61/72] fix cent5 build --- libs/srtp/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/srtp/Makefile.am b/libs/srtp/Makefile.am index 4e89d96f26..88be99b4e0 100644 --- a/libs/srtp/Makefile.am +++ b/libs/srtp/Makefile.am @@ -1,4 +1,4 @@ -AUTOMAKE_OPTIONS = gnu subdir-objects +AUTOMAKE_OPTIONS = gnu NAME=srtp AM_CFLAGS = $(new_AM_CFLAGS) -I./src -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include From 15a7ff25198a33cb11fb8e72b250a809ecc22dda Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Jan 2015 11:22:42 -0600 Subject: [PATCH 62/72] fix hash dump gdb function --- support-d/.gdbinit | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/support-d/.gdbinit b/support-d/.gdbinit index 329bc34777..eb94cc908b 100755 --- a/support-d/.gdbinit +++ b/support-d/.gdbinit @@ -29,14 +29,16 @@ define hash_it_str set $i = 0 set $idx = 0 set $len = $arg0->tablelength + printf "len: %d\n", $arg0->tablelength while($idx < $len) - set $x=$arg0->table->[$idx] + set $x = $arg0->table[$idx] while($x != 0x0) printf "key: %s valueptr: %p\n", $x->k, $x->v set $x = $x->next set $i = $i + 1 end + set $idx = $idx + 1 end end document hash_it_str From f770b318cfbf7bbc2304a9e209a3e99562bbe4db Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Jan 2015 11:24:01 -0600 Subject: [PATCH 63/72] FS-7106 #resolve --- src/mod/applications/mod_httapi/mod_httapi.c | 81 ++++++++++---------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/src/mod/applications/mod_httapi/mod_httapi.c b/src/mod/applications/mod_httapi/mod_httapi.c index 6a452b4ab4..b27790644b 100644 --- a/src/mod/applications/mod_httapi/mod_httapi.c +++ b/src/mod/applications/mod_httapi/mod_httapi.c @@ -195,6 +195,7 @@ struct http_file_context { } write; switch_mutex_t *mutex; + switch_thread_rwlock_t *rwlock; }; typedef struct http_file_context http_file_context_t; @@ -2418,24 +2419,31 @@ static size_t save_file_callback(void *ptr, size_t size, size_t nmemb, void *dat { register unsigned int realsize = (unsigned int) (size * nmemb); client_t *client = data; - int x; + int x, wrote = 0, sanity = 1000; + unsigned char *buffer = (unsigned char *) ptr; client->bytes += realsize; - - if (client->bytes > client->max_bytes) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Oversized file detected [%d bytes]\n", (int) client->bytes); client->err = 1; return 0; } - x = write(client->fd, ptr, realsize); + do { + x = write(client->fd, buffer + wrote, realsize - wrote); + if (x > 0) { + wrote += x; + } else { + switch_cond_next(); + } + } while (wrote != realsize && (x == -1 && (errno == EAGAIN || errno == EINTR)) && --sanity); - if (x != (int) realsize) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write! %d out of %d\n", x, realsize); + if (wrote != (int) realsize) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Short write! fd:%d %d out of %d [%s]\n", client->fd, wrote, realsize, strerror(errno)); } - return x; + + return wrote; } @@ -2449,7 +2457,7 @@ static switch_status_t fetch_cache_data(http_file_context_t *context, const char char *dup_creds = NULL, *dynamic_url = NULL, *use_url; char *ua = NULL; const char *profile_name = NULL; - + int tries = 10; if (context->url_params) { profile_name = switch_event_get_header(context->url_params, "profile_name"); @@ -2467,9 +2475,15 @@ static switch_status_t fetch_cache_data(http_file_context_t *context, const char return SWITCH_STATUS_FALSE; } + client->fd = -1; if (save_path) { - if ((client->fd = open(save_path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) < 0) { + while(--tries && (client->fd == 0 || client->fd == -1)) { + client->fd = open(save_path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); + } + + if (client->fd < 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "ERROR OPENING FILE %s [%s]\n", save_path, strerror(errno)); return SWITCH_STATUS_FALSE; } } @@ -2602,6 +2616,7 @@ static switch_status_t fetch_cache_data(http_file_context_t *context, const char if (client->fd > -1) { close(client->fd); + client->fd = -1; } if (headers && client->headers) { @@ -2701,36 +2716,28 @@ static switch_status_t write_meta_file(http_file_context_t *context, const char } -static switch_status_t lock_file(http_file_context_t *context, switch_bool_t lock) +static void lock_file(http_file_context_t *context, switch_bool_t lock) { - - switch_status_t status = SWITCH_STATUS_SUCCESS; - http_file_context_t *xcontext = NULL; + void *x = NULL; if (lock) { - switch_mutex_lock(globals.request_mutex); - if (!(xcontext = switch_core_hash_find(globals.request_hash, context->dest_url))) { - switch_core_hash_insert(globals.request_hash, context->dest_url, context); - xcontext = context; - } - switch_mutex_lock(context->mutex); - switch_mutex_unlock(globals.request_mutex); + do { + switch_mutex_lock(globals.request_mutex); + if ((x = switch_core_hash_find(globals.request_hash, context->dest_url))) { + switch_mutex_unlock(globals.request_mutex); + switch_yield(100000); + } + } while(x); - if (context != xcontext) { - switch_mutex_lock(xcontext->mutex); - switch_mutex_unlock(xcontext->mutex); - } - + switch_core_hash_insert(globals.request_hash, context->dest_url, (void *)1); + switch_mutex_unlock(globals.request_mutex); } else { switch_mutex_lock(globals.request_mutex); - if ((xcontext = switch_core_hash_find(globals.request_hash, context->dest_url)) && xcontext == context) { - switch_core_hash_delete(globals.request_hash, context->dest_url); - } - switch_mutex_unlock(context->mutex); + switch_core_hash_delete(globals.request_hash, context->dest_url); switch_mutex_unlock(globals.request_mutex); } - return status; + return; } @@ -2875,7 +2882,6 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path, context = switch_core_alloc(handle->memory_pool, sizeof(*context)); context->pool = handle->memory_pool; - switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); pdup = switch_core_strdup(context->pool, pa); @@ -2955,13 +2961,13 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path, } lock_file(context, SWITCH_TRUE); - - if ((status = locate_url_file(context, context->dest_url)) != SWITCH_STATUS_SUCCESS) { - return status; - } - + status = locate_url_file(context, context->dest_url); lock_file(context, SWITCH_FALSE); + if (status != SWITCH_STATUS_SUCCESS) { + return status; + } + if ((status = switch_core_file_open(&context->fh, context->cache_file, handle->channels, @@ -3005,9 +3011,6 @@ static switch_status_t http_file_file_close(switch_file_handle_t *handle) { http_file_context_t *context = handle->private_info; - switch_mutex_lock(context->mutex); - switch_mutex_unlock(context->mutex); - if (switch_test_flag((&context->fh), SWITCH_FILE_OPEN)) { switch_core_file_close(&context->fh); } From 062ddcfa6f61b7cf62119f76c4c827f4e1569910 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Wed, 21 Jan 2015 17:16:56 -0500 Subject: [PATCH 64/72] FS-7174: #resolve #comment make sure not to leave any sessions readlocked in bridge_early_media=true in case one in the middle of the list is abandoned --- src/switch_ivr_originate.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 00eebd1cc1..506fc53bfd 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1753,11 +1753,7 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * switch_core_session_t *session = originate_status[i].peer_session; switch_channel_t *channel = originate_status[i].peer_channel; - if (!session) { - break; - } - - if (!channel || !switch_channel_up(channel)) { + if (!session || !channel || !switch_channel_up(channel)) { continue; } @@ -1836,7 +1832,7 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void * switch_core_session_t *session = originate_status[i].peer_session; switch_channel_t *channel = originate_status[i].peer_channel; - if (!session) break; + if (!session) continue; if (switch_core_codec_ready((&read_codecs[i]))) { switch_core_codec_destroy(&read_codecs[i]); From 90d3cb633c45b9d21ed15d361d862e8e7d9be6fb Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Jan 2015 21:08:09 -0600 Subject: [PATCH 65/72] fix media reload on verto and sip re-invites --- src/switch_core_media.c | 8 +++++--- src/switch_rtp.c | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 9fe886d047..7137a05bc9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -3916,7 +3916,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s const char *rm_encoding; const switch_codec_implementation_t *mimp = NULL; int vmatch = 0, i; - + nm_idx = 0; m_idx = 0; memset(matches, 0, sizeof(matches[0]) * MAX_MATCHES); @@ -3991,7 +3991,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (!(rm_encoding = map->rm_encoding)) { rm_encoding = ""; } - + for (i = 0; i < total_codecs; i++) { const switch_codec_implementation_t *imp = codec_array[i]; @@ -4078,7 +4078,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s pmap->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp); pmap->agreed_pt = (switch_payload_t) map->rm_pt; - + + smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp; #if 0 if (j == 0 && (!switch_true(mirror) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) { @@ -5812,6 +5813,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi video_up: if (session && v_engine) { + printf("WTFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF?????\n"); check_dtls_reinvite(session, v_engine); } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0761948c5a..ad93d8ee71 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -379,6 +379,7 @@ struct switch_rtp { switch_mutex_t *flag_mutex; switch_mutex_t *read_mutex; switch_mutex_t *write_mutex; + switch_mutex_t *ice_mutex; switch_timer_t timer; uint8_t ready; uint8_t cn; @@ -842,6 +843,8 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d return; } + switch_mutex_lock(rtp_session->ice_mutex); + READ_INC(rtp_session); WRITE_INC(rtp_session); @@ -1213,7 +1216,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d end: - + switch_mutex_unlock(rtp_session->ice_mutex); READ_DEC(rtp_session); WRITE_DEC(rtp_session); } @@ -3499,6 +3502,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session switch_mutex_init(&rtp_session->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&rtp_session->read_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&rtp_session->write_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&rtp_session->ice_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&rtp_session->dtmf_data.dtmf_mutex, SWITCH_MUTEX_NESTED, pool); switch_queue_create(&rtp_session->dtmf_data.dtmf_queue, 100, rtp_session->pool); switch_queue_create(&rtp_session->dtmf_data.dtmf_inqueue, 100, rtp_session->pool); @@ -3947,7 +3951,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio switch_port_t port = 0; char bufc[30]; - READ_INC(rtp_session); + switch_mutex_lock(rtp_session->ice_mutex); if (proto == IPR_RTP) { ice = &rtp_session->ice; @@ -4016,7 +4020,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio switch_rtp_break(rtp_session); } - READ_DEC(rtp_session); + switch_mutex_unlock(rtp_session->ice_mutex); return SWITCH_STATUS_SUCCESS; } @@ -6630,11 +6634,13 @@ static int rtp_common_write(switch_rtp_t *rtp_session, srtp_dealloc(rtp_session->send_ctx[rtp_session->srtp_idx_rtp]); rtp_session->send_ctx[rtp_session->srtp_idx_rtp] = NULL; if ((stat = srtp_create(&rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &rtp_session->send_policy[rtp_session->srtp_idx_rtp]))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error! RE-Activating Secure RTP SEND\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, + "Error! RE-Activating %s Secure RTP SEND\n", rtp_type(rtp_session)); ret = -1; goto end; } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "RE-Activating Secure RTP SEND\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, + "RE-Activating %s Secure RTP SEND\n", rtp_type(rtp_session)); } } @@ -6642,7 +6648,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session, stat = srtp_protect(rtp_session->send_ctx[rtp_session->srtp_idx_rtp], &send_msg->header, &sbytes); if (stat) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error: SRTP protection failed with code %d\n", stat); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, + "Error: %s SRTP protection failed with code %d\n", rtp_type(rtp_session), stat); } bytes = sbytes; From 608d3e2425ee584d6c3c33fae16ce57cdc099ef7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Jan 2015 21:10:21 -0600 Subject: [PATCH 66/72] wtf --- src/switch_core_media.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 7137a05bc9..445e8771e9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -5813,7 +5813,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi video_up: if (session && v_engine) { - printf("WTFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF?????\n"); check_dtls_reinvite(session, v_engine); } From 01dcb74f33964e435e3b93d425ffaadaad67f206 Mon Sep 17 00:00:00 2001 From: "E. Schmidbauer" Date: Thu, 22 Jan 2015 15:41:22 -0500 Subject: [PATCH 67/72] FS-7187 add switch_cache_db_create_schema() to test for SCF_AUTO_SCHEMAS flag --- src/include/switch_core.h | 8 +++ src/mod/applications/mod_db/mod_db.c | 3 +- .../mod_voicemail/mod_voicemail.c | 2 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 +- src/switch_core_sqldb.c | 70 +++++++++++-------- 5 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 1414d518a2..89916b2a55 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -26,6 +26,7 @@ * Anthony Minessale II * Luke Dashjr (OpenMethods, LLC) * Joseph Sullivan + * Emmanuel Schmidbauer * * switch_core.h -- Core Library * @@ -2437,6 +2438,13 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle_dsn(switch_cache_ const char *file, const char *func, int line); #define switch_cache_db_get_db_handle_dsn(_a, _b) _switch_cache_db_get_db_handle_dsn(_a, _b, __FILE__, __SWITCH_FUNC__, __LINE__) +/*! + \brief Executes the create schema sql + \param [in] dbh The handle + \param [in] sql - sql to run + \param [out] err - Error if it exists +*/ +SWITCH_DECLARE(switch_status_t) switch_cache_db_create_schema(switch_cache_db_handle_t *dbh, char *sql, char **err); /*! \brief Executes the sql and returns the result as a string \param [in] dbh The handle diff --git a/src/mod/applications/mod_db/mod_db.c b/src/mod/applications/mod_db/mod_db.c index d0e9dd8931..bfaad70dc3 100644 --- a/src/mod/applications/mod_db/mod_db.c +++ b/src/mod/applications/mod_db/mod_db.c @@ -28,6 +28,7 @@ * Mathieu Rene * Bret McDanel * Rupa Schomaker + * Emmanuel Schmidbauer * * mod_db.c -- Implements simple db API, group support, and limit db backend * @@ -325,7 +326,7 @@ static switch_status_t do_config() switch_cache_db_test_reactive(dbh, "select * from group_data", NULL, group_sql); for (x = 0; indexes[x]; x++) { - switch_cache_db_execute_sql(dbh, indexes[x], NULL); + switch_cache_db_create_schema(dbh, indexes[x], NULL); } switch_cache_db_release_db_handle(&dbh); diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 423f293a8b..2f5f1b950c 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -782,7 +782,7 @@ static vm_profile_t *load_profile(const char *profile_name) for (x = 0; vm_index_list[x]; x++) { errmsg = NULL; - switch_cache_db_execute_sql(dbh, vm_index_list[x], &errmsg); + switch_cache_db_create_schema(dbh, vm_index_list[x], &errmsg); switch_safe_free(errmsg); } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 0aafd19789..c26c66740d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2271,7 +2271,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) free(test_sql); for (x = 0; indexes[x]; x++) { - switch_cache_db_execute_sql(dbh, indexes[x], NULL); + switch_cache_db_create_schema(dbh, indexes[x], NULL); } switch_cache_db_release_db_handle(&dbh); diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 508b68643d..2a73aeb95a 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -26,6 +26,7 @@ * Anthony Minessale II * Michael Jerris * Paul D. Tinsley + * Emmanuel Schmidbauer * * * switch_core_sqldb.c -- Main Core Library (statistics tracker) @@ -1267,6 +1268,19 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback_err(switch_ return status; } +SWITCH_DECLARE(switch_status_t) switch_cache_db_create_schema(switch_cache_db_handle_t *dbh, char *sql, char **err) +{ + switch_status_t r = SWITCH_STATUS_SUCCESS; + + switch_assert(sql != NULL); + + if (switch_test_flag((&runtime), SCF_AUTO_SCHEMAS)) { + r = switch_cache_db_execute_sql(dbh, sql, err); + } + + return r; +} + /*! * \brief Performs test_sql and if it fails performs drop_sql and reactive_sql. * @@ -3399,10 +3413,10 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_cache_db_test_reactive(sql_manager.dbh, "select hostname from recovery", "DROP TABLE recovery", recovery_sql); - switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery1 on recovery(technology)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery2 on recovery(profile_name)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery3 on recovery(uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index recovery3 on recovery(runtime_uuid)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index recovery1 on recovery(technology)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index recovery2 on recovery(profile_name)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index recovery3 on recovery(uuid)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index recovery3 on recovery(runtime_uuid)", NULL); @@ -3536,30 +3550,30 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ switch_cache_db_execute_sql(sql_manager.dbh, sql, NULL); } - switch_cache_db_execute_sql(sql_manager.dbh, "create index alias1 on aliases (alias)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index tasks1 on tasks (hostname,task_id)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete1 on complete (a1,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete2 on complete (a2,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete3 on complete (a3,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete4 on complete (a4,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete5 on complete (a5,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete6 on complete (a6,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete7 on complete (a7,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete8 on complete (a8,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete9 on complete (a9,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete10 on complete (a10,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index channels1 on channels(hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index calls1 on calls(hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index chidx1 on channels (hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex on channels (uuid, hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index uuindex2 on channels (call_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index callsidx1 on calls (hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index eruuindex on calls (caller_uuid, hostname)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex on calls (callee_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index eeuuindex2 on calls (call_uuid)", NULL); - switch_cache_db_execute_sql(sql_manager.dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index alias1 on aliases (alias)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index tasks1 on tasks (hostname,task_id)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete1 on complete (a1,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete2 on complete (a2,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete3 on complete (a3,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete4 on complete (a4,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete5 on complete (a5,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete6 on complete (a6,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete7 on complete (a7,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete8 on complete (a8,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete9 on complete (a9,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete10 on complete (a10,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index complete11 on complete (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index nat_map_port_proto on nat (port,proto,hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index channels1 on channels(hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index calls1 on calls(hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index chidx1 on channels (hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index uuindex on channels (uuid, hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index uuindex2 on channels (call_uuid)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index callsidx1 on calls (hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index eruuindex on calls (caller_uuid, hostname)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index eeuuindex on calls (callee_uuid)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index eeuuindex2 on calls (call_uuid)", NULL); + switch_cache_db_create_schema(sql_manager.dbh, "create index regindex1 on registrations (reg_user,realm,hostname)", NULL); skip: From fc93895624f6239cad7f207f7aa613d74863144a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 23 Jan 2015 11:03:33 -0600 Subject: [PATCH 68/72] FS-7173 #comment please test --- src/switch_core_codec.c | 15 +++++++++++++++ src/switch_ivr_async.c | 9 ++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index 63e33ec2b6..ef22e7714f 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -319,6 +319,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_read_impl(switch_core_se if (session->read_impl.codec_id) { *impp = session->read_impl; return SWITCH_STATUS_SUCCESS; + } else { + memset(impp, 0, sizeof(*impp)); + impp->number_of_channels = 1; } return SWITCH_STATUS_FALSE; @@ -329,6 +332,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_real_read_impl(switch_co if (session->real_read_impl.codec_id) { *impp = session->real_read_impl; return SWITCH_STATUS_SUCCESS; + } else { + memset(impp, 0, sizeof(*impp)); + impp->number_of_channels = 1; } return SWITCH_STATUS_FALSE; @@ -339,6 +345,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_write_impl(switch_core_s if (session->write_impl.codec_id) { *impp = session->write_impl; return SWITCH_STATUS_SUCCESS; + } else { + memset(impp, 0, sizeof(*impp)); + impp->number_of_channels = 1; } return SWITCH_STATUS_FALSE; @@ -349,6 +358,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_read_impl(switch_c if (session->video_read_impl.codec_id) { *impp = session->video_read_impl; return SWITCH_STATUS_SUCCESS; + } else { + memset(impp, 0, sizeof(*impp)); + impp->number_of_channels = 1; } return SWITCH_STATUS_FALSE; @@ -359,6 +371,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_write_impl(switch_ if (session->video_write_impl.codec_id) { *impp = session->video_write_impl; return SWITCH_STATUS_SUCCESS; + } else { + memset(impp, 0, sizeof(*impp)); + impp->number_of_channels = 1; } return SWITCH_STATUS_FALSE; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 792dba257b..60de27c73e 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1121,8 +1121,8 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void * switch_channel_t *channel = switch_core_session_get_channel(session); struct record_helper *rh; switch_size_t bsize = SWITCH_RECOMMENDED_BUFFER_SIZE, samples = 0, inuse = 0; - unsigned char *data = switch_core_session_alloc(session, bsize); - int channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : rh->read_impl.number_of_channels; + unsigned char *data; + int channels = 1; if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { return NULL; @@ -1132,6 +1132,9 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void * switch_buffer_create_dynamic(&rh->thread_buffer, 1024 * 512, 1024 * 64, 0); rh->thread_ready = 1; + channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : rh->read_impl.number_of_channels; + data = switch_core_session_alloc(session, bsize); + while(switch_test_flag(rh->fh, SWITCH_FILE_OPEN)) { switch_mutex_lock(rh->buffer_mutex); inuse = switch_buffer_inuse(rh->thread_buffer); @@ -1144,7 +1147,7 @@ static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void * switch_mutex_unlock(rh->buffer_mutex); break; } - + samples = switch_buffer_read(rh->thread_buffer, data, bsize) / 2 / channels; switch_mutex_unlock(rh->buffer_mutex); From b37d0719087f1360b1b6d4aa3e0d7e3e8eb1ffba Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 23 Jan 2015 13:14:58 -0600 Subject: [PATCH 69/72] FS-7186 #resolve --- src/switch_ivr_originate.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 506fc53bfd..9e25ba0aef 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1655,13 +1655,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess for (i = 0; i < x_argc; i++) { - if (channel) { - switch_channel_handle_cause(channel, handles[i].cause); - } - if (hp == &handles[i]) { continue; } + + if (channel && handles[i].cause && handles[i].cause != SWITCH_CAUSE_SUCCESS) { + switch_channel_handle_cause(channel, handles[i].cause); + } + switch_mutex_unlock(handles[i].mutex); if (getcause && *cause != handles[i].cause && handles[i].cause != SWITCH_CAUSE_LOSE_RACE && handles[i].cause != SWITCH_CAUSE_NO_PICKUP) { From 17102140254050e4246b18cf97a27857eb808e97 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 23 Jan 2015 20:53:00 +0000 Subject: [PATCH 70/72] enable nat mode for verto when ext-rtp-ip is set --- src/mod/endpoints/mod_verto/mod_verto.c | 2 +- src/switch_core_media.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 58b66a9b61..9c5272bad9 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -2203,7 +2203,7 @@ static void verto_set_media_options(verto_pvt_t *tech_pvt, verto_profile_t *prof profile->rtpip_cur = 0; } - tech_pvt->mparams->extrtpip = profile->extrtpip; + tech_pvt->mparams->extrtpip = tech_pvt->mparams->extsipip = profile->extrtpip; //tech_pvt->mparams->dtmf_type = tech_pvt->profile->dtmf_type; switch_channel_set_flag(tech_pvt->channel, CF_TRACKABLE); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 445e8771e9..e16b681583 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2926,6 +2926,11 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(smh->session, (char *) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_addr); engine->cur_payload_map->remote_sdp_port = (switch_port_t) engine->ice_in.cands[engine->ice_in.chosen[0]][0].con_port; + + if (!smh->mparams->remote_ip) { + smh->mparams->remote_ip = engine->cur_payload_map->remote_sdp_ip; + } + if (engine->remote_rtcp_port) { engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port; } From 76370f4d1767bb0dcf828a3d6cde6e015b2cfa03 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 23 Jan 2015 15:06:16 -0600 Subject: [PATCH 71/72] auto urlencode user portion of sip uri --- src/include/switch_utils.h | 26 +++++++++++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 52 +++++++++++++++++++++++++ src/switch_utils.c | 14 +++++-- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 523e3a4768..395c1b5e16 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -43,6 +43,9 @@ SWITCH_BEGIN_EXTERN_C +#define SWITCH_URL_UNSAFE "\r\n \"#%&+:;<=>?@[\\]^`{|}" + + /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii http://www.azillionmonkeys.com/qed/asmexample.html */ @@ -971,6 +974,29 @@ 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 int switch_needs_url_encode(const char *s) +{ + const char hex[] = "0123456789ABCDEF"; + const char *p, *e = end_of_p(s); + + + for(p = s; p && *p; p++) { + if (*p == '%' && e-p > 1) { + if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) { + p++; + continue; + } + } + + if (strchr(SWITCH_URL_UNSAFE, *p)) { + return 1; + } + } + + return 0; +} + SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len); SWITCH_DECLARE(char *) switch_url_decode(char *s); SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to, diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 223bb195b3..68453edf34 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4247,6 +4247,54 @@ static switch_status_t sofia_manage(char *relative_oid, switch_management_action return SWITCH_STATUS_SUCCESS; } +static void protect_dest_uri(switch_caller_profile_t *cp) +{ + char *p = cp->destination_number, *o = p; + char *q = NULL, *e = NULL, *qenc = NULL; + switch_size_t enclen = 0; + + while((p = strchr(p, '/'))) { + q = p++; + } + + if (q) { + const char *i; + int go = 0; + + for (i = q+1; i && *i && *i != '@'; i++) { + if (strchr(SWITCH_URL_UNSAFE, *i)) { + go = 1; + } + } + + if (!go) return; + + *q++ = '\0'; + } else { + return; + } + + if (!strncasecmp(q, "sips:", 5)) { + q += 5; + } else if (!strncasecmp(q, "sip:", 4)) { + q += 4; + } + + if (!(e = strchr(q, '@'))) { + return; + } + + *e++ = '\0'; + + if (switch_needs_url_encode(q)) { + enclen = (strlen(q) * 2) + 2; + qenc = switch_core_alloc(cp->pool, enclen); + switch_url_encode(q, qenc, enclen); + } + + cp->destination_number = switch_core_sprintf(cp->pool, "%s/%s@%s", o, qenc ? qenc : q, e); +} + static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause) @@ -4272,6 +4320,10 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session goto error; } + if (!switch_true(switch_event_get_header(var_event, "sofia_suppress_url_encoding"))) { + protect_dest_uri(outbound_profile); + } + if (!(nsession = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool, switch_event_get_header(var_event, "origination_uuid")))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n"); diff --git a/src/switch_utils.c b/src/switch_utils.c index 444333ec12..905442e6ce 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -2923,9 +2923,8 @@ SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms) SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len) { - const char *p; + const char *p, *e = end_of_p(url); size_t x = 0; - const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}"; const char hex[] = "0123456789ABCDEF"; if (!buf) { @@ -2939,10 +2938,19 @@ SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len) len--; for (p = url; *p; p++) { + int ok = 0; + if (x >= len) { break; } - if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) { + + if (*p == '%' && e-p > 1) { + if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) { + ok = 1; + } + } + + if (!ok && (*p < ' ' || *p > '~' || strchr(SWITCH_URL_UNSAFE, *p))) { if ((x + 3) > len) { break; } From 83dd94193d292084bd29eaa6ab65c859f65a7c59 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 23 Jan 2015 15:12:26 -0600 Subject: [PATCH 72/72] FS-7166 #resolve --- src/include/switch_types.h | 1 + src/switch_core_media.c | 12 +++++++----- src/switch_core_session.c | 8 ++++++++ src/switch_ivr.c | 7 +++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 69602de419..6cd4836846 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1338,6 +1338,7 @@ typedef enum { CF_WINNER, CF_CONTROLLED, CF_PROXY_MODE, + CF_PROXY_OFF, CF_SUSPEND, CF_EVENT_PARSE, CF_GEN_RINGBACK, diff --git a/src/switch_core_media.c b/src/switch_core_media.c index e16b681583..7d6d443fbf 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -5881,10 +5881,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, //port, secure ? "S" : "", switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : ""); switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d %s", port, - get_media_profile_name(session, - (secure && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) || - a_engine->crypto_type != CRYPTO_INVALID)); - + get_media_profile_name(session, secure || a_engine->crypto_type != CRYPTO_INVALID)); for (i = 0; i < smh->mparams->num_codecs; i++) { const switch_codec_implementation_t *imp = smh->codecs[i]; @@ -6307,6 +6304,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_channel_clear_flag(smh->session->channel, CF_DTLS); } + if (switch_channel_test_flag(session->channel, CF_PROXY_OFF) && (tmp = switch_channel_get_variable(smh->session->channel, "uuid_media_secure_media"))) { + switch_channel_set_variable(smh->session->channel, "rtp_secure_media", tmp); + switch_core_session_parse_crypto_prefs(session); + switch_core_session_check_outgoing_crypto(session); + } + if (is_outbound || switch_channel_test_flag(session->channel, CF_RECOVERING) || switch_channel_test_flag(session->channel, CF_3PCC)) { if (!switch_channel_test_flag(session->channel, CF_WEBRTC) && @@ -6724,7 +6727,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess mult = switch_channel_get_variable(session->channel, "sdp_m_per_ptime"); - if (switch_channel_test_flag(session->channel, CF_WEBRTC) || (mult && switch_false(mult))) { char *bp = buf; int both = (switch_channel_test_flag(session->channel, CF_WEBRTC) || switch_channel_test_flag(session->channel, CF_DTLS)) ? 0 : 1; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index a3728234e1..4e02b735c7 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -808,6 +808,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit switch_channel_clear_flag(session->channel, CF_EARLY_MEDIA); } + if (message->message_id == SWITCH_MESSAGE_INDICATE_MEDIA) { + switch_channel_set_flag(session->channel, CF_PROXY_OFF); + } + if (message->message_id == SWITCH_MESSAGE_INDICATE_DISPLAY) { char *arg = NULL; @@ -914,6 +918,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit end: + if (message->message_id == SWITCH_MESSAGE_INDICATE_MEDIA) { + switch_channel_clear_flag(session->channel, CF_PROXY_OFF); + } + switch_core_session_free_message(&message); switch_core_session_rwunlock(session); diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 24f177355a..ad9b6b1139 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1653,6 +1653,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_nomedia(const char *uuid, switch_medi status = SWITCH_STATUS_SUCCESS; channel = switch_core_session_get_channel(session); + if (switch_channel_test_flag(channel, CF_SECURE)) { + switch_core_session_rwunlock(session); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, + "Cannot bypass %s due to secure connection.\n", switch_channel_get_name(channel)); + return SWITCH_STATUS_FALSE; + } + if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) { switch_core_session_rwunlock(session); return SWITCH_STATUS_INUSE;