diff --git a/configure.ac b/configure.ac index 016b66027a..e45d0bba11 100644 --- a/configure.ac +++ b/configure.ac @@ -1122,6 +1122,8 @@ elif test "$ac_cv_sizeof_long" = "8"; then case "$host" in *pc-solaris2*) ;; + sparc-*-solaris2*) + ;; *-solaris2*|*apple-darwin*|*-openbsd*) if test "$ac_cv_sizeof_long_long" = "8"; then int64_t_fmt='#define SWITCH_INT64_T_FMT "lld"' diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index 6783699354..a8ccae6570 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -608,6 +608,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}), freeswitch-mod-memcache (= \${binary:Version}), freeswitch-mod-nibblebill (= \${binary:Version}), freeswitch-mod-oreka (= \${binary:Version}), + freeswitch-mod-png (= \${binary:Version}), freeswitch-mod-redis (= \${binary:Version}), freeswitch-mod-rss (= \${binary:Version}), freeswitch-mod-sms (= \${binary:Version}), diff --git a/debian/freeswitch-systemd.freeswitch.service b/debian/freeswitch-systemd.freeswitch.service index cc0cf1d582..b9fbdb9d76 100644 --- a/debian/freeswitch-systemd.freeswitch.service +++ b/debian/freeswitch-systemd.freeswitch.service @@ -19,7 +19,7 @@ Group=daemon LimitCORE=infinity LimitNOFILE=100000 LimitNPROC=60000 -LimitSTACK=240K +LimitSTACK=250000 LimitRTPRIO=infinity LimitRTTIME=7000000 IOSchedulingClass=realtime diff --git a/debian/util.sh b/debian/util.sh index aa828e365c..51e50c47f1 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -199,7 +199,7 @@ create_dsc () { m) modules_list="$OPTARG";; p) modules_add="$modules_add $OPTARG";; s) speed="$OPTARG";; - u) suite_postfix="$OPTARG"; suite_postfix_p=true; ;; + u) suite_postfix="$OPTARG"; suite_postfix_p=true;; z) zl="$OPTARG";; esac done @@ -245,7 +245,7 @@ create_dsc () { } fmt_debug_hook () { - cat <<'EOF' + cat <<'EOF' #!/bin/bash export debian_chroot="cow" cd /tmp/buildd/*/debian/.. @@ -290,24 +290,24 @@ build_debs () { done shift $(($OPTIND-1)) if [ "$custom_sources_file" == "/etc/apt/sources.list" ]; then - # If you are using the system sources, then it is reasonable that you expect to use all of the supplementary repos too - cat /etc/apt/sources.list > /tmp/fs.sources.list - if [ "$(ls -A /etc/apt/sources.list.d)" ]; then - for X in /etc/apt/sources.list.d/*; do cat $X >> /tmp/fs.sources.list; done - fi - custom_sources_file="/tmp/fs.sources.list" - apt-key exportall > "/tmp/fs.asc" - custom_keyring="/tmp/fs.asc" + # If you are using the system sources, then it is reasonable that you expect to use all of the supplementary repos too + cat /etc/apt/sources.list > /tmp/fs.sources.list + if [ "$(ls -A /etc/apt/sources.list.d)" ]; then + for X in /etc/apt/sources.list.d/*; do cat $X >> /tmp/fs.sources.list; done + fi + custom_sources_file="/tmp/fs.sources.list" + apt-key exportall > "/tmp/fs.asc" + custom_keyring="/tmp/fs.asc" fi if [ "$custom_sources_file" == "" ]; then - # Caller has explicitly set the custom sources file to empty string. They must intend to not use additional mirrors. - use_custom_sources=false + # Caller has explicitly set the custom sources file to empty string. They must intend to not use additional mirrors. + use_custom_sources=false fi if [[ "$custom_source_file" == "/tmp/fs.sources.list" && ! -e "/tmp/fs.sources.list" ]]; then - echo "deb http://files.freeswitch.org/repo/deb/debian/ jessie main" >> "/tmp/fs.sources.list" + echo "deb http://files.freeswitch.org/repo/deb/debian/ jessie main" >> "/tmp/fs.sources.list" fi if [[ "$custom_keyring" == "/tmp/fs.asc" && ! -r "/tmp/fs.asc" ]]; then - cat << EOF > "/tmp/fs.asc" + cat << EOF > "/tmp/fs.asc" -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.12 (GNU/Linux) diff --git a/freeswitch.spec b/freeswitch.spec index 9e3f2a748e..a6b38719bb 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -1543,7 +1543,7 @@ LOGGERS_MODULES="loggers/mod_console loggers/mod_graylog2 loggers/mod_logfile lo # Phrase engine language modules # ###################################################################################################################### -SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_fr say/mod_say_he say/mod_say_ru say/mod_say_sv" +SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_es say/mod_say_pt say/mod_say_fr say/mod_say_he say/mod_say_ru say/mod_say_sv" ###################################################################################################################### # @@ -2442,7 +2442,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/vm/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/es/dir/*.xml -%{MODINSTDIR}/mod_say_en.so* +%{MODINSTDIR}/mod_say_es.so* %files lang-pt %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/pt @@ -2453,7 +2453,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/demo/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/vm/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/lang/pt/dir/*.xml -%{MODINSTDIR}/mod_say_en.so* +%{MODINSTDIR}/mod_say_pt.so* %files lang-sv %dir %attr(0750, freeswitch, daemon) %{sysconfdir}/lang/sv diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index 2ea234eb45..dbe0017137 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -6,12 +6,13 @@ function getCodecPayloadType(sdpLine){var pattern=new RegExp('a=rtpmap:(\\d+) \\ function setDefaultCodec(mLine,payload){var elements=mLine.split(' ');var newLine=[];var index=0;for(var i=0;i=resList.length){var res={'validRes':$.FSRTC.validRes,'bestResSupported':$.FSRTC.bestResSupported()};localStorage.setItem("res_"+cam,$.toJSON(res));if(func)return func(res);return;} var video={mandatory:{},optional:[]} if(cam){video.optional=[{sourceId:cam}];} -w=resList[resI][0];h=resList[resI][1];resI++;video.mandatory={"minWidth":w,"minHeight":h,"maxWidth":w,"maxHeight":h};if(window.moz){video=video.mandatory;if(!video.width)video.width=video.minWidth;if(!video.height)video.height=video.minHeight;if(!video.frameRate)video.frameRate=video.minFrameRate;} -getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.stop();console.info(w+"x"+h+" supported.");$.FSRTC.validRes.push([w,h]);checkRes(cam,func);},onerror:function(e){console.error(w+"x"+h+" not supported.");checkRes(cam,func);}});} +w=resList[resI][0];h=resList[resI][1];resI++;video.mandatory={"minWidth":w,"minHeight":h,"maxWidth":w,"maxHeight":h};getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info(w+"x"+h+" supported.");$.FSRTC.validRes.push([w,h]);checkRes(cam,func);},onerror:function(e){console.error(w+"x"+h+" not supported.");checkRes(cam,func);}});} $.FSRTC.getValidRes=function(cam,func){var used=[];var cached=localStorage.getItem("res_"+cam);if(cached){var cache=$.parseJSON(cached);if(cache){$.FSRTC.validRes=cache.validRes;console.log("CACHED RES FOR CAM "+cam,cache);}else{console.error("INVALID CACHE");} return func?func(cache):null;} $.FSRTC.validRes=[];resI=0;checkRes(cam,func);} -$.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.stop();console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true)}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);} -console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.call=function(method,params,success_cb,error_cb){if(!params){params={};} +$.FSRTC.checkPerms=function(runtime,check_audio,check_video){getUserMedia({constraints:{audio:check_audio,video:check_video,},onsuccess:function(e){e.getTracks().forEach(function(track){track.stop();});console.info("media perm init complete");if(runtime){setTimeout(runtime,100,true);}},onerror:function(e){if(check_video&&check_audio){console.error("error, retesting with audio params only");return $.FSRTC.checkPerms(runtime,check_audio,false);} +console.error("media perm init error");if(runtime){runtime(false)}}});}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,loginParams:null,userVariables:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);self.ws_cnt=0;this.wsOnMessage=function(event){self._wsOnMessage(event);};};$.JsonRpcClient.prototype._ws_socket=null;$.JsonRpcClient.prototype._ws_callbacks={};$.JsonRpcClient.prototype._current_id=1;$.JsonRpcClient.prototype.speedTest=function(bytes,cb){var socket=this.options.getSocket(this.wsOnMessage);if(socket!==null){this.speedCB=cb;this.speedBytes=bytes;socket.send("#SPU "+bytes);var loops=bytes/1024;var rem=bytes%1024;var i;var data=new Array(1024).join(".");for(i=0;i-1){var tmp=$.parseJSON(data[4]);data[4]=tmp.oldStatus;data[5]=null;} +return data;} +function genArray(obj){var data=obj.asArray();for(var i in data){data[i]=genRow(data[i]);} +return data;} +la.onChange=function(obj,args){var index=0;var iserr=0;if(!dt){if(!config.aoColumns){if(args.action!="init"){return;} config.aoColumns=[];for(var i in args.data){config.aoColumns.push({"sTitle":args.data[i]});}} dt=jq.dataTable(config);} if(dt&&(args.action=="del"||args.action=="modify")){index=args.index;if(index===undefined&&args.key){index=la.indexOf(args.key);} if(index===undefined){console.error("INVALID PACKET Missing INDEX\n",args);return;}} if(config.onChange){config.onChange(obj,args);} try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data");return;} -dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} -if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);} +dt.fnClearTable();dt.fnAddData(genArray(obj));dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;} +if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(genArray(obj));}else{dt.fnAddData(genRow(args.data));} dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;} -dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} +dt.fnUpdate(genRow(args.data),index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(genArray(obj));break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.conf=function(verto,params){var conf=this;conf.params=$.extend({dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);conf.verto=verto;conf.serno=CONFMAN_SERNO++;createMainModeratorMethods();verto.subscribe(conf.params.laData.modChannel,{handler:function(v,e){if(conf.params.onBroadcast){conf.params.onBroadcast(verto,conf,e.data);}}});verto.subscribe(conf.params.laData.chatChannel,{handler:function(v,e){if(typeof(conf.params.chatCallback)==="function"){conf.params.chatCallback(v,e);}}});};$.verto.conf.prototype.modCommand=function(cmd,id,value){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.conf.prototype.destroy=function(){var conf=this;conf.destroyed=true;conf.params.onBroadcast(conf.verto,conf,'destroy');if(conf.params.laData.modChannel){conf.verto.unsubscribe(conf.params.laData.modChannel);} if(conf.params.laData.chatChannel){conf.verto.unsubscribe(conf.params.laData.chatChannel);}};function createMainModeratorMethods(){$.verto.conf.prototype.listVideoLayouts=function(){this.modCommand("list-videoLayouts",null,null);};$.verto.conf.prototype.play=function(file){this.modCommand("play",null,file);};$.verto.conf.prototype.stop=function(){this.modCommand("stop",null,"all");};$.verto.conf.prototype.record=function(file){this.modCommand("recording",null,["start",file]);};$.verto.conf.prototype.stopRecord=function(){this.modCommand("recording",null,["stop","all"]);};$.verto.conf.prototype.snapshot=function(file){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("vid-write-png",null,file);};$.verto.conf.prototype.setVideoLayout=function(layout){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("vid-layout",null,layout);};$.verto.conf.prototype.kick=function(memberID){this.modCommand("kick",parseInt(memberID));};$.verto.conf.prototype.muteMic=function(memberID){this.modCommand("tmute",parseInt(memberID));};$.verto.conf.prototype.muteVideo=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} +this.modCommand("vid-write-png",null,file);};$.verto.conf.prototype.setVideoLayout=function(layout,canvasID){if(!this.params.hasVid){throw'Conference has no video';} +if(canvasID){this.modCommand("vid-layout",null,[layout,canvasID]);}else{this.modCommand("vid-layout",null,layout);}};$.verto.conf.prototype.kick=function(memberID){this.modCommand("kick",parseInt(memberID));};$.verto.conf.prototype.muteMic=function(memberID){this.modCommand("tmute",parseInt(memberID));};$.verto.conf.prototype.muteVideo=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} this.modCommand("tvmute",parseInt(memberID));};$.verto.conf.prototype.presenter=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} this.modCommand("vid-res-id",parseInt(memberID),"presenter");};$.verto.conf.prototype.videoFloor=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} this.modCommand("vid-floor",parseInt(memberID),"force");};$.verto.conf.prototype.banner=function(memberID,text){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("vid-banner",parseInt(memberID),escape(text));};$.verto.conf.prototype.volumeDown=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("volume_in",parseInt(memberID),"down");};$.verto.conf.prototype.volumeUp=function(memberID){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("volume_in",parseInt(memberID),"up");};$.verto.conf.prototype.transfer=function(memberID,exten){if(!this.params.hasVid){throw'Conference has no video';} -this.modCommand("transfer",parseInt(memberID),exten);};$.verto.conf.prototype.sendChat=function(message,type){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};} +this.modCommand("vid-banner",parseInt(memberID),escape(text));};$.verto.conf.prototype.volumeDown=function(memberID){this.modCommand("volume_out",parseInt(memberID),"down");};$.verto.conf.prototype.volumeUp=function(memberID){this.modCommand("volume_out",parseInt(memberID),"up");};$.verto.conf.prototype.gainDown=function(memberID){this.modCommand("volume_in",parseInt(memberID),"down");};$.verto.conf.prototype.gainUp=function(memberID){this.modCommand("volume_in",parseInt(memberID),"up");};$.verto.conf.prototype.transfer=function(memberID,exten){this.modCommand("transfer",parseInt(memberID),exten);};$.verto.conf.prototype.sendChat=function(message,type){var conf=this;conf.verto.rpcClient.call("verto.broadcast",{"eventChannel":conf.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};} $.verto.modfuncs={};$.verto.confMan=function(verto,params){var confMan=this;confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;confMan.canvasCount=confMan.params.laData.canvasCount;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var snapshot_id="snapshot_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="

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

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

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

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

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

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

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

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

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

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

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

");},4000);}}}});if(confMan.params.hasVid){confMan.modCommand("list-videoLayouts",null,null);}} var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback=function(nRow,aData,iDisplayIndex,iDisplayIndexFull){if(!aData[5]){var $row=$('td:eq(5)',nRow);genControls($row,aData);if(confMan.params.onLaRow){confMan.params.onLaRow(verto,confMan,$row,aData);}}};} confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID","sWidth":"50"},{"sTitle":"Number","sWidth":"250"},{"sTitle":"Name","sWidth":"250"},{"sTitle":"Codec","sWidth":"100"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"200px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1400,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.sendChat=function(message,type){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} if(confMan.params.laData.chatChannel){confMan.verto.unsubscribe(confMan.params.laData.chatChannel);} if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);} -if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:verto.options.deviceParams.useCamera,useMic:verto.options.deviceParams.useMic,useSpeak:verto.options.deviceParams.useSpeak,tag:verto.options.tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=dialog.params.useCamera;dialog.useMic=dialog.params.useMic;dialog.useSpeak=dialog.params.useSpeak;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} +if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;var tag=verto.options.tag;if(typeof(tag)==="function"){tag=tag();} +dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:verto.options.deviceParams.useCamera,useMic:verto.options.deviceParams.useMic,useSpeak:verto.options.deviceParams.useSpeak,tag:tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=dialog.params.useCamera;dialog.useMic=dialog.params.useMic;dialog.useSpeak=dialog.params.useSpeak;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}} if(dialog.params.localTag){dialog.localVideo=document.getElementById(dialog.params.localTag);} dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;} @@ -238,18 +254,24 @@ if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="No if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";} RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;} RTCcallbacks.onICESDP=function(rtc){console.log("RECV "+rtc.type+" SDP",rtc.mediaData.SDP);if(dialog.state==$.verto.enum.state.requesting||dialog.state==$.verto.enum.state.answering||dialog.state==$.verto.enum.state.active){location.reload();return;} -if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;} +if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.screenShare?null:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;} obj.dialogParams[i]=dialog.params[i];} dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;} return false;} +function find_name(id){for(var i in $.verto.audioOutDevices){var source=$.verto.audioOutDevices[i];if(source.id===id){return(source.label);}} +return id;} +$.verto.dialog.prototype.setAudioPlaybackDevice=function(sinkId,callback,arg){var dialog=this;var element=dialog.audioStream;if(typeof element.sinkId!=='undefined'){var devname=find_name(sinkId);console.info("Dialog: "+dialog.callID+" Setting speaker:",element,devname);element.setSinkId(sinkId).then(function(){console.log("Dialog: "+dialog.callID+' Success, audio output device attached: '+sinkId);if(callback){callback(true,devname,arg);}}).catch(function(error){var errorMessage=error;if(error.name==='SecurityError'){errorMessage="Dialog: "+dialog.callID+' You need to use HTTPS for selecting audio output '+'device: '+error;} +if(callback){callback(false,null,arg);} +console.error(errorMessage);});}else{console.warn("Dialog: "+dialog.callID+' Browser does not support output device selection.');if(callback){callback(false,null,arg);}}} $.verto.dialog.prototype.setState=function(state){var dialog=this;if(dialog.state==$.verto.enum.state.ringing){dialog.stopRinging();} if(dialog.state==state||!checkStateChange(dialog.state,state)){console.error("Dialog "+dialog.callID+": INVALID state change from "+dialog.state.name+" to "+state.name);dialog.hangup();return false;} console.log("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;} if(!dialog.cause){dialog.cause="NORMAL CLEARING";} if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);} -switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"){var videoElement=dialog.audioStream;setTimeout(function(){console.info("Setting speaker:",videoElement,speaker);attachSinkId(videoElement,speaker);},500);} +switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"&&speaker!=="none"){setTimeout(function(){dialog.setAudioPlaybackDevice(speaker);},500);} break;case $.verto.enum.state.trying:setTimeout(function(){if(dialog.state==$.verto.enum.state.trying){dialog.setState($.verto.enum.state.hangup);}},30000);break;case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});} -dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(!dialog.params.screenShare){dialog.rtc.stop();} +dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:if(typeof(dialog.verto.options.tag)==="function"){$('#'+dialog.params.tag).remove();} +delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();} break;} return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} @@ -258,7 +280,7 @@ if(success){} break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;} if(params.cause){dialog.cause=params.cause;}} if(dialog.state.val>=$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;} -dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;} +dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;} if(!msg.body){console.error("Missing Body");err++;} if(err){return false;} dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(!params){params={};} @@ -273,7 +295,8 @@ dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.h dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1,hangup:1},requesting:{trying:1,hangup:1,active:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$.verto.unloadJobs=[];$(window).bind('beforeunload',function(){for(var f in $.verto.unloadJobs){$.verto.unloadJobs[f]();} for(var i in $.verto.saved){var verto=$.verto.saved[i];if(verto){verto.purge();verto.logout();}} return $.verto.warnOnUnload;});$.verto.videoDevices=[];$.verto.audioInDevices=[];$.verto.audioOutDevices=[];var checkDevices=function(runtime){console.info("enumerating devices");var aud_in=[],aud_out=[],vid=[];if((!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices)&&MediaStreamTrack.getSources){MediaStreamTrack.getSources(function(media_sources){for(var i=0;i + diff --git a/html5/verto/verto_communicator/src/locales/locale-en.json b/html5/verto/verto_communicator/src/locales/locale-en.json index c8c59ace10..ade59cc7d4 100644 --- a/html5/verto/verto_communicator/src/locales/locale-en.json +++ b/html5/verto/verto_communicator/src/locales/locale-en.json @@ -149,5 +149,6 @@ "CHAT_GAIN_MINUS": "Gain -", "CHAT_GAIN_PLUS": "Gain +", "LANGUAGE": "Language:", - "BROWSER_LANGUAGE": "Browser Language" + "BROWSER_LANGUAGE": "Browser Language", + "FACTORY_RESET_SETTINGS": "Factory Reset Settings" } diff --git a/html5/verto/verto_communicator/src/locales/locale-pt.json b/html5/verto/verto_communicator/src/locales/locale-pt.json index 4bd236f855..19f04512ba 100644 --- a/html5/verto/verto_communicator/src/locales/locale-pt.json +++ b/html5/verto/verto_communicator/src/locales/locale-pt.json @@ -147,5 +147,6 @@ "CHAT_VOL_MINUS": "Vol -", "CHAT_VOL_PLUS": "Vol +", "CHAT_GAIN_MINUS": "Ganho -", - "CHAT_GAIN_PLUS": "Ganho +" + "CHAT_GAIN_PLUS": "Ganho +", + "FACTORY_RESET_SETTINGS": "Redefinir configurações" } diff --git a/html5/verto/verto_communicator/src/partials/settings.html b/html5/verto/verto_communicator/src/partials/settings.html index 96d19db0b7..7e15a24e3b 100644 --- a/html5/verto/verto_communicator/src/partials/settings.html +++ b/html5/verto/verto_communicator/src/partials/settings.html @@ -1,4 +1,4 @@ -
+
@@ -162,6 +162,7 @@ ng-options="item.id as item.label for item in verto.bandwidth">
+
diff --git a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js index 80b81236da..dc3ce4a181 100644 --- a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js +++ b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js @@ -18,6 +18,7 @@ 'ui.bootstrap', 'directive.g+signin', 'pascalprecht.translate', + 'angular-click-outside', ]); vertoApp.constant('configLanguages', { diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index b1a3794c12..6f61816c82 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -290,6 +290,11 @@ $rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled')); }; + $scope.closeSettings = function() { + var settingsEl = angular.element(document.querySelector('#settings')); + settingsEl.removeClass('toggled'); + }; + $scope.goFullscreen = function() { if (storage.data.userStatus !== 'connected') { return; diff --git a/html5/verto/video_demo/js/verto-min.js b/html5/verto/video_demo/js/verto-min.js index eff22f009c..dbe0017137 100644 --- a/html5/verto/video_demo/js/verto-min.js +++ b/html5/verto/video_demo/js/verto-min.js @@ -141,7 +141,8 @@ if(!verto.options.deviceParams.useMic){verto.options.deviceParams.useMic="any";} if(!verto.options.deviceParams.useSpeak){verto.options.deviceParams.useSpeak="any";} if(verto.options.sessid){verto.sessid=verto.options.sessid;}else{verto.sessid=localStorage.getItem("verto_session_uuid")||generateGUID();localStorage.setItem("verto_session_uuid",verto.sessid);} verto.dialogs={};verto.callbacks=callbacks||{};verto.eventSUBS={};verto.rpcClient=new $.JsonRpcClient({login:verto.options.login,passwd:verto.options.passwd,socketUrl:verto.options.socketUrl,loginParams:verto.options.loginParams,userVariables:verto.options.userVariables,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.purge();}});var tag=verto.options.tag;if(typeof(tag)==="function"){tag=tag();} +if(verto.options.ringFile&&verto.options.tag){verto.ringer=$("#"+tag);} verto.rpcClient.call('login',{});};$.verto.prototype.deviceParams=function(obj){var verto=this;for(var i in obj){verto.options.deviceParams[i]=obj[i];} if(obj.useCamera){$.FSRTC.getValidRes(verto.options.deviceParams.useCamera,obj?obj.onResCheck:undefined);}};$.verto.prototype.videoParams=function(obj){var verto=this;for(var i in obj){verto.options.videoParams[i]=obj[i];}};$.verto.prototype.iceServers=function(obj){var verto=this;verto.options.iceServers=obj;};$.verto.prototype.loginData=function(params){var verto=this;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();if(verto.callbacks.onWSClose){verto.callbacks.onWSClose(verto,false);} 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++;} @@ -244,7 +245,8 @@ var row_callback=null;if(confMan.params.laData.role==="moderator"){row_callback= confMan.lt=new $.verto.liveTable(verto,confMan.params.laData.laChannel,confMan.params.laData.laName,$(confMan.params.tableID),{subParams:{callID:confMan.params.dialog?confMan.params.dialog.callID:null},"onChange":function(obj,args){$(confMan.params.statusID).text("Conference Members: "+" ("+obj.arrayLen()+" Total)");if(confMan.params.onLaChange){confMan.params.onLaChange(verto,confMan,$.verto.enum.confEvent.laChange,obj,args);}},"aaData":[],"aoColumns":[{"sTitle":"ID","sWidth":"50"},{"sTitle":"Number","sWidth":"250"},{"sTitle":"Name","sWidth":"250"},{"sTitle":"Codec","sWidth":"100"},{"sTitle":"Status","sWidth":confMan.params.hasVid?"200px":"150px"},{"sTitle":atitle,"sWidth":awidth,}],"bAutoWidth":true,"bDestroy":true,"bSort":false,"bInfo":false,"bFilter":false,"bLengthChange":false,"bPaginate":false,"iDisplayLength":1400,"oLanguage":{"sEmptyTable":"The Conference is Empty....."},"fnRowCallback":row_callback});};$.verto.confMan.prototype.modCommand=function(cmd,id,value){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.modChannel,"data":{"application":"conf-control","command":cmd,"id":id,"value":value}});};$.verto.confMan.prototype.sendChat=function(message,type){var confMan=this;confMan.verto.rpcClient.call("verto.broadcast",{"eventChannel":confMan.params.laData.chatChannel,"data":{"action":"send","message":message,"type":type}});};$.verto.confMan.prototype.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} if(confMan.params.laData.chatChannel){confMan.verto.unsubscribe(confMan.params.laData.chatChannel);} if(confMan.params.laData.modChannel){confMan.verto.unsubscribe(confMan.params.laData.modChannel);} -if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:verto.options.deviceParams.useCamera,useMic:verto.options.deviceParams.useMic,useSpeak:verto.options.deviceParams.useSpeak,tag:verto.options.tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=dialog.params.useCamera;dialog.useMic=dialog.params.useMic;dialog.useSpeak=dialog.params.useSpeak;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} +if(confMan.params.mainModID){$(confMan.params.mainModID).html("");}};$.verto.dialog=function(direction,verto,params){var dialog=this;var tag=verto.options.tag;if(typeof(tag)==="function"){tag=tag();} +dialog.params=$.extend({useVideo:verto.options.useVideo,useStereo:verto.options.useStereo,screenShare:false,useCamera:verto.options.deviceParams.useCamera,useMic:verto.options.deviceParams.useMic,useSpeak:verto.options.deviceParams.useSpeak,tag:tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.verto=verto;dialog.direction=direction;dialog.lastState=null;dialog.state=dialog.lastState=$.verto.enum.state.new;dialog.callbacks=verto.callbacks;dialog.answered=false;dialog.attach=params.attach||false;dialog.screenShare=params.screenShare||false;dialog.useCamera=dialog.params.useCamera;dialog.useMic=dialog.params.useMic;dialog.useSpeak=dialog.params.useSpeak;if(dialog.params.callID){dialog.callID=dialog.params.callID;}else{dialog.callID=dialog.params.callID=generateGUID();} if(dialog.params.tag){dialog.audioStream=document.getElementById(dialog.params.tag);if(dialog.params.useVideo){dialog.videoStream=dialog.audioStream;}} if(dialog.params.localTag){dialog.localVideo=document.getElementById(dialog.params.localTag);} dialog.verto.dialogs[dialog.callID]=dialog;var RTCcallbacks={};if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.params.display_direction==="outbound"){dialog.params.remote_caller_id_name=dialog.params.caller_id_name;dialog.params.remote_caller_id_number=dialog.params.caller_id_number;}else{dialog.params.remote_caller_id_name=dialog.params.callee_id_name;dialog.params.remote_caller_id_number=dialog.params.callee_id_number;} @@ -268,7 +270,8 @@ if(!dialog.cause){dialog.cause="NORMAL CLEARING";} if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);} switch(dialog.state){case $.verto.enum.state.early:case $.verto.enum.state.active:var speaker=dialog.useSpeak;console.info("Using Speaker: ",speaker);if(speaker&&speaker!=="any"&&speaker!=="none"){setTimeout(function(){dialog.setAudioPlaybackDevice(speaker);},500);} break;case $.verto.enum.state.trying:setTimeout(function(){if(dialog.state==$.verto.enum.state.trying){dialog.setState($.verto.enum.state.hangup);}},30000);break;case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});} -dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();} +dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:if(typeof(dialog.verto.options.tag)==="function"){$('#'+dialog.params.tag).remove();} +delete dialog.verto.dialogs[dialog.callID];if(dialog.params.screenShare){dialog.rtc.stopPeer();}else{dialog.rtc.stop();} break;} return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();} break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);} diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index f564586fb2..300fb9dcb6 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -3403,7 +3403,7 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans) //switch_core_strdup(pool, val); const switch_codec_implementation_t *codec = NULL; int num_codecs; - num_codecs = switch_loadable_module_get_codecs_sorted(&codec, 1, &val, 1); + num_codecs = switch_loadable_module_get_codecs_sorted(&codec, NULL, 1, &val, 1); if (num_codecs != 1 || !codec) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed finding codec %s for unrestricted digital calls\n", val); diff --git a/libs/libvpx/build/make/configure.sh b/libs/libvpx/build/make/configure.sh index d888268dc8..c8a3291b74 100644 --- a/libs/libvpx/build/make/configure.sh +++ b/libs/libvpx/build/make/configure.sh @@ -317,10 +317,20 @@ EOF } check_cflags() { - log check_cflags "$@" - check_cc -Werror "$@" <src_port.chunk.vendor_id = htons(0x0000); hg->src_port.chunk.type_id = htons(0x0007); - hg->src_port.data = dst ? htons(su->su_port) : htons(su_self->su_port); + hg->src_port.data = dst ? su->su_port : su_self->su_port; hg->src_port.chunk.length = htons(sizeof(hg->src_port)); /* DST PORT */ hg->dst_port.chunk.vendor_id = htons(0x0000); hg->dst_port.chunk.type_id = htons(0x0008); - hg->dst_port.data = dst ? htons(su_self->su_port) : htons(su->su_port); + hg->dst_port.data = dst ? su_self->su_port : su->su_port; hg->dst_port.chunk.length = htons(sizeof(hg->dst_port)); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c index 976a88dede..c872336b0b 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.c @@ -137,7 +137,6 @@ enum { tls_buffer_size = 16384 }; * Log the TLS error specified by the error code @a e and all the errors in * the queue. The error code @a e implies no error, and it is not logged. */ -static void tls_log_errors(unsigned level, char const *s, unsigned long e) { if (e == 0) @@ -449,12 +448,22 @@ int tls_init_context(tls_t *tls, tls_issues_t const *ti) void tls_free(tls_t *tls) { + int ret; if (!tls) return; if (tls->con != NULL) { - SSL_shutdown(tls->con); - SSL_free(tls->con), tls->con = NULL; + do { + ret = SSL_shutdown(tls->con); + if (ret == -1) { + /* The return value -1 means that the connection wasn't actually established */ + /* so it should be safe to not call shutdown again. We need to clear the eror */ + /* queue for other connections though. */ + tls_log_errors(3, "tls_free", 0); + ret = 1; + } + } while (ret != 1); + SSL_free(tls->con), tls->con = NULL; } if (tls->ctx != NULL && tls->type != tls_slave) { @@ -498,13 +507,18 @@ tls_t *tls_init_master(tls_issues_t *ti) RAND_pseudo_bytes(sessionId, sizeof(sessionId)); - SSL_CTX_set_session_id_context(tls->ctx, + if (!SSL_CTX_set_session_id_context(tls->ctx, (void*) sessionId, - sizeof(sessionId)); + sizeof(sessionId))) { + tls_log_errors(3, "tls_init_master", 0); + } - if (ti->CAfile != NULL) + if (ti->CAfile != NULL) { SSL_CTX_set_client_CA_list(tls->ctx, SSL_load_client_CA_file(ti->CAfile)); + if (tls->ctx->client_CA == NULL) + tls_log_errors(3, "tls_init_master", 0); + } #if 0 if (sock != -1) { @@ -576,6 +590,7 @@ int tls_post_connection_check(tport_t *self, tls_t *tls) if (!tls) return -1; if (!(cipher = SSL_get_current_cipher(tls->con))) { + tls_log_errors(3, "tls_post_connection_check", 0); SU_DEBUG_7(("%s(%p): %s\n", __func__, (void*)self, "OpenSSL failed to return an SSL_CIPHER object to us.")); return SSL_ERROR_SSL; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h index 74a8db6a15..e8d04a14b7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_tls.h @@ -83,6 +83,7 @@ tls_t *tls_init_master(tls_issues_t *tls_issues); tls_t *tls_init_secondary(tls_t *tls_master, int sock, int accept); void tls_free(tls_t *tls); int tls_get_socket(tls_t *tls); +void tls_log_errors(unsigned level, char const *s, unsigned long e); ssize_t tls_read(tls_t *tls); void *tls_read_buffer(tls_t *tls, size_t N); int tls_want_read(tls_t *tls, int events); diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c index 8857515cb3..050b2f8364 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_type_ws.c @@ -385,22 +385,37 @@ static int tport_ws_init_primary_secure(tport_primary_t *pri, SSL_CTX_sess_set_remove_cb(wspri->ssl_ctx, NULL); wspri->ws_secure = 1; - if ( !wspri->ssl_ctx ) goto done; + if ( !wspri->ssl_ctx ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } if (chain) { - SSL_CTX_use_certificate_chain_file(wspri->ssl_ctx, chain); + if ( !SSL_CTX_use_certificate_chain_file(wspri->ssl_ctx, chain) ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + } } /* set the local certificate from CertFile */ - SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM); + if ( !SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM) ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } /* set the private key from KeyFile */ - SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM); + if ( !SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM) ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } /* verify private key */ if ( !SSL_CTX_check_private_key(wspri->ssl_ctx) ) { - goto done; + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; } - SSL_CTX_set_cipher_list(wspri->ssl_ctx, "!eNULL:!aNULL:!DSS:HIGH:@STRENGTH"); + if ( !SSL_CTX_set_cipher_list(wspri->ssl_ctx, "!eNULL:!aNULL:!DSS:HIGH:@STRENGTH") ) { + tls_log_errors(3, "tport_ws_init_primary_secure", 0); + goto done; + } ret = tport_ws_init_primary(pri, tpn, ai, tags, return_culprit); diff --git a/libs/spandsp/src/spandsp/g711.h b/libs/spandsp/src/spandsp/g711.h index f722c6067c..62e537acff 100644 --- a/libs/spandsp/src/spandsp/g711.h +++ b/libs/spandsp/src/spandsp/g711.h @@ -50,9 +50,12 @@ specification by other means. #if !defined(_SPANDSP_G711_H_) #define _SPANDSP_G711_H_ +/*! The A-law alternate mark inversion mask */ +#define G711_ALAW_AMI_MASK 0x55 + /* The usual values to use on idle channels, to emulate silence */ /*! Idle value for A-law channels */ -#define G711_ALAW_IDLE_OCTET 0x5D +#define G711_ALAW_IDLE_OCTET (0x80 ^ G711_ALAW_AMI_MASK) /*! Idle value for u-law channels */ #define G711_ULAW_IDLE_OCTET 0xFF @@ -192,9 +195,6 @@ static __inline__ int16_t ulaw_to_linear(uint8_t ulaw) * John Wiley & Sons, pps 98-111 and 472-476. */ -/*! The A-law alternate mark inversion mask */ -#define G711_ALAW_AMI_MASK 0x55 - /*! \brief Encode a linear sample to A-law \param linear The sample to encode. \return The A-law value. diff --git a/scripts/perl/analyze-debug-alloc.pl b/scripts/perl/analyze-debug-alloc.pl new file mode 100755 index 0000000000..fe13092211 --- /dev/null +++ b/scripts/perl/analyze-debug-alloc.pl @@ -0,0 +1,136 @@ +#!/usr/bin/perl + +# analyze-debug-alloc.pl +# generate allocation report by processing log files + +# Note that this script is only useful when run against freeswitch log files +# produced when server is running with DEBUG_ALLOC and DEBUG_ALLOC2 set. +# It's purely for diagnosing memory leaks. + +use strict; +use JSON; + +my $debug = 0; + +my @logs = sort glob("freeswitch.log.*"); +push( @logs, "freeswitch.log" ); + +my %pools = (); + +foreach my $file (@logs) { + open( my $in, "<$file" ); + while ( defined( my $line = <$in> ) ) { + if ( $line =~ /(0x[0-9A-Fa-f]+) DESTROY POOL$/o ) { + my $paddr = $1; + if ( !$pools{$paddr} ) { + $debug && print "WARN: No ref to pool $paddr.\n"; + } + else { + foreach my $alloc ( @{ $pools{$paddr}->{allocs} } ) { + + # debug, might not be needed + } + delete $pools{$paddr}; + } + } + elsif ( $line =~ /(0x[0-9A-Fa-f]+) Free Pool/o ) { + my $paddr = $1; + if ( !$pools{$paddr} ) { + $debug && print "WARN: No ref to pool $paddr.\n"; + } + else { + foreach my $alloc ( @{ $pools{$paddr}->{allocs} } ) { + + # debug, might not be needed + } + delete $pools{$paddr}; + } + } + elsif ( $line =~ /(0x[0-9A-Fa-f]+) New Pool (.*)$/o ) { + my $paddr = $1; + my $where = $2; + if ( $pools{$paddr} ) { + $debug && print "WARN: Duplicate pool $paddr at $where.\n"; + } + $pools{$paddr}->{where} = $where; + if ( !$pools{$paddr}->{allocs} ) { + $pools{$paddr}->{allocs} = []; + } + } + elsif ( $line =~ /CONSOLE\] \s*(.*?:\d+) (0x[0-9A-Fa-f]+) Core Allocate (.*:\d+)\s+(\d+)$/o ) { + my $where = $1; + my $paddr = $2; + my $pwhere = $3; + my $size = $4; + if ( !$pools{$paddr} ) { + $debug && print "WARN: Missing pool ref for alloc of $size from $paddr at $where (pool $pwhere)\n"; + } + $pools{$paddr}->{where} = $where; + push( @{ $pools{$paddr}->{allocs} }, { size => $size, where => $where } ); + } + elsif ( $line =~ /CONSOLE\] \s*(.*?:\d+) (0x[0-9A-Fa-f]+) Core Strdup Allocate (.*:\d+)\s+(\d+)$/o ) { + my $where = $1; + my $paddr = $2; + my $pwhere = $3; + my $size = $4; + if ( !$pools{$paddr} ) { + $debug + && print "WARN: Missing pool ref for strdup alloc of $size from $paddr at $where (pool $pwhere)\n"; + } + $pools{$paddr}->{where} = $where; + push( @{ $pools{$paddr}->{allocs} }, { size => $size, where => $where } ); + } + } +} + +my $used = 0; +my $pcount = 0; +my $acount = 0; +my %pool_cnt_by_where = (); +my %alloc_size_by_where = (); +my %alloc_cnt_by_where = (); +foreach my $pool ( keys %pools ) { + my $where = $pools{$pool}->{where}; + $pcount++; + $pool_cnt_by_where{$where}++; + + foreach my $alloc ( @{ $pools{$pool}->{allocs} } ) { + my $sz = $alloc->{size}; + my $where = $alloc->{where}; + + $acount++; + $alloc_size_by_where{$where} += $sz; + $alloc_cnt_by_where{$where}++; + + $used += $sz; + } +} + +print "Used: $used\n"; +print "Pool Count: $pcount\n"; +print "Alloc Count: $acount\n"; + +my $json = new JSON; +$json->pretty(1); +$json->canonical(1); + +print "Pool Count by Where:\n"; +foreach my $pool ( sort { $pool_cnt_by_where{$a} <=> $pool_cnt_by_where{$b} || $a cmp $b } keys %pool_cnt_by_where ) { + print $pool_cnt_by_where{$pool}, "\t", $pool, "\n"; +} +print "\n"; + +print "Alloc Count by Where:\n"; +foreach my $pool ( sort { $alloc_cnt_by_where{$a} <=> $alloc_cnt_by_where{$b} || $a cmp $b } keys %alloc_cnt_by_where ) +{ + print $alloc_cnt_by_where{$pool}, "\t", $pool, "\n"; +} +print "\n"; + +print "Alloc Size by Where:\n"; +foreach + my $pool ( sort { $alloc_size_by_where{$a} <=> $alloc_size_by_where{$b} || $a cmp $b } keys %alloc_size_by_where ) +{ + print $alloc_size_by_where{$pool}, "\t", $pool, "\n"; +} +print "\n"; diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 0d93ec4d58..6f3b7244a0 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -286,6 +286,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core switch_media_type_t type, const char *iananame, uint32_t rate, + const char *fmtp_in, switch_payload_t *ptP, switch_payload_t *recv_ptP, char **fmtpP); diff --git a/src/include/switch_loadable_module.h b/src/include/switch_loadable_module.h index 54e51d95d6..04cf75d3b7 100644 --- a/src/include/switch_loadable_module.h +++ b/src/include/switch_loadable_module.h @@ -117,7 +117,7 @@ SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoin */ SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name, const char *modname); -SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname); +SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname, char **fmtp); /*! \brief Retrieve the dialplan interface by it's registered name @@ -272,7 +272,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_impleme \return the number of elements added to the array \note this function only considers codecs that are listed in the "prefs" array and ignores the rest. */ -SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, int arraylen, char **prefs, int preflen); +SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen); /*! \brief Execute a registered API command diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index 933c4d3688..962bf972b3 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -279,7 +279,7 @@ typedef intptr_t switch_ssize_t; #endif -#if defined(__sun__) && defined(__x86_64) +#if defined(__sun__) && (defined(__x86_64) || defined(__arch64__)) #define SWITCH_TIME_T_FMT SWITCH_SIZE_T_FMT #else #define SWITCH_TIME_T_FMT SWITCH_INT64_T_FMT diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 3ffae84a4d..8279e10a7f 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -234,6 +234,8 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "5000" #define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "2000" +#define MAX_FMTP_LEN 256 + /* Jitter */ #define JITTER_VARIANCE_THRESHOLD 400.0 /* IPDV */ diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 347ca8f732..7d0ca45815 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1459,6 +1459,8 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo if (context->video_st.st && (error = av_read_frame(context->fc, &pkt)) < 0) { if (error == AVERROR_EOF) { + if (!context->has_video) break; + eof = 1; /* just make sure*/ pkt.data = NULL; diff --git a/src/mod/applications/mod_avmd/avmd_desa2.c b/src/mod/applications/mod_avmd/avmd_desa2.c index abecf6ee64..b1d19eb8ae 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2.c +++ b/src/mod/applications/mod_avmd/avmd_desa2.c @@ -5,8 +5,11 @@ #ifdef WIN32 #include #define ISNAN(x) (!!(_isnan(x))) +#define ISINF(x) (isinf(x)) #else -#define ISNAN(x) (isnan(x)) +int __isnan(double); +#define ISNAN(x) (__isnan(x)) +#define ISINF(x) (__isinf(x)) #endif #include "avmd_buffer.h" #include "avmd_desa2.h" diff --git a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c index 0b75b9eed1..8eae1753f3 100644 --- a/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c +++ b/src/mod/applications/mod_avmd/avmd_desa2_tweaked.c @@ -5,8 +5,11 @@ #ifdef WIN32 #include #define ISNAN(x) (!!(_isnan(x))) +#define ISINF(x) (isinf(x)) #else -#define ISNAN(x) (isnan(x)) +int __isnan(double); +#define ISNAN(x) (__isnan(x)) +#define ISINF(x) (__isinf(x)) #endif #include "avmd_buffer.h" #include "avmd_desa2_tweaked.h" @@ -48,7 +51,7 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i) we do simplified, modified for speed version : */ result = n/d; - if (isinf(result)) { + if (ISINF(result)) { if (n < 0.0) return -10.0; else diff --git a/src/mod/applications/mod_avmd/avmd_options.h b/src/mod/applications/mod_avmd/avmd_options.h index 74498e6512..d5c39368d5 100644 --- a/src/mod/applications/mod_avmd/avmd_options.h +++ b/src/mod/applications/mod_avmd/avmd_options.h @@ -14,40 +14,12 @@ #define __AVMD_OPTIONS_H__ -/* define/undefine this to enable/disable printing of avmd - * intermediate computations to log */ -/*#define AVMD_DEBUG*/ - -/* define/undef this to enable/disable reporting of beep - * detection status after session ended */ -#define AVMD_REPORT_STATUS - /* define/undefine this to enable/disable faster computation * of arcus cosine - table will be created mapping floats * to integers and returning arc cos values given these integer * indices into table */ /* #define AVMD_FAST_MATH */ -/* define/undefine this to classify avmd beep detection as valid - * only when there is required number of consecutive elements - * in the SMA buffer without reset */ -#define AVMD_REQUIRE_CONTINUOUS_STREAK - -/* define number of samples to skip starting from the beginning - * of the frame and after reset */ -#define AVMD_SAMLPE_TO_SKIP_N 6 - -/* define/undefine this to enable/disable simplified estimation - * of frequency based on approximation of sin(x) with (x) - * in the range x=[0,PI/2] */ -#define AVMD_SIMPLIFIED_ESTIMATION - -/* define/undefine to enable/disable avmd on internal channel */ -/*#define AVMD_INBOUND_CHANNEL*/ - -/* define/undefine to enable/disable avmd on external channel */ -#define AVMD_OUTBOUND_CHANNEL - #endif /* __AVMD_OPTIONS_H__ */ diff --git a/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml b/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml index 9d7363c68a..039658cf8d 100644 --- a/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml +++ b/src/mod/applications/mod_avmd/conf/autoload_configs/avmd.conf.xml @@ -38,7 +38,7 @@ - + - + diff --git a/src/mod/applications/mod_osp/docs/mod_osp.txt b/src/mod/applications/mod_osp/docs/mod_osp.txt index a12e718740..fa339bac37 100644 --- a/src/mod/applications/mod_osp/docs/mod_osp.txt +++ b/src/mod/applications/mod_osp/docs/mod_osp.txt @@ -43,7 +43,7 @@ OSP provider parameter names ane values cab be: - http-retry-limit: HTTP retry times. The default is 2. - http-timeout: HTTP timeout. The default is 10000 in ms. - work-mode: OSP module work mode (direct and indirect). The default is "direct". - - service-type: OSP service type (voice and npquery). The default is "voice". + - service-type: OSP service type (voice, npquery and cnamquery (this option has not been implemented)). The default is "voice". - max-destinations: Max destinations OSP server will return. It is up to 12. The default is 12. 3 OSP Applications @@ -54,7 +54,7 @@ The OSP applications are called in dial plan like this: *PROFILE* is an OSP service provider profile name configured in osp.conf.xml. If data attribute is not provided or its value is empty, profile name "default" is used. 3.1 OSPLookup Application -osplookup application does OSP authorization request and gets first supported destination for inbound calls. It exports a set channel variables for FreeSWITCH dial plan logic. +osplookup application does OSP authorization request and gets first supported destination for inbound calls. It exports a set of channel variables for FreeSWITCH dial plan logic. osplookup application accepts two sets of channel variables that are used to pass additional inbound call information and outbound control parameters to OSP module. It also exports a set of channel variables for outbound channels and FreeSWITCH dial plan logic. 3.1.1 Inbound Call Information @@ -64,7 +64,9 @@ osplookup application accepts two sets of channel variables that are used to pas 3.1.2 Outbound Control Parameters - osp_networkid_userparam: The URI user parameter name that is used to present destination network ID. For example, sip:callednumber;networkid=dnid@host. - - osp_networkid_uriparam: The URI parameter name that is used to present destination network ID. For example, sip:callednumber @host;networkid=dnid. + - osp_networkid_uriparam: The URI parameter name that is used to present destination network ID. For example, sip:callednumber@host;networkid=dnid. + - osp_outstring_userparam: The URI user parameter string. For example, sip:callednumber;outstring@host. + - osp_outstring_uriparam: The URI parameter string. For example, sip:callednumber@host;outstring. - osp_user_phone: Flag to add "user=phone" URI parameter. The default is "disabled". - osp_outbound_proxy: Outbound proxy IP address channel variable. @@ -79,7 +81,7 @@ osplookup application accepts two sets of channel variables that are used to pas - osp_termiation_cause: Destination termination cause. It will be used by ospnext application and OSP module state handlers. 3.2 OSPNext Application -ospnext application gets next supported destination for inbound calls. It exports a set channel variables for FreeSWITCH dial plan logic. +ospnext application gets next supported destination for inbound calls. It exports a set of channel variables for FreeSWITCH dial plan logic. ospnext application accepts a set of channel variables exported by osplookup application to pass OSP call transaction information to OSP module. It also exports a set of channel variables for outbound channels and FreeSWITCH dial plan logic. 3.2.1 Transaction Parameters @@ -157,7 +159,7 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + @@ -176,15 +178,14 @@ OSP module state handler accepts a set of channel variables exported by osplooku - @@ -206,27 +207,68 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + + - - + - + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -265,10 +307,18 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + + + + + + + - + @@ -283,7 +333,9 @@ OSP module state handler accepts a set of channel variables exported by osplooku - + diff --git a/src/mod/applications/mod_osp/mod_osp.c b/src/mod/applications/mod_osp/mod_osp.c index 19ea56e399..693d240826 100644 --- a/src/mod/applications/mod_osp/mod_osp.c +++ b/src/mod/applications/mod_osp/mod_osp.c @@ -34,6 +34,8 @@ #include #include +#define OSP_FREESWITCH "freeswitch" /* FreeSWITCH */ + /* OSP Buffer Size Constants */ #define OSP_SIZE_NORSTR 512 /* OSP normal string buffer size */ #define OSP_SIZE_KEYSTR 1024 /* OSP certificate string buffer size */ @@ -64,18 +66,22 @@ /* OSP Handle Constant */ #define OSP_INVALID_HANDLE -1 /* Invalid OSP handle, provider, transaction etc. */ -/* OSP Provider Contants */ +/* OSP Provider Constants */ #define OSP_AUDIT_URL "localhost" /* OSP default Audit URL */ #define OSP_LOCAL_VALID 1 /* OSP token validating method, locally */ #define OSP_CUSTOMER_ID "" /* OSP customer ID */ #define OSP_DEVICE_ID "" /* OSP device ID */ -/* URI Contants */ -#define OSP_URI_DELIM '@' /* URI delimit */ -#define OSP_USER_DELIM ";:" /* URI userinfo delimit */ -#define OSP_HOST_DELIM ";>" /* URI hostport delimit */ +/* URI/SDP Constants */ +#define OSP_URI_DELIM '@' /* URI delimiter */ +#define OSP_USER_DELIM ";:" /* URI userinfo delimiter */ +#define OSP_HOST_DELIM ";>" /* URI hostport delimiter */ +#define OSP_SDP_DELIM '\r' /* SDP line delimiter */ +#define OSP_IP_DELIM '/' /* SDP multicast address delimiter */ +#define OSP_SDP_CHEADER "c=IN IP4 " /* SDP connection line header */ +#define OSP_CHEADER_SIZE 9 /* SDP connection line header length */ -/* OSP Module Other Contants */ +/* OSP Module Other Constants */ #define OSP_MAX_CINFO 8 /* Max number of custom info */ #define OSP_DEF_STRING "" /* OSP default empty string */ #define OSP_DEF_STATS -1 /* OSP default statistics */ @@ -101,6 +107,8 @@ #define OSP_VAR_CUSTOMINFO "osp_custom_info_" /* Custom info, inbound */ #define OSP_VAR_DNIDUSERPARAM "osp_networkid_userparam" /* Destination network ID user parameter name, outbound */ #define OSP_VAR_DNIDURIPARAM "osp_networkid_uriparam" /* Destination network ID URI parameter name, outbound */ +#define OSP_VAR_OUTUSERPARAM "osp_outstring_userparam" /* Fixed outbound parameter string user parameter, outbound */ +#define OSP_VAR_OUTURIPARAM "osp_outstring_uriparam" /* Fixed outbound parameter string URI parameter, outbound */ #define OSP_VAR_USERPHONE "osp_user_phone" /* If to add "user=phone", outbound */ #define OSP_VAR_OUTPROXY "osp_outbound_proxy" /* Outbound proxy, outbound */ #define OSP_VAR_PROFILE "osp_profile_name" /* Profile name */ @@ -108,13 +116,15 @@ #define OSP_VAR_TRANSID "osp_transaction_id" /* Transaction ID */ #define OSP_VAR_ROUTETOTAL "osp_route_total" /* Total number of destinations */ #define OSP_VAR_ROUTECOUNT "osp_route_count" /* Destination count */ -#define OSP_VAR_TCCODE "osp_termination_cause" /* Terimation cause */ +#define OSP_VAR_TCCODE "osp_termination_cause" /* Termination cause */ #define OSP_VAR_AUTOROUTE "osp_auto_route" /* Bridge route string */ #define OSP_VAR_LOOKUPSTATUS "osp_lookup_status" /* OSP lookup function status */ #define OSP_VAR_NEXTSTATUS "osp_next_status" /* OSP next function status */ /* OSP Using FreeSWITCH Variable Names */ +#define OSP_FS_SIPLOCALIP "sip_local_network_addr" /* Inbound SIP local IP */ #define OSP_FS_CALLID "sip_call_id" /* Inbound SIP Call-ID */ +#define OSP_FS_FROMDISPLAY "sip_from_display" /* Inbound SIP From display name */ #define OSP_FS_FROMUSER "sip_from_user" /* Inbound SIP From user */ #define OSP_FS_TOHOST "sip_to_host" /* Inbound SIP To host */ #define OSP_FS_TOPORT "sip_to_port" /* Inbound SIP To port */ @@ -122,15 +132,20 @@ #define OSP_FS_PAI "sip_P-Asserted-Identity" /* Inbound SIP P-Asserted-Identity header */ #define OSP_FS_DIV "sip_h_Diversion" /* Inbound SIP Diversion header */ #define OSP_FS_PCI "sip_h_P-Charge-Info" /* Inbound SIP P-Charge-Info header */ +#define OSP_FS_USERAGENT "sip_user_agent" /* Inbound SIP User-Agent header */ +#define OSP_FS_RURIUSERPARAM "sip_invite_tel_params" /* Outbound RURI user parameter */ +#define OSP_FS_RURIURIPARAM "sip_invite_params" /* Outbound RURI URI parameter */ #define OSP_FS_OUTCALLING "origination_caller_id_number" /* Outbound calling number */ +#define OSP_FS_HANGUPCAUSE "last_bridge_hangup_cause" /* Termination cause */ +#define OSP_FS_BLEGPREFIX "Other-Leg" /* Originatee variable prefix */ +#define OSP_FS_BLEGSTART "Other-Leg-Channel-Created-Time" /* Usage B-leg start time */ #define OSP_FS_SIPRELEASE "sip_hangup_disposition" /* Usage SIP release source */ #define OSP_FS_SRCCODEC "write_codec" /* Usage source codec */ -#define OSP_FS_DESTCODEC "read_codec" /* Usage destiantion codec */ -#define OSP_FS_RTPSRCREPOCTS "rtp_audio_out_media_bytes" /* Usage source->reporter octets */ -#define OSP_FS_RTPDESTREPOCTS "rtp_audio_in_media_bytes" /* Usage destination->reporter octets */ -#define OSP_FS_RTPSRCREPPKTS "rtp_audio_out_media_packet_count" /* Usage source->reporter packets */ -#define OSP_FS_RTPDESTREPPKTS "rtp_audio_in_media_packet_count" /* Usage destination->reporter packets */ -#define OSP_FS_HANGUPCAUSE "last_bridge_hangup_cause" /* Termination cause */ +#define OSP_FS_DESTCODEC "read_codec" /* Usage destination codec */ +#define OSP_FS_SRCSDP SWITCH_R_SDP_VARIABLE /* Usage source SDP */ +#define OSP_FS_DESTSDP SWITCH_B_SDP_VARIABLE /* Usage destination SDP */ +#define OSP_FS_RTPINOCTS "rtp_audio_in_media_bytes" /* Usage in octets (A-leg downstream or B-leg upstream) */ +#define OSP_FS_RTPINPKTS "rtp_audio_in_media_packet_count" /* Usage in packets (A-leg downstream or B-leg upstream)*/ /* FreeSWITCH Endpoint Parameters */ typedef struct osp_endpoint { @@ -158,7 +173,8 @@ typedef enum osp_workmode { /* OSP Service Types */ typedef enum osp_srvtype { OSP_SRV_VOICE = 0, /* Normal voice service */ - OSP_SRV_NPQUERY /* Number portability query service */ + OSP_SRV_NPQUERY, /* Number portability query service */ + OSP_SRV_CNAMQUERY /* CNAM query service */ } osp_srvtype_t; /* OSP Profile Parameters */ @@ -194,11 +210,13 @@ typedef struct osp_inbound { int npdi; /* Inbound NP database dip indicator */ const char *tohost; /* Inbound host of To URI */ const char *toport; /* Inbound port of To URI */ + const char *fromdisplay; /* Inbound display name of From header */ char rpiduser[OSP_SIZE_NORSTR]; /* Inbound user of SIP Remote-Party-ID header */ char paiuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP P-Asserted-Identity header */ + char pciuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP P-Charge-Info header */ char divuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP Diversion header */ char divhost[OSP_SIZE_NORSTR]; /* Inbound hostport of SIP Diversion header */ - char pciuser[OSP_SIZE_NORSTR]; /* Inbound user of SIP P-Charge-Info header */ + const char *useragent; /* Inbound User-Agent header */ const char *cinfo[OSP_MAX_CINFO]; /* Custom info */ } osp_inbound_t; @@ -218,6 +236,7 @@ typedef struct osp_results { char npcic[OSP_SIZE_NORSTR]; /* Outbound NP carrier identification code */ int npdi; /* Outbound NP database dip indicator */ char opname[OSPC_OPNAME_NUMBER][OSP_SIZE_NORSTR]; /* Outbound Operator names */ + char cnam[OSP_SIZE_NORSTR]; /* CNAM */ OSPE_PROTOCOL_NAME protocol; /* Signaling protocol */ switch_bool_t supported; /* Supported by FreeRADIUS OSP module */ switch_call_cause_t cause; /* Termination cause for current destination */ @@ -227,33 +246,52 @@ typedef struct osp_results { typedef struct osp_outbound { const char *dniduserparam; /* Destination network ID user parameter name */ const char *dniduriparam; /* Destination network ID URI parameter name */ + const char *outuserparam; /* Fixed outbound parameter string user parameter */ + const char *outuriparam; /* Fixed outbound parameter string URI parameter */ switch_bool_t userphone; /* If to add "user=phone" parameter */ const char *outproxy; /* Outbound proxy IP address */ } osp_outbound_t; /* OSP Usage Parameters */ typedef struct osp_usage { - OSPE_RELEASE release; /* Release source */ - switch_call_cause_t cause; /* Termination cause */ - switch_time_t start; /* Call start time */ - switch_time_t alert; /* Call alert time */ - switch_time_t connect; /* Call answer time */ - switch_time_t end; /* Call end time */ - switch_time_t duration; /* Call duration */ - switch_time_t pdd; /* Post dial delay, in us */ - const char *srccodec; /* Source codec */ - const char *destcodec; /* Destination codec */ - int rtpsrcrepoctets; /* RTP source->reporter bytes */ - int rtpdestrepoctets; /* RTP destination->reporter bytes */ - int rtpsrcreppackets; /* RTP source->reporter packets */ - int rtpdestreppackets; /* RTP destiantion->reporter packets */ + OSPE_RELEASE release; /* Release source */ + switch_call_cause_t cause; /* Termination cause */ + switch_time_t start; /* Call start time */ + switch_time_t alert; /* Call alert time */ + switch_time_t connect; /* Call answer time */ + switch_time_t end; /* Call end time */ + switch_time_t duration; /* Call duration */ + switch_time_t pdd; /* Post dial delay, in us */ + switch_time_t pstart; /* Provider call start time */ + switch_time_t ppdd; /* Provider post dial delay, in us */ + const char *localip; /* FreeSWITCH local signal address */ + char srcmediaip[OSP_SIZE_NORSTR]; /* Source media IP */ + char destmediaip[OSP_SIZE_NORSTR]; /* Source media IP */ + const char *srccodec; /* Source codec */ + const char *destcodec; /* Destination codec */ + int rtpsrcrepoctets; /* RTP source->reporter bytes */ + int rtpsrcreppackets; /* RTP source->reporter packets */ } osp_usage_t; -/* Macro functions for debug */ -#define OSP_DEBUG(_fmt, ...) if (osp_global.debug) { switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__); } -#define OSP_DEBUG_MSG(_msg) OSP_DEBUG("%s", _msg) -#define OSP_DEBUG_START OSP_DEBUG_MSG("Start") -#define OSP_DEBUG_END OSP_DEBUG_MSG("End") +/* Macro functions for log */ +/* Normal log */ +#define OSP_DEBUG(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_INFO(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_NOTICE(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_WARN(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_ERROR(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_CRIT(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +#define OSP_ALERT(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +/* Normal OSP log */ +#define OSP_LOG(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) +/* OSP debug log */ +#define OSP_TEST(_fmt, ...) if (osp_global.debug) { switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__); } +#define OSP_TEST_MSG(_msg) OSP_TEST("%s", _msg) +#define OSP_TEST_START OSP_TEST_MSG("Start") +#define OSP_TEST_END OSP_TEST_MSG("End") +/* OSP develop log */ +#define OSP_DEV(_fmt, ...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "%s: "_fmt"\n", __SWITCH_FUNC__, __VA_ARGS__) + /* Macro to prevent NULL string */ #define OSP_FILTER_NULLSTR(_str) (switch_strlen_zero(_str) ? OSP_DEF_STRING : (_str)) /* Macro to prevent NULL integer */ @@ -285,7 +323,7 @@ static switch_status_t osp_find_profile( osp_profile_t *p; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; if (name) { if (profile) { @@ -304,12 +342,12 @@ static switch_status_t osp_find_profile( } if (status == SWITCH_STATUS_SUCCESS) { - OSP_DEBUG("Found profile '%s'", name); + OSP_TEST("Found profile '%s'", name); } else { - OSP_DEBUG("Unable to find profile '%s'", name); + OSP_TEST("Unable to find profile '%s'", name); } - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -331,16 +369,16 @@ static switch_status_t osp_load_config( int number; switch_status_t status = SWITCH_STATUS_SUCCESS; - OSP_DEBUG_START; + OSP_TEST_START; /* Load OSP module configuration file */ if (!(xml = switch_xml_open_cfg(OSP_CONFIG_FILE, &xcfg, NULL))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open OSP module configuration file '%s'\n", OSP_CONFIG_FILE); - OSP_DEBUG_END; + OSP_ERROR("Failed to open OSP module configuration file '%s'", OSP_CONFIG_FILE); + OSP_TEST_END; return SWITCH_STATUS_FALSE; } - OSP_DEBUG_MSG("Parsing settings"); + OSP_TEST_MSG("Parsing settings"); /* Init OSP module global status */ memset(&osp_global, 0, sizeof(osp_global)); @@ -370,7 +408,7 @@ static switch_status_t osp_load_config( if (!switch_strlen_zero(value)) { osp_global.debug = switch_true(value); } - OSP_DEBUG("debug-info: '%d'", osp_global.debug); + OSP_TEST("debug-info: '%d'", osp_global.debug); } else if (!strcasecmp(name, "log-level")) { /* OSP module debug message log level */ if (switch_strlen_zero(value)) { @@ -392,13 +430,13 @@ static switch_status_t osp_load_config( } else if (!strcasecmp(value, "debug")) { osp_global.loglevel = SWITCH_LOG_DEBUG; } - OSP_DEBUG("log-level: '%d'", osp_global.loglevel); + OSP_TEST("log-level: '%d'", osp_global.loglevel); } else if (!strcasecmp(name, "crypto-hardware")) { /* OSP module crypto hardware flag */ if (!switch_strlen_zero(value)) { osp_global.hardware = switch_true(value); } - OSP_DEBUG("crypto-hardware: '%d'", osp_global.hardware); + OSP_TEST("crypto-hardware: '%d'", osp_global.hardware); } else if (!strcasecmp(name, "default-protocol")) { /* OSP module default signaling protocol */ if (switch_strlen_zero(value)) { @@ -412,14 +450,14 @@ static switch_status_t osp_load_config( } else if (!strcasecmp(value, OSP_PROTOCOL_SKYPE)) { osp_global.protocol = OSPC_PROTNAME_SKYPE; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported protocol '%s'\n", value); + OSP_WARN("Unsupported protocol '%s'", value); } - OSP_DEBUG("default-protocol: '%d'", osp_global.protocol); + OSP_TEST("default-protocol: '%d'", osp_global.protocol); } else if (!strcasecmp(name, OSP_PROTOCOL_SIP)) { /* SIP endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SIP].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate SIP module name\n"); + OSP_CRIT("%s", "Failed to duplicate SIP module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -427,17 +465,17 @@ static switch_status_t osp_load_config( /* SIP endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SIP].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate SIP profile name\n"); + OSP_CRIT("%s", "Failed to duplicate SIP profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("SIP: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile); + OSP_TEST("SIP: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile); } else if (!strcasecmp(name, OSP_PROTOCOL_H323)) { /* H.323 endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_Q931].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate H.323 module name\n"); + OSP_CRIT("%s", "Failed to duplicate H.323 module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -445,17 +483,17 @@ static switch_status_t osp_load_config( /* H.323 endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_Q931].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate H.323 profile name\n"); + OSP_CRIT("%s", "Failed to duplicate H.323 profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("H.323: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_Q931].module, osp_global.endpoint[OSPC_PROTNAME_Q931].profile); + OSP_TEST("H.323: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_Q931].module, osp_global.endpoint[OSPC_PROTNAME_Q931].profile); } else if (!strcasecmp(name, OSP_PROTOCOL_IAX)) { /* IAX endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_IAX].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate IAX module name\n"); + OSP_CRIT("%s", "Failed to duplicate IAX module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -463,17 +501,17 @@ static switch_status_t osp_load_config( /* IAX endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_IAX].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate IAX profile name\n"); + OSP_CRIT("%s", "Failed to duplicate IAX profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("IAX: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_IAX].module, osp_global.endpoint[OSPC_PROTNAME_IAX].profile); + OSP_TEST("IAX: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_IAX].module, osp_global.endpoint[OSPC_PROTNAME_IAX].profile); } else if (!strcasecmp(name, OSP_PROTOCOL_SKYPE)) { /* Skype endpoint module */ if (!switch_strlen_zero(module)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SKYPE].module = switch_core_strdup(osp_global.pool, module))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate Skype module name\n"); + OSP_CRIT("%s", "Failed to duplicate Skype module name"); status = SWITCH_STATUS_MEMERR; break; } @@ -481,14 +519,14 @@ static switch_status_t osp_load_config( /* Skype endpoint profile */ if (!switch_strlen_zero(context)) { if (!(osp_global.endpoint[OSPC_PROTNAME_SKYPE].profile = switch_core_strdup(osp_global.pool, context))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate Skype profile name\n"); + OSP_CRIT("%s", "Failed to duplicate Skype profile name"); status = SWITCH_STATUS_MEMERR; break; } } - OSP_DEBUG("SKYPE: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SKYPE].module, osp_global.endpoint[OSPC_PROTNAME_SKYPE].profile); + OSP_TEST("SKYPE: '%s/%s'", osp_global.endpoint[OSPC_PROTNAME_SKYPE].module, osp_global.endpoint[OSPC_PROTNAME_SKYPE].profile); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter '%s'\n", name); + OSP_WARN("Unknown parameter '%s'", name); } } } @@ -496,7 +534,7 @@ static switch_status_t osp_load_config( if (status != SWITCH_STATUS_SUCCESS) { /* Fail for SWITCH_STATUS_MEMERR */ switch_xml_free(xml); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -508,24 +546,24 @@ static switch_status_t osp_load_config( if (switch_strlen_zero(name)) { name = OSP_DEF_PROFILE; } - OSP_DEBUG("Parsing profile '%s'", name); + OSP_TEST("Parsing profile '%s'", name); - /* Check duplate profile name */ + /* Check duplicate profile name */ if (osp_find_profile(name, NULL) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored duplicate profile '%s'\n", name); + OSP_WARN("Ignored duplicate profile '%s'", name); continue; } /* Allocate profile */ if (!(profile = switch_core_alloc(osp_global.pool, sizeof(*profile)))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to alloc profile\n"); + OSP_CRIT("%s", "Failed to allocate profile"); status = SWITCH_STATUS_MEMERR; break; } /* Store profile name */ if (!(profile->name = switch_core_strdup(osp_global.pool, name))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate profile name\n"); + OSP_CRIT("%s", "Failed to duplicate profile name"); status = SWITCH_STATUS_MEMERR; /* "profile" cannot free to pool in FreeSWITCH */ break; @@ -556,63 +594,63 @@ static switch_status_t osp_load_config( /* OSP service point URL */ if (profile->spnumber < OSP_MAX_SPNUMBER) { profile->spurl[profile->spnumber] = switch_core_strdup(osp_global.pool, value); - OSP_DEBUG("service-point-url[%d]: '%s'", profile->spnumber, profile->spurl[profile->spnumber]); + OSP_TEST("service-point-url[%d]: '%s'", profile->spnumber, profile->spurl[profile->spnumber]); profile->spnumber++; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored service point '%s'\n", value); + OSP_WARN("Ignored service point '%s'", value); } } else if (!strcasecmp(name, "device-ip")) { /* OSP client end IP */ profile->deviceip = switch_core_strdup(osp_global.pool, value); - OSP_DEBUG("device-ip: '%s'", profile->deviceip); + OSP_TEST("device-ip: '%s'", profile->deviceip); } else if (!strcasecmp(name, "ssl-lifetime")) { /* SSL lifetime */ if (sscanf(value, "%d", &number) == 1) { profile->lifetime = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ssl-lifetime must be a number\n"); + OSP_WARN("%s", "ssl-lifetime must be a number"); } - OSP_DEBUG("ssl-lifetime: '%d'", profile->lifetime); + OSP_TEST("ssl-lifetime: '%d'", profile->lifetime); } else if (!strcasecmp(name, "http-max-connections")) { /* HTTP max connections */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_MAXCONN) && (number <= OSP_MAX_MAXCONN)) { profile->maxconnect = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-max-connections must be between %d and %d\n", OSP_MIN_MAXCONN, OSP_MAX_MAXCONN); + OSP_WARN("http-max-connections must be between %d and %d", OSP_MIN_MAXCONN, OSP_MAX_MAXCONN); } - OSP_DEBUG("http-max-connections: '%d'", profile->maxconnect); + OSP_TEST("http-max-connections: '%d'", profile->maxconnect); } else if (!strcasecmp(name, "http-persistence")) { /* HTTP persistence */ if (sscanf(value, "%d", &number) == 1) { profile->persistence = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-persistence must be a number\n"); + OSP_WARN("%s", "http-persistence must be a number"); } - OSP_DEBUG("http-persistence: '%d'", profile->persistence); + OSP_TEST("http-persistence: '%d'", profile->persistence); } else if (!strcasecmp(name, "http-retry-delay")) { /* HTTP retry delay */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_RETRYDELAY) && (number <= OSP_MAX_RETRYDELAY)) { profile->retrydelay = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-retry-delay must be between %d and %d\n", OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY); + OSP_WARN("http-retry-delay must be between %d and %d", OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY); } - OSP_DEBUG("http-retry-delay: '%d'", profile->retrydelay); + OSP_TEST("http-retry-delay: '%d'", profile->retrydelay); } else if (!strcasecmp(name, "http-retry-limit")) { /* HTTP retry limit */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_RETRYLIMIT) && (number <= OSP_MAX_RETRYLIMIT)) { profile->retrylimit = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-retry-limit must be between %d and %d\n", OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT); + OSP_WARN("http-retry-limit must be between %d and %d", OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT); } - OSP_DEBUG("http-retry-limit: '%d'", profile->retrylimit); + OSP_TEST("http-retry-limit: '%d'", profile->retrylimit); } else if (!strcasecmp(name, "http-timeout")) { /* HTTP timeout value */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_TIMEOUT) && (number <= OSP_MAX_TIMEOUT)) { profile->timeout = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-timeout must be between %d and %d\n", OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT); + OSP_WARN("http-timeout must be between %d and %d", OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT); } - OSP_DEBUG("http-timeout: '%d'", profile->timeout); + OSP_TEST("http-timeout: '%d'", profile->timeout); } else if (!strcasecmp(name, "work-mode")) { /* OSP work mode */ if (!strcasecmp(value, "direct")) { @@ -620,35 +658,39 @@ static switch_status_t osp_load_config( } else if (!strcasecmp(value, "indirect")) { profile->workmode = OSP_MODE_INDIRECT; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown work mode '%s'\n", value); + OSP_WARN("Unknown work mode '%s'", value); } - OSP_DEBUG("work-mode: '%d'", profile->workmode); + OSP_TEST("work-mode: '%d'", profile->workmode); } else if (!strcasecmp(name, "service-type")) { /* OSP service type */ if (!strcasecmp(value, "voice")) { profile->srvtype = OSP_SRV_VOICE; } else if (!strcasecmp(value, "npquery")) { profile->srvtype = OSP_SRV_NPQUERY; + } else if (!strcasecmp(value, "cnamquery")) { + // Have not been implemented + // profile->srvtype = OSP_SRV_CNAMQUERY; + OSP_WARN("Unsupported service type '%s'", value); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown service type '%s'\n", value); + OSP_WARN("Unknown service type '%s'", value); } - OSP_DEBUG("service-type: '%d'", profile->srvtype); + OSP_TEST("service-type: '%d'", profile->srvtype); } else if (!strcasecmp(name, "max-destinations")) { /* Max destinations */ if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_MAXDEST) && (number <= OSP_MAX_MAXDEST)) { profile->maxdest = number; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "max-destinations must be between %d and %d\n", OSP_MIN_MAXDEST, OSP_MAX_MAXDEST); + OSP_WARN("max-destinations must be between %d and %d", OSP_MIN_MAXDEST, OSP_MAX_MAXDEST); } - OSP_DEBUG("max-destinations: '%d'", profile->maxdest); + OSP_TEST("max-destinations: '%d'", profile->maxdest); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter '%s'\n", name); + OSP_WARN("Unknown parameter '%s'", name); } } - /* Check number of service porints */ + /* Check number of service points */ if (!profile->spnumber) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Without service point URI in profile '%s'\n", profile->name); + OSP_WARN("Without service point URI in profile '%s'", profile->name); /* "profile" cannot free to pool in FreeSWITCH */ continue; } @@ -660,7 +702,7 @@ static switch_status_t osp_load_config( switch_xml_free(xml); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -681,13 +723,13 @@ static void osp_init_osptk(void) unsigned char cacertdata[OSP_SIZE_KEYSTR]; int error; - OSP_DEBUG_START; + OSP_TEST_START; /* Init OSP Toolkit */ if (osp_global.hardware) { if ((error = OSPPInit(OSPC_TRUE)) != OSPC_ERR_NO_ERROR) { /* Unable to enable crypto hardware, disable it */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to enable crypto hardware, error '%d'\n", error); + OSP_WARN("Unable to enable crypto hardware, error '%d'", error); osp_global.hardware = SWITCH_FALSE; OSPPInit(OSPC_FALSE); } @@ -708,11 +750,11 @@ static void osp_init_osptk(void) cacert.CertDataLength = sizeof(cacertdata); if ((error = OSPPBase64Decode(B64PKey, strlen(B64PKey), privatekey.PrivateKeyData, &privatekey.PrivateKeyLength)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to decode private key, error '%d'\n", error); + OSP_WARN("Unable to decode private key, error '%d'", error); } else if ((error = OSPPBase64Decode(B64LCert, strlen(B64LCert), localcert.CertData, &localcert.CertDataLength)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to decode local cert, error '%d'\n", error); + OSP_WARN("Unable to decode local cert, error '%d'", error); } else if ((error = OSPPBase64Decode(B64CACert, strlen(B64CACert), cacert.CertData, &cacert.CertDataLength)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to decode cacert, error '%d'\n", error); + OSP_WARN("Unable to decode cacert, error '%d'", error); } if (error == OSPC_ERR_NO_ERROR) { @@ -722,7 +764,7 @@ static void osp_init_osptk(void) profile->spurl, /* Service point URLs */ NULL, /* Weights */ OSP_AUDIT_URL, /* Audit URL */ - &privatekey, /* Provate key */ + &privatekey, /* Private key */ &localcert, /* Local cert */ 1, /* Number of cacerts */ &pcacert, /* cacerts */ @@ -737,15 +779,15 @@ static void osp_init_osptk(void) OSP_DEVICE_ID, /* Device ID */ &profile->provider); /* Provider handle */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to create provider for profile %s, error '%d'\n", profile->name, error); + OSP_WARN("Unable to create provider for profile %s, error '%d'", profile->name, error); profile->provider = OSP_INVALID_HANDLE; } else { - OSP_DEBUG("Created provider handle for profile '%s'", profile->name); + OSP_TEST("Created provider handle for profile '%s'", profile->name); } } } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -756,21 +798,21 @@ static void osp_cleanup_osptk(void) { osp_profile_t *profile; - OSP_DEBUG_START; + OSP_TEST_START; for (profile = osp_profiles; profile; profile = profile->next) { if (profile->provider != OSP_INVALID_HANDLE) { /* Delete provider handle */ OSPPProviderDelete(profile->provider, 0); profile->provider = OSP_INVALID_HANDLE; - OSP_DEBUG("Deleted provider handle for profile '%s'", profile->name); + OSP_TEST("Deleted provider handle for profile '%s'", profile->name); } } /* Cleanup OSP Toolkit */ OSPPCleanup(); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -783,7 +825,7 @@ static const char *osp_get_protocolname( { const char *name; - OSP_DEBUG_START; + OSP_TEST_START; switch (protocol) { case OSPC_PROTNAME_UNKNOWN: @@ -814,9 +856,9 @@ static const char *osp_get_protocolname( name = OSP_PROTOCOL_UNSUP; break; } - OSP_DEBUG("Protocol %d: '%s'", protocol, name); + OSP_TEST("Protocol %d: '%s'", protocol, name); - OSP_DEBUG_END; + OSP_TEST_END; return name; } @@ -831,7 +873,7 @@ static OSPE_PROTOCOL_NAME osp_get_protocol( { OSPE_PROTOCOL_NAME protocol; - OSP_DEBUG_START; + OSP_TEST_START; if (!strcasecmp(module, OSP_MODULE_SIP)) { protocol = OSPC_PROTNAME_SIP; @@ -844,9 +886,9 @@ static OSPE_PROTOCOL_NAME osp_get_protocol( } else { protocol = OSPC_PROTNAME_UNKNOWN; } - OSP_DEBUG("Module %s: '%d'", module, protocol); + OSP_TEST("Module %s: '%d'", module, protocol); - OSP_DEBUG_END; + OSP_TEST_END; return protocol; } @@ -877,7 +919,7 @@ static void osp_parse_userinfo( char *item; char *tmp; - OSP_DEBUG_START; + OSP_TEST_START; /* Set default values */ if (user && usersize) { @@ -925,12 +967,12 @@ static void osp_parse_userinfo( } } - OSP_DEBUG("user: '%s'", OSP_FILTER_NULLSTR(user)); - OSP_DEBUG("rn: '%s'", OSP_FILTER_NULLSTR(rn)); - OSP_DEBUG("cic: '%s'", OSP_FILTER_NULLSTR(cic)); - OSP_DEBUG("npdi: '%d'", OSP_FILTER_NULLINT(npdi)); + OSP_TEST("user: '%s'", OSP_FILTER_NULLSTR(user)); + OSP_TEST("rn: '%s'", OSP_FILTER_NULLSTR(rn)); + OSP_TEST("cic: '%s'", OSP_FILTER_NULLSTR(cic)); + OSP_TEST("npdi: '%d'", OSP_FILTER_NULLINT(npdi)); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -950,7 +992,7 @@ static void osp_parse_header_user( char *tmp; char *item; - OSP_DEBUG_START; + OSP_TEST_START; if (user && usersize) { user[0] = '\0'; @@ -970,10 +1012,10 @@ static void osp_parse_header_user( } } - OSP_DEBUG("user: '%s'", user); + OSP_TEST("user: '%s'", user); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -992,7 +1034,7 @@ static void osp_parse_header_host( char *head; char *tmp; - OSP_DEBUG_START; + OSP_TEST_START; if (hostsize) { host[0] = '\0'; @@ -1012,10 +1054,10 @@ static void osp_parse_header_host( } } - OSP_DEBUG("host: '%s'", host); + OSP_TEST("host: '%s'", host); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1034,7 +1076,7 @@ static void osp_convert_inout( char buffer[OSP_SIZE_NORSTR]; char *port; - OSP_DEBUG_START; + OSP_TEST_START; if (dest && destsize) { dest[0] = '\0'; @@ -1054,16 +1096,15 @@ static void osp_convert_inout( } else { switch_snprintf(dest, destsize, "[%s]", buffer); } - dest[destsize - 1] = '\0'; } else { switch_copy_string(dest, src, destsize); } } - OSP_DEBUG("out: '%s'", dest); + OSP_TEST("out: '%s'", dest); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1082,7 +1123,7 @@ static void osp_convert_outin( char *end; char *port; - OSP_DEBUG_START; + OSP_TEST_START; if (dest && destsize) { dest[0] = '\0'; @@ -1102,7 +1143,6 @@ static void osp_convert_outin( if (port) { switch_snprintf(dest, destsize, "%s:%s", buffer + 1, port); - dest[destsize - 1] = '\0'; } else { switch_copy_string(dest, buffer + 1, destsize); } @@ -1110,10 +1150,52 @@ static void osp_convert_outin( switch_copy_string(dest, src, destsize); } } - OSP_DEBUG("in: '%s'", dest); + OSP_TEST("in: '%s'", dest); } - OSP_DEBUG_END; + OSP_TEST_END; +} + +/* + * Get SDP connection IP + * param sdp SDP string + */ +static void osp_get_mediaip( + const char *sdp, + char *ip, + int ipsize) +{ + char *start; + char *end; + int size; + + OSP_TEST_START; + + if (ip && ipsize) { + ip[0] = '\0'; + + if (!switch_strlen_zero(sdp)) { + start = strstr(sdp, OSP_SDP_CHEADER); + if (start) { + start += OSP_CHEADER_SIZE; + end = strchr(start, OSP_SDP_DELIM); + if (end) { + size = end - start + 1; + } else { + size = ipsize; + } + switch_snprintf(ip, size, "%s", start); + + end = strchr(ip, OSP_IP_DELIM); + if (end) { + *end = '\0'; + } + } + } + OSP_TEST("ip: '%s'", ip); + } + + OSP_TEST_END; } /* @@ -1132,7 +1214,7 @@ static void osp_log_authreq( char term[OSP_SIZE_NORSTR]; int total; - OSP_DEBUG_START; + OSP_TEST_START; /* Get source device and source */ if (profile->workmode == OSP_MODE_INDIRECT) { @@ -1147,9 +1229,11 @@ static void osp_log_authreq( srcdev = inbound->srcdev; } - /* Get preferred destination for NP query */ - if (profile->srvtype == OSP_SRV_NPQUERY) { - srvtype = "npquery"; + /* Get preferred destination for NP/CNAM query */ + switch (profile->srvtype) { + case OSP_SRV_NPQUERY: + case OSP_SRV_CNAMQUERY: + srvtype = (profile->srvtype == OSP_SRV_NPQUERY) ? "npquery" : "cnamquery"; if (switch_strlen_zero(inbound->tohost)) { switch_copy_string(term, source, sizeof(term)); } else { @@ -1160,13 +1244,16 @@ static void osp_log_authreq( } } total = 1; - } else { + break; + case OSP_SRV_VOICE: + default: srvtype = "voice"; term[0] = '\0'; total = profile->maxdest; + break; } - switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, + OSP_LOG( "AuthReq: " "srvtype '%s' " "source '%s' " @@ -1178,12 +1265,14 @@ static void osp_log_authreq( "called '%s' " "lnp '%s/%s/%d' " "preferred '%s' " + "fromdisplay '%s' " "rpid '%s' " "pai '%s' " - "div '%s/%s' " "pci '%s' " + "div '%s/%s' " + "useragent '%s' " "cinfo '%s/%s/%s/%s/%s/%s/%s/%s' " - "maxcount '%d'\n", + "maxcount '%d'", srvtype, source, srcdev, @@ -1194,15 +1283,17 @@ static void osp_log_authreq( inbound->called, inbound->nprn, inbound->npcic, inbound->npdi, term, + OSP_FILTER_NULLSTR(inbound->fromdisplay), inbound->rpiduser, inbound->paiuser, - inbound->divuser, inbound->divhost, inbound->pciuser, + inbound->divuser, inbound->divhost, + OSP_FILTER_NULLSTR(inbound->useragent), OSP_FILTER_NULLSTR(inbound->cinfo[0]), OSP_FILTER_NULLSTR(inbound->cinfo[1]), OSP_FILTER_NULLSTR(inbound->cinfo[2]), OSP_FILTER_NULLSTR(inbound->cinfo[3]), OSP_FILTER_NULLSTR(inbound->cinfo[4]), OSP_FILTER_NULLSTR(inbound->cinfo[5]), OSP_FILTER_NULLSTR(inbound->cinfo[6]), OSP_FILTER_NULLSTR(inbound->cinfo[7]), total); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1213,9 +1304,9 @@ static void osp_log_authreq( static void osp_log_authrsp( osp_results_t *results) { - OSP_DEBUG_START; + OSP_TEST_START; - switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, + OSP_LOG( "AuthRsp: " "destcount '%d/%d' " "transid '%"PRIu64"' " @@ -1225,8 +1316,9 @@ static void osp_log_authrsp( "destination '%s' " "destnid '%s' " "lnp '%s/%s/%d' " + "cnam '%s' " "protocol '%s' " - "supported '%d'\n", + "supported '%d'", results->count, results->total, results->transid, @@ -1236,14 +1328,15 @@ static void osp_log_authrsp( results->dest, results->destnid, results->nprn, results->npcic, results->npdi, + results->cnam, osp_get_protocolname(results->protocol), results->supported); - OSP_DEBUG_END; + OSP_TEST_END; } /* - * Alway log UsageInd parameters + * Always log UsageInd parameters * param results Route info * param usage Usage info * return @@ -1252,32 +1345,34 @@ static void osp_log_usageind( osp_results_t *results, osp_usage_t *usage) { - OSP_DEBUG_START; + OSP_TEST_START; - switch_log_printf(SWITCH_CHANNEL_LOG, osp_global.loglevel, + OSP_LOG( "UsageInd: " "destcount '%d/%d' " "transid '%"PRIu64"' " "cause '%d' " "release '%d' " - "times '%"PRId64"/%"PRId64"/%"PRId64"/%"PRId64"' " + "times '%"PRId64"/%"PRId64"/%"PRId64"/%"PRId64"/%"PRId64"' " "duration '%"PRId64"' " - "pdd '%"PRId64"' " + "pdd '%"PRId64"/%"PRId64"' " + "mediaip '%s/%s' " "codec '%s/%s' " - "rtpctets '%d/%d' " - "rtppackets '%d/%d'\n", + "rtpctets '%d' " + "rtppackets '%d'", results->count, results->total, results->transid, results->cause ? results->cause : usage->cause, usage->release, - usage->start / 1000000, usage->alert / 1000000, usage->connect / 1000000, usage->end / 1000000, + usage->start / 1000000, usage->pstart / 1000000, usage->alert / 1000000, usage->connect / 1000000, usage->end / 1000000, usage->duration / 1000000, - usage->pdd / 1000, + usage->pdd / 1000, usage->ppdd / 1000, + usage->srcmediaip, usage->destmediaip, OSP_FILTER_NULLSTR(usage->srccodec), OSP_FILTER_NULLSTR(usage->destcodec), - usage->rtpsrcrepoctets, usage->rtpdestrepoctets, - usage->rtpsrcreppackets, usage->rtpdestreppackets); + usage->rtpsrcrepoctets, + usage->rtpsrcreppackets); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1295,33 +1390,34 @@ static void osp_get_inbound( int i; char name[OSP_SIZE_NORSTR]; - OSP_DEBUG_START; + OSP_TEST_START; /* Cleanup buffer */ memset(inbound, 0, sizeof(*inbound)); + inbound->protocol = OSPC_PROTNAME_UNKNOWN; /* Get caller profile */ caller = switch_channel_get_caller_profile(channel); /* osp_source_device */ inbound->actsrc = switch_channel_get_variable(channel, OSP_VAR_SRCDEV); - OSP_DEBUG("actsrc: '%s'", OSP_FILTER_NULLSTR(inbound->actsrc)); + OSP_TEST("actsrc: '%s'", OSP_FILTER_NULLSTR(inbound->actsrc)); /* Source device */ inbound->srcdev = caller->network_addr; - OSP_DEBUG("srcdev: '%s'", OSP_FILTER_NULLSTR(inbound->srcdev)); + OSP_TEST("srcdev: '%s'", OSP_FILTER_NULLSTR(inbound->srcdev)); /* osp_source_nid */ inbound->srcnid = switch_channel_get_variable(channel, OSP_VAR_SRCNID); - OSP_DEBUG("srcnid: '%s'", OSP_FILTER_NULLSTR(inbound->srcnid)); + OSP_TEST("srcnid: '%s'", OSP_FILTER_NULLSTR(inbound->srcnid)); /* Source signaling protocol */ inbound->protocol = osp_get_protocol(caller->source); - OSP_DEBUG("protocol: '%d'", inbound->protocol); + OSP_TEST("protocol: '%d'", inbound->protocol); /* Call-ID */ inbound->callid = switch_channel_get_variable(channel, OSP_FS_CALLID); - OSP_DEBUG("callid: '%s'", OSP_FILTER_NULLSTR(inbound->callid)); + OSP_TEST("callid: '%s'", OSP_FILTER_NULLSTR(inbound->callid)); /* Calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_FROMUSER))) { @@ -1329,56 +1425,64 @@ static void osp_get_inbound( } else { osp_parse_userinfo(caller->caller_id_number, inbound->calling, sizeof(inbound->calling), NULL, 0, NULL, 0, NULL); } - OSP_DEBUG("calling: '%s'", inbound->calling); + OSP_TEST("calling: '%s'", inbound->calling); /* Called number and LNP parameters */ osp_parse_userinfo(caller->destination_number, inbound->called, sizeof(inbound->called), inbound->nprn, sizeof(inbound->nprn), inbound->npcic, sizeof(inbound->npcic), &inbound->npdi); - OSP_DEBUG("called: '%s'", inbound->called); - OSP_DEBUG("nprn: '%s'", inbound->nprn); - OSP_DEBUG("npcic: '%s'", inbound->npcic); - OSP_DEBUG("npdi: '%d'", inbound->npdi); + OSP_TEST("called: '%s'", inbound->called); + OSP_TEST("nprn: '%s'", inbound->nprn); + OSP_TEST("npcic: '%s'", inbound->npcic); + OSP_TEST("npdi: '%d'", inbound->npdi); /* To header */ inbound->tohost = switch_channel_get_variable(channel, OSP_FS_TOHOST); - OSP_DEBUG("tohost: '%s'", OSP_FILTER_NULLSTR(inbound->tohost)); + OSP_TEST("tohost: '%s'", OSP_FILTER_NULLSTR(inbound->tohost)); inbound->toport = switch_channel_get_variable(channel, OSP_FS_TOPORT); - OSP_DEBUG("toport: '%s'", OSP_FILTER_NULLSTR(inbound->toport)); + OSP_TEST("toport: '%s'", OSP_FILTER_NULLSTR(inbound->toport)); + + /* From header display name */ + inbound->fromdisplay = switch_channel_get_variable(channel, OSP_FS_FROMDISPLAY); + OSP_TEST("FROM display: '%s'", OSP_FILTER_NULLSTR(inbound->fromdisplay)); /* RPID calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_RPID))) { osp_parse_header_user(tmp, inbound->rpiduser, sizeof(inbound->rpiduser)); } - OSP_DEBUG("RPID user: '%s'", inbound->rpiduser); + OSP_TEST("RPID user: '%s'", inbound->rpiduser); /* PAI calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_PAI))) { osp_parse_userinfo(tmp, inbound->paiuser, sizeof(inbound->paiuser), NULL, 0, NULL, 0, NULL); } - OSP_DEBUG("PAI user: '%s'", inbound->paiuser); + OSP_TEST("PAI user: '%s'", inbound->paiuser); + + /* PCI calling number */ + if ((tmp = switch_channel_get_variable(channel, OSP_FS_PCI))) { + osp_parse_header_user(tmp, inbound->pciuser, sizeof(inbound->pciuser)); + } + OSP_TEST("PCI user: '%s'", inbound->pciuser); /* DIV calling number */ if ((tmp = switch_channel_get_variable(channel, OSP_FS_DIV))) { osp_parse_header_user(tmp, inbound->divuser, sizeof(inbound->divuser)); osp_parse_header_host(tmp, inbound->divhost, sizeof(inbound->divhost)); } - OSP_DEBUG("DIV user: '%s'", inbound->divuser); - OSP_DEBUG("DIV host: '%s'", inbound->divhost); + OSP_TEST("DIV user: '%s'", inbound->divuser); + OSP_TEST("DIV host: '%s'", inbound->divhost); - /* PCI calling number */ - if ((tmp = switch_channel_get_variable(channel, OSP_FS_PCI))) { - osp_parse_header_user(tmp, inbound->pciuser, sizeof(inbound->pciuser)); - } - OSP_DEBUG("PCI user: '%s'", inbound->pciuser); + /* User-Agent header */ + inbound->useragent = switch_channel_get_variable(channel, OSP_FS_USERAGENT); + OSP_TEST("User-Agent: '%s'", OSP_FILTER_NULLSTR(inbound->useragent)); /* Custom info */ for (i = 0; i < OSP_MAX_CINFO; i++) { switch_snprintf(name, sizeof(name), "%s%d", OSP_VAR_CUSTOMINFO, i + 1); inbound->cinfo[i] = switch_channel_get_variable(channel, name); - OSP_DEBUG("cinfo[%d]: '%s'", i, OSP_FILTER_NULLSTR(inbound->cinfo[i])); + OSP_TEST("cinfo[%d]: '%s'", i, OSP_FILTER_NULLSTR(inbound->cinfo[i])); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1393,29 +1497,35 @@ static void osp_get_outbound( { const char *tmp; - OSP_DEBUG_START; + OSP_TEST_START; /* Cleanup buffer */ memset(outbound, 0, sizeof(*outbound)); - /* Get destination network ID namd & location info */ + /* Get destination network ID name & location info */ outbound->dniduserparam = switch_channel_get_variable(channel, OSP_VAR_DNIDUSERPARAM); - OSP_DEBUG("dniduserparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduserparam)); + OSP_TEST("dniduserparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduserparam)); outbound->dniduriparam = switch_channel_get_variable(channel, OSP_VAR_DNIDURIPARAM); - OSP_DEBUG("dniduriparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduriparam)); + OSP_TEST("dniduriparam: '%s'", OSP_FILTER_NULLSTR(outbound->dniduriparam)); + + /* Get fixed outbound parameter string & location info */ + outbound->outuserparam = switch_channel_get_variable(channel, OSP_VAR_OUTUSERPARAM); + OSP_TEST("outuserparam: '%s'", OSP_FILTER_NULLSTR(outbound->outuserparam)); + outbound->outuriparam = switch_channel_get_variable(channel, OSP_VAR_OUTURIPARAM); + OSP_TEST("outuriparam: '%s'", OSP_FILTER_NULLSTR(outbound->outuriparam)); /* Get "user=phone" insert flag */ tmp = switch_channel_get_variable(channel, OSP_VAR_USERPHONE); if (!switch_strlen_zero(tmp)) { outbound->userphone = switch_true(tmp); } - OSP_DEBUG("userphone: '%d'", outbound->userphone); + OSP_TEST("userphone: '%d'", outbound->userphone); /* Get outbound proxy info */ outbound->outproxy = switch_channel_get_variable(channel, OSP_VAR_OUTPROXY); - OSP_DEBUG("outporxy: '%s'", OSP_FILTER_NULLSTR(outbound->outproxy)); + OSP_TEST("outporxy: '%s'", OSP_FILTER_NULLSTR(outbound->outproxy)); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1434,7 +1544,12 @@ static switch_status_t osp_get_transaction( osp_profile_t *profile; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; + + /* Cleanup buffer */ + memset(results, 0, sizeof(*results)); + results->transaction = OSP_INVALID_HANDLE; + results->protocol = OSPC_PROTNAME_UNKNOWN; /* Get profile name */ if (!(results->profile = switch_channel_get_variable(channel, OSP_VAR_PROFILE))) { @@ -1443,13 +1558,13 @@ static switch_status_t osp_get_transaction( /* Get transaction handle */ if (osp_find_profile(results->profile, &profile) == SWITCH_STATUS_FALSE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find profile '%s'\n", results->profile); + OSP_ERROR("Failed to find profile '%s'", results->profile); } else if (profile->provider == OSP_INVALID_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disabled profile '%s'\n", results->profile); + OSP_ERROR("Disabled profile '%s'", results->profile); } else if (!(tmp = switch_channel_get_variable(channel, OSP_VAR_TRANSACTION)) || (sscanf(tmp, "%d", &results->transaction) != 1)){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get transaction handle'\n"); + OSP_ERROR("%s", "Failed to get transaction handle'"); } else if (results->transaction == OSP_INVALID_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid transaction handle'\n"); + OSP_ERROR("%s", "Invalid transaction handle'"); } else { if (!(tmp = switch_channel_get_variable(channel, OSP_VAR_TRANSID)) || (sscanf(tmp, "%"PRIu64"", &results->transid) != 1)) { results->transid = 0; @@ -1466,7 +1581,7 @@ static switch_status_t osp_get_transaction( } /* - * Get termiantion cause + * Get termination cause * The logic is * 1. osp_next_function should get TCCode from last_bridge_hangup_cause * 2. osp_on_reporting should get TCCode from osp_terimation_cause @@ -1485,23 +1600,23 @@ static switch_status_t osp_get_transaction( status = SWITCH_STATUS_SUCCESS; } - OSP_DEBUG("profile: '%s'", results->profile); - OSP_DEBUG("transaction: '%d'", results->transaction); - OSP_DEBUG("transid: '%"PRIu64"'", results->transid); - OSP_DEBUG("total: '%d'", results->total); - OSP_DEBUG("count: '%d'", results->count); - OSP_DEBUG("cause: '%d'", results->cause); + OSP_TEST("profile: '%s'", results->profile); + OSP_TEST("transaction: '%d'", results->transaction); + OSP_TEST("transid: '%"PRIu64"'", results->transid); + OSP_TEST("total: '%d'", results->total); + OSP_TEST("count: '%d'", results->count); + OSP_TEST("cause: '%d'", results->cause); - OSP_DEBUG_END; + OSP_TEST_END; return status; } /* * Retrieve usage info - * param channel channel + * param channel Channel * param originator Originator profile - * param terminator Terminator profile, not used at this time + * param originatee Originatee profile * param results Route info * param usage Usage info * return @@ -1509,21 +1624,26 @@ static switch_status_t osp_get_transaction( static void osp_get_usage( switch_channel_t *channel, switch_caller_profile_t *originator, - switch_caller_profile_t *terminator_unused, + switch_caller_profile_t *originatee, osp_results_t *results, osp_usage_t *usage) { const char *tmp; - switch_channel_timetable_t *times; + switch_channel_timetable_t *otimes; + switch_channel_timetable_t *ttimes; - OSP_DEBUG_START; + OSP_TEST_START; /* Cleanup buffer */ memset(usage, 0, sizeof(*usage)); + usage->release = OSPC_RELEASE_UNKNOWN; + usage->rtpsrcrepoctets = OSP_DEF_STATS; + usage->rtpsrcreppackets = OSP_DEF_STATS; /* Release source */ - usage->release = OSPC_RELEASE_UNKNOWN; if (osp_get_protocol(originator->source) == OSPC_PROTNAME_SIP) { + usage->localip = switch_channel_get_variable(channel, OSP_FS_SIPLOCALIP); + tmp = switch_channel_get_variable(channel, OSP_FS_SIPRELEASE); if (!tmp) { usage->release = OSPC_RELEASE_UNDEFINED; @@ -1537,56 +1657,67 @@ static void osp_get_usage( usage->release = OSPC_RELEASE_SOURCE; } } - OSP_DEBUG("release: '%d'", usage->release); + OSP_TEST("localip: '%s'", OSP_FILTER_NULLSTR(usage->localip)); + OSP_TEST("release: '%d'", usage->release); - /* Termiation cause */ + /* Termination cause */ usage->cause = switch_channel_get_cause_q850(channel); - OSP_DEBUG("cause: '%d'", usage->cause); + OSP_TEST("cause: '%d'", usage->cause); /* Timestamps */ - times = switch_channel_get_timetable(channel); - usage->start = times->created; - OSP_DEBUG("start: '%"PRIu64"'", usage->start); - usage->alert = times->progress; - OSP_DEBUG("alert: '%"PRIu64"'", usage->alert); - usage->connect = times->answered; - OSP_DEBUG("connect: '%"PRIu64"'", usage->connect); - usage->end = times->hungup; - OSP_DEBUG("end: '%"PRIu64"'", usage->end); - if (times->answered) { - usage->duration = times->hungup - times->answered; - OSP_DEBUG("duration: '%"PRIu64"'", usage->duration); + otimes = switch_channel_get_timetable(channel); + usage->start = otimes->created; + OSP_TEST("start: '%"PRId64"'", usage->start); + if (originatee && ((ttimes = originatee->times) || (ttimes = originatee->old_times))) { + usage->pstart = ttimes->created; + } else { + usage->pstart = usage->start; } - if (times->progress) { - usage->pdd = times->progress - usage->start; - OSP_DEBUG("pdd: '%"PRIu64"'", usage->pdd); + usage->alert = otimes->progress; + OSP_TEST("alert: '%"PRId64"'", usage->alert); + usage->connect = otimes->answered; + OSP_TEST("connect: '%"PRId64"'", usage->connect); + usage->end = otimes->hungup; + OSP_TEST("end: '%"PRId64"'", usage->end); + if (otimes->answered) { + usage->duration = otimes->hungup - otimes->answered; + OSP_TEST("duration: '%"PRId64"'", usage->duration); + } + if (otimes->progress) { + usage->pdd = otimes->progress - usage->start; + OSP_TEST("pdd: '%"PRId64"'", usage->pdd); + + usage->ppdd = otimes->progress - usage->pstart; + OSP_TEST("ppdd: '%"PRId64"'", usage->ppdd); } - /* Codecs */ - usage->srccodec = switch_channel_get_variable(channel, OSP_FS_SRCCODEC); - OSP_DEBUG("srccodec: '%s'", OSP_FILTER_NULLSTR(usage->srccodec)); - usage->destcodec = switch_channel_get_variable(channel, OSP_FS_DESTCODEC); - OSP_DEBUG("destcodec: '%s'", OSP_FILTER_NULLSTR(usage->destcodec)); + if (otimes->answered) { + /* Media addresses */ + tmp = switch_channel_get_variable(channel, OSP_FS_SRCSDP); + osp_get_mediaip(tmp, usage->srcmediaip, sizeof(usage->srcmediaip)); + OSP_TEST("srcmediaip: '%s'", usage->srcmediaip); + tmp = switch_channel_get_variable(channel, OSP_FS_DESTSDP); + osp_get_mediaip(tmp, usage->destmediaip, sizeof(usage->destmediaip)); + OSP_TEST("destmediaip: '%s'", usage->destmediaip); - /* QoS statistics */ - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPSRCREPOCTS)) || (sscanf(tmp, "%d", &usage->rtpsrcrepoctets) != 1)) { - usage->rtpsrcrepoctets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpsrcrepoctets: '%d'", usage->rtpsrcrepoctets); - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPDESTREPOCTS)) || (sscanf(tmp, "%d", &usage->rtpdestrepoctets) != 1)) { - usage->rtpdestrepoctets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpdestrepoctets: '%d'", usage->rtpdestrepoctets); - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPSRCREPPKTS)) || (sscanf(tmp, "%d", &usage->rtpsrcreppackets) != 1)) { - usage->rtpsrcreppackets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpsrcreppackets: '%d'", usage->rtpsrcreppackets); - if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPDESTREPPKTS)) || (sscanf(tmp, "%d", &usage->rtpdestreppackets) != 1)) { - usage->rtpdestreppackets = OSP_DEF_STATS; - } - OSP_DEBUG("rtpdestreppackets: '%d'", usage->rtpdestreppackets); + /* Codecs */ + usage->srccodec = switch_channel_get_variable(channel, OSP_FS_SRCCODEC); + OSP_TEST("srccodec: '%s'", OSP_FILTER_NULLSTR(usage->srccodec)); + usage->destcodec = switch_channel_get_variable(channel, OSP_FS_DESTCODEC); + OSP_TEST("destcodec: '%s'", OSP_FILTER_NULLSTR(usage->destcodec)); - OSP_DEBUG_END; + /* QoS statistics */ + if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPINOCTS)) || (sscanf(tmp, "%d", &usage->rtpsrcrepoctets) != 1)) { + usage->rtpsrcrepoctets = OSP_DEF_STATS; + } + OSP_TEST("rtpsrcrepoctets: '%d'", usage->rtpsrcrepoctets); + if (!(tmp = switch_channel_get_variable(channel, OSP_FS_RTPINPKTS)) || (sscanf(tmp, "%d", &usage->rtpsrcreppackets) != 1)) { + usage->rtpsrcreppackets = OSP_DEF_STATS; + } + OSP_TEST("rtpsrcreppackets: '%d'", usage->rtpsrcreppackets); + } + + OSP_TEST_END; } /* @@ -1603,23 +1734,23 @@ static switch_status_t osp_check_destination( int error; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; if ((error = OSPPTransactionIsDestOSPEnabled(results->transaction, &enabled)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination OSP version, error '%d'\n", error); + OSP_ERROR("Failed to get destination OSP version, error '%d'", error); } else if ((error = OSPPTransactionGetDestProtocol(results->transaction, &protocol)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get signaling protocol, error '%d'\n", error); + OSP_ERROR("Failed to get signaling protocol, error '%d'", error); } else { + results->protocol = protocol; switch(protocol) { case OSPC_PROTNAME_UNDEFINED: case OSPC_PROTNAME_UNKNOWN: - protocol = osp_global.protocol; + results->protocol = osp_global.protocol; case OSPC_PROTNAME_SIP: case OSPC_PROTNAME_Q931: case OSPC_PROTNAME_IAX: case OSPC_PROTNAME_SKYPE: - results->protocol = protocol; - if (!switch_strlen_zero(osp_global.endpoint[protocol].module) && !switch_strlen_zero(osp_global.endpoint[protocol].profile)) { + if (!switch_strlen_zero(osp_global.endpoint[results->protocol].module) && !switch_strlen_zero(osp_global.endpoint[results->protocol].profile)) { results->supported = SWITCH_TRUE; results->cause = 0; status = SWITCH_STATUS_SUCCESS; @@ -1631,21 +1762,25 @@ static switch_status_t osp_check_destination( case OSPC_PROTNAME_SMPP: case OSPC_PROTNAME_XMPP: default: - results->protocol = protocol; results->supported = SWITCH_FALSE; /* Q.850 protocol error, unspecified */ results->cause = 111; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported protocol '%d'\n", protocol); + OSP_WARN("Unsupported protocol '%d'", protocol); break; } - OSP_DEBUG("protocol: '%d'", results->protocol); - OSP_DEBUG("supported: '%d'", results->supported); - OSP_DEBUG("cause: '%d'", results->cause); + OSP_TEST("protocol: '%d'", results->protocol); + OSP_TEST("supported: '%d'", results->supported); + OSP_TEST("cause: '%d'", results->cause); if ((error = OSPPTransactionGetDestinationNetworkId(results->transaction, sizeof(results->destnid), results->destnid)) != OSPC_ERR_NO_ERROR) { results->destnid[0] = '\0'; } - OSP_DEBUG("destnid: '%s'", results->destnid); + OSP_TEST("destnid: '%s'", results->destnid); + + if ((error = OSPPTransactionGetCNAM(results->transaction, sizeof(results->cnam), results->cnam)) != OSPC_ERR_NO_ERROR) { + results->cnam[0] = '\0'; + } + OSP_TEST("cnam: '%s'", results->cnam); error = OSPPTransactionGetNumberPortabilityParameters( results->transaction, @@ -1659,72 +1794,86 @@ static switch_status_t osp_check_destination( results->npcic[0] = '\0'; results->npdi = 0; } - OSP_DEBUG("nprn: '%s'", results->nprn); - OSP_DEBUG("npcic: '%s'", results->npcic); - OSP_DEBUG("npdi: '%d'", results->npdi); + OSP_TEST("nprn: '%s'", results->nprn); + OSP_TEST("npcic: '%s'", results->npcic); + OSP_TEST("npdi: '%d'", results->npdi); for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) { if ((error = OSPPTransactionGetOperatorName(results->transaction, type, sizeof(results->opname[type]), results->opname[type])) != OSPC_ERR_NO_ERROR) { results->opname[type][0] = '\0'; } - OSP_DEBUG("opname[%d]: '%s'", type, results->opname[type]); + OSP_TEST("opname[%d]: '%s'", type, results->opname[type]); } osp_log_authrsp(results); } - OSP_DEBUG_END; + OSP_TEST_END; return status; } /* - * Build parameter string for each channel - * param results Route info - * param buffer Buffer - * param bufsize Buffer size - * return - */ -static void osp_build_eachparam( - osp_results_t *results, - char *buffer, - switch_size_t bufsize) -{ - OSP_DEBUG_START; - - if (results && buffer && bufsize) { - switch_snprintf(buffer, bufsize, "[%s=%s]", OSP_FS_OUTCALLING, results->calling); - OSP_DEBUG("eachparam: '%s'", buffer); - } - - OSP_DEBUG_END; -} - -/* - * Build endpoint string + * Build parameter string for all channels * param results Route info * param outbound Outbound settings * param buffer Buffer * param bufsize Buffer size * return */ -static void osp_build_endpoint( +static void osp_build_allparam( osp_results_t *results, osp_outbound_t *outbound, char *buffer, switch_size_t bufsize) { - char *head = buffer; - switch_size_t len, size = bufsize; - - OSP_DEBUG_START; + OSP_TEST_START; if (results && buffer && bufsize) { switch (results->protocol) { case OSPC_PROTNAME_SIP: - /* module/profile/called */ - switch_snprintf(head, size, "%s/%s/%s", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile, results->called); - OSP_ADJUST_LEN(head, size, len); + case OSPC_PROTNAME_Q931: + case OSPC_PROTNAME_IAX: + case OSPC_PROTNAME_SKYPE: + default: + buffer[0] = '\0'; + break; + } + OSP_TEST("allparam: '%s'", buffer); + } + + OSP_TEST_END; +} + +/* + * Build parameter string for each channel + * param results Route info + * param outbound Outbound settings + * param buffer Buffer + * param bufsize Buffer size + * return + */ +static void osp_build_eachparam( + osp_results_t *results, + osp_outbound_t *outbound, + char *buffer, + switch_size_t bufsize) +{ + char *head; + switch_size_t len, size; + char userparam[OSP_SIZE_NORSTR] = { 0 }; + char uriparam[OSP_SIZE_NORSTR] = { 0 }; + char param[OSP_SIZE_NORSTR] = { 0 }; + + OSP_TEST_START; + + if (results && buffer && bufsize) { + /* Translated calling number */ + switch (results->protocol) { + case OSPC_PROTNAME_SIP: + /* User parameter string buffer */ + head = userparam; + size = sizeof(userparam); /* RN */ if (!switch_strlen_zero_buf(results->nprn)) { @@ -1750,9 +1899,15 @@ static void osp_build_endpoint( OSP_ADJUST_LEN(head, size, len); } - /* Destination */ - switch_snprintf(head, size, "@%s", results->dest); - OSP_ADJUST_LEN(head, size, len); + /* User parameter fixed outbound parameter string */ + if (!switch_strlen_zero(outbound->outuserparam)) { + switch_snprintf(head, size, ";%s", outbound->outuserparam); + OSP_ADJUST_LEN(head, size, len); + } + + /* URI parameter string buffer */ + head = uriparam; + size = sizeof(uriparam); /* URI parameter destination network ID */ if (!switch_strlen_zero(outbound->dniduriparam) && !switch_strlen_zero_buf(results->destnid)) { @@ -1760,12 +1915,88 @@ static void osp_build_endpoint( OSP_ADJUST_LEN(head, size, len); } + /* URI parameter fixed outbound parameter string */ + if (!switch_strlen_zero(outbound->outuriparam)) { + switch_snprintf(head, size, ";%s", outbound->outuriparam); + OSP_ADJUST_LEN(head, size, len); + } + /* user=phone */ if (outbound->userphone) { switch_snprintf(head, size, ";user=phone"); OSP_ADJUST_LEN(head, size, len); } + /* Parameter string buffer */ + head = param; + size = sizeof(param); + + if (!switch_strlen_zero(userparam)) { + switch_snprintf(head, size, ",%s=%s", OSP_FS_RURIUSERPARAM, userparam + 1); + OSP_ADJUST_LEN(head, size, len); + } + + if (!switch_strlen_zero(uriparam)) { + switch_snprintf(head, size, ",%s=%s", OSP_FS_RURIURIPARAM, uriparam + 1); + OSP_ADJUST_LEN(head, size, len); + } + break; + case OSPC_PROTNAME_Q931: + case OSPC_PROTNAME_IAX: + case OSPC_PROTNAME_SKYPE: + default: + break; + } + + /* Fill buffer */ + head = buffer; + size = bufsize; + + switch_snprintf(head, size - 1, "[%s=%s", OSP_FS_OUTCALLING, results->calling); + OSP_ADJUST_LEN(head, size, len); + + switch_snprintf(head, size - 1, "%s", param); + OSP_ADJUST_LEN(head, size, len); + + switch_snprintf(head, size, "]"); + OSP_ADJUST_LEN(head, size, len); + + OSP_TEST("eachparam: '%s'", buffer); + } + + OSP_TEST_END; +} + +/* + * Build endpoint string + * param results Route info + * param outbound Outbound settings + * param buffer Buffer + * param bufsize Buffer size + * return + */ +static void osp_build_endpoint( + osp_results_t *results, + osp_outbound_t *outbound, + char *buffer, + switch_size_t bufsize) +{ + char *head = buffer; + switch_size_t len, size = bufsize; + + OSP_TEST_START; + + if (results && buffer && bufsize) { + switch (results->protocol) { + case OSPC_PROTNAME_SIP: + /* module/profile/called */ + switch_snprintf(head, size, "%s/%s/%s", osp_global.endpoint[OSPC_PROTNAME_SIP].module, osp_global.endpoint[OSPC_PROTNAME_SIP].profile, results->called); + OSP_ADJUST_LEN(head, size, len); + + /* Destination */ + switch_snprintf(head, size, "@%s", results->dest); + OSP_ADJUST_LEN(head, size, len); + /* Outbound proxy */ if (!switch_strlen_zero(outbound->outproxy)) { switch_snprintf(head, size, ";fs_path=sip:%s", outbound->outproxy); @@ -1793,10 +2024,10 @@ static void osp_build_endpoint( buffer[0] = '\0'; break; } - OSP_DEBUG("endpoint: '%s'", buffer); + OSP_TEST("endpoint: '%s'", buffer); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1813,22 +2044,26 @@ static void osp_create_route( char *buffer, switch_size_t bufsize) { + char allparam[OSP_SIZE_NORSTR]; char eachparam[OSP_SIZE_NORSTR]; char endpoint[OSP_SIZE_NORSTR]; - OSP_DEBUG_START; + OSP_TEST_START; + + /* Build dial string for all channels part */ + osp_build_allparam(results, outbound, allparam, sizeof(allparam)); /* Build dial string for each channel part */ - osp_build_eachparam(results, eachparam, sizeof(eachparam)); + osp_build_eachparam(results, outbound, eachparam, sizeof(eachparam)); /* Build dial string for endpoint part */ osp_build_endpoint(results, outbound, endpoint, sizeof(endpoint)); /* Build dail string */ - switch_snprintf(buffer, bufsize, "%s%s", eachparam, endpoint); - OSP_DEBUG("route: '%s'", buffer); + switch_snprintf(buffer, bufsize, "%s%s%s", allparam, eachparam, endpoint); + OSP_TEST("route: '%s'", buffer); - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -1854,7 +2089,7 @@ static switch_status_t osp_request_auth( int i, error; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; /* Set source network ID */ OSPPTransactionSetNetworkIds(results->transaction, inbound->srcnid, NULL); @@ -1865,18 +2100,24 @@ static switch_status_t osp_request_auth( /* Set source LNP parameters */ OSPPTransactionSetNumberPortability(results->transaction, inbound->nprn, inbound->npcic, inbound->npdi); + /* Set From */ + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_FROM, OSPC_NFORMAT_DISPLAYNAME, inbound->fromdisplay); + /* Set RPID */ - OSPPTransactionSetRemotePartyId(results->transaction, OSPC_NFORMAT_E164, inbound->rpiduser); + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_RPID, OSPC_NFORMAT_E164, inbound->rpiduser); /* Set PAI */ - OSPPTransactionSetAssertedId(results->transaction, OSPC_NFORMAT_E164, inbound->paiuser); + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_PAI, OSPC_NFORMAT_E164, inbound->paiuser); - /* Set diversion */ + /* Set PCI */ + OSPPTransactionSetSIPHeader(results->transaction, OSPC_SIPHEADER_PCI, OSPC_NFORMAT_E164, inbound->pciuser); + + /* Set Diversion */ osp_convert_inout(inbound->divhost, tmp, sizeof(tmp)); OSPPTransactionSetDiversion(results->transaction, inbound->divuser, tmp); - /* Set PCI */ - OSPPTransactionSetChargeInfo(results->transaction, OSPC_NFORMAT_E164, inbound->pciuser); + /* Set User-Agent */ + OSPPTransactionSetUserAgent(results->transaction, inbound->useragent); /* Set custom info */ for (i = 0; i < OSP_MAX_CINFO; i++) { @@ -1901,8 +2142,10 @@ static switch_status_t osp_request_auth( osp_convert_inout(srcdev, dev, sizeof(dev)); /* Preferred and max destinations */ - if (profile->srvtype == OSP_SRV_NPQUERY) { - OSPPTransactionSetServiceType(results->transaction, OSPC_SERVICE_NPQUERY); + switch (profile->srvtype) { + case OSP_SRV_NPQUERY: + case OSP_SRV_CNAMQUERY: + OSPPTransactionSetServiceType(results->transaction, (profile->srvtype == OSP_SRV_NPQUERY) ? OSPC_SERVICE_NPQUERY : OSPC_SERVICE_CNAMQUERY); if (switch_strlen_zero(inbound->tohost)) { switch_copy_string(term, src, sizeof(term)); @@ -1917,13 +2160,18 @@ static switch_status_t osp_request_auth( preferred[0] = term; results->total = 1; - } else { + + break; + case OSP_SRV_VOICE: + default: OSPPTransactionSetServiceType(results->transaction, OSPC_SERVICE_VOICE); results->total = profile->maxdest; + + break; } - OSP_DEBUG_MSG("RequestAuthorisation"); + OSP_TEST_MSG("RequestAuthorisation"); /* Request authorization */ error = OSPPTransactionRequestAuthorisation( @@ -1942,10 +2190,10 @@ static switch_status_t osp_request_auth( NULL, /* Log buffer size */ NULL); /* Log buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to request routing for '%s/%s', error '%d'\n", inbound->calling, inbound->called, error); + OSP_WARN("Unable to request routing for '%s/%s', error '%d'", inbound->calling, inbound->called, error); results->total = 0; } else if (results->total == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Without destination\n"); + OSP_WARN("%s", "Without destination"); } else { context = OSPPTransactionGetContext(results->transaction, &error); if (error == OSPC_ERR_NO_ERROR) { @@ -1955,10 +2203,10 @@ static switch_status_t osp_request_auth( } status = SWITCH_STATUS_SUCCESS; } - OSP_DEBUG("transid: '%"PRIu64"'", results->transid); - OSP_DEBUG("total: '%d'", results->total); + OSP_TEST("transid: '%"PRIu64"'", results->transid); + OSP_TEST("total: '%d'", results->total); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -1976,12 +2224,12 @@ static switch_status_t osp_get_first( unsigned int callidlen = 0, tokenlen = 0; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; /* Set destination count */ results->count = 1; - OSP_DEBUG_MSG("GetFirstDestination"); + OSP_TEST_MSG("GetFirstDestination"); /* Get first destination */ error = OSPPTransactionGetFirstDestination( @@ -2003,16 +2251,16 @@ static switch_status_t osp_get_first( &tokenlen, /* Token buffer length */ NULL); /* Token buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get first destination, error '%d'\n", error); + OSP_ERROR("Failed to get first destination, error '%d'", error); } else { osp_convert_outin(term, results->dest, sizeof(results->dest)); /* Check destination */ status = osp_check_destination(results); } - OSP_DEBUG("status: '%d'", status); + OSP_TEST("status: '%d'", status); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2030,17 +2278,17 @@ static switch_status_t osp_get_next( unsigned int callidlen = 0, tokenlen = 0; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; while ((status == SWITCH_STATUS_FALSE) && (results->count < results->total)) { /* Set destination count */ results->count++; - OSP_DEBUG_MSG("GetNextDestination"); + OSP_TEST_MSG("GetNextDestination"); /* Get next destination */ error = OSPPTransactionGetNextDestination( - results->transaction, /* Transsaction handle */ + results->transaction, /* Transaction handle */ results->cause, /* Failure reason */ 0, /* Timestamp buffer size */ NULL, /* Valid after */ @@ -2059,7 +2307,7 @@ static switch_status_t osp_get_next( &tokenlen, /* Token buffer length */ NULL); /* Token buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination, error '%d'\n", error); + OSP_ERROR("Failed to get destination, error '%d'", error); break; } else { osp_convert_outin(term, results->dest, sizeof(results->dest)); @@ -2068,9 +2316,9 @@ static switch_status_t osp_get_next( status = osp_check_destination(results); } } - OSP_DEBUG("status: '%d'", status); + OSP_TEST("status: '%d'", status); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2087,9 +2335,10 @@ static switch_status_t osp_report_usage( { int error; unsigned int dummy = 0; + osp_profile_t *profile; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; /* Set role info */ OSPPTransactionSetRoleInfo(results->transaction, OSPC_RSTATE_STOP, OSPC_RFORMAT_OSP, OSPC_RVENDOR_FREESWITCH); @@ -2101,6 +2350,26 @@ static switch_status_t osp_report_usage( OSPPTransactionRecordFailure(results->transaction, usage->cause); } + /* Set provider post dial delay */ + OSPPTransactionSetProviderPDD(results->transaction, usage->ppdd / 1000); + + /* Set media address */ + if (!switch_strlen_zero(usage->srcmediaip)) { + OSPPTransactionSetSrcAudioAddr(results->transaction, usage->srcmediaip); + } + if (!switch_strlen_zero(usage->destmediaip)) { + OSPPTransactionSetDestAudioAddr(results->transaction, usage->destmediaip); + } + + /* Set signal local address */ + OSPPTransactionSetProxyIngressAddr(results->transaction, usage->localip); + OSPPTransactionSetProxyEgressAddr(results->transaction, usage->localip); + + /* Set CDR proxy */ + if (osp_find_profile(results->profile, &profile) == SWITCH_STATUS_SUCCESS) { + OSPPTransactionSetCDRProxy(results->transaction, profile->deviceip, OSP_FREESWITCH, NULL); + } + /* Set codecs */ if (!switch_strlen_zero(usage->srccodec)) { OSPPTransactionSetCodec(results->transaction, OSPC_CODEC_SOURCE, usage->srccodec); @@ -2113,17 +2382,11 @@ static switch_status_t osp_report_usage( if (usage->rtpsrcrepoctets != OSP_DEF_STATS) { OSPPTransactionSetOctets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, usage->rtpsrcrepoctets); } - if (usage->rtpdestrepoctets != OSP_DEF_STATS) { - OSPPTransactionSetOctets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, usage->rtpdestrepoctets); - } if (usage->rtpsrcreppackets != OSP_DEF_STATS) { OSPPTransactionSetPackets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, usage->rtpsrcreppackets); } - if (usage->rtpdestreppackets != OSP_DEF_STATS) { - OSPPTransactionSetPackets(results->transaction, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, usage->rtpdestreppackets); - } - OSP_DEBUG_MSG("ReportUsage"); + OSP_TEST_MSG("ReportUsage"); /* Report usage */ error = OSPPTransactionReportUsage( @@ -2144,7 +2407,7 @@ static switch_status_t osp_report_usage( &dummy, /* Detail log buffer size */ NULL); /* Detail log buffer */ if (error != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to report usage, error '%d'\n", error); + OSP_ERROR("Failed to report usage, error '%d'", error); } else { status = SWITCH_STATUS_SUCCESS; } @@ -2152,7 +2415,7 @@ static switch_status_t osp_report_usage( /* Delete transaction handle */ OSPPTransactionDelete(results->transaction); - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2161,48 +2424,48 @@ static switch_status_t osp_report_usage( * Export OSP lookup status to channel * param channel Originator channel * param status OSP lookup status - * param outbound Outbound info * param results Routing info + * param outbound Outbound info * return */ static void osp_export_lookup( switch_channel_t *channel, switch_status_t status, - osp_outbound_t *outbound, - osp_results_t *results) + osp_results_t *results, + osp_outbound_t *outbound) { char value[OSP_SIZE_ROUSTR]; - OSP_DEBUG_START; + OSP_TEST_START; /* Profile name */ switch_channel_set_variable_var_check(channel, OSP_VAR_PROFILE, results->profile, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_PROFILE, results->profile); + OSP_TEST("%s: '%s'", OSP_VAR_PROFILE, results->profile); /* Transaction handle */ switch_snprintf(value, sizeof(value), "%d", results->transaction); switch_channel_set_variable_var_check(channel, OSP_VAR_TRANSACTION, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_TRANSACTION, value); + OSP_TEST("%s: '%s'", OSP_VAR_TRANSACTION, value); /* Transaction ID */ switch_snprintf(value, sizeof(value), "%"PRIu64"", results->transid); switch_channel_set_variable_var_check(channel, OSP_VAR_TRANSID, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_TRANSID, value); + OSP_TEST("%s: '%s'", OSP_VAR_TRANSID, value); /* OSP lookup status */ switch_snprintf(value, sizeof(value), "%d", status); switch_channel_set_variable_var_check(channel, OSP_VAR_LOOKUPSTATUS, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_LOOKUPSTATUS, value); + OSP_TEST("%s: '%s'", OSP_VAR_LOOKUPSTATUS, value); /* Destination total */ switch_snprintf(value, sizeof(value), "%d", results->total); switch_channel_set_variable_var_check(channel, OSP_VAR_ROUTETOTAL, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_ROUTETOTAL, value); + OSP_TEST("%s: '%s'", OSP_VAR_ROUTETOTAL, value); /* Destination count */ switch_snprintf(value, sizeof(value), "%d", results->count); switch_channel_set_variable_var_check(channel, OSP_VAR_ROUTECOUNT, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_ROUTECOUNT, value); + OSP_TEST("%s: '%s'", OSP_VAR_ROUTECOUNT, value); /* Dial string */ if (status == SWITCH_STATUS_SUCCESS) { @@ -2212,9 +2475,9 @@ static void osp_export_lookup( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_AUTOROUTE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_AUTOROUTE, value); + OSP_TEST("%s: '%s'", OSP_VAR_AUTOROUTE, value); - /* Termiantion cause */ + /* Termination cause */ if (results->cause) { switch_snprintf(value, sizeof(value), "%d", results->cause); switch_channel_set_variable_var_check(channel, OSP_VAR_TCCODE, value, SWITCH_FALSE); @@ -2222,38 +2485,38 @@ static void osp_export_lookup( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_TCCODE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_TCCODE, value); + OSP_TEST("%s: '%s'", OSP_VAR_TCCODE, value); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Export OSP next status to channel * param channel Originator channel * param status OSP next status - * param outbound Outbound info * param results Routing info + * param outbound Outbound info * return */ static void osp_export_next( switch_channel_t *channel, switch_status_t status, - osp_outbound_t *outbound, - osp_results_t *results) + osp_results_t *results, + osp_outbound_t *outbound) { char value[OSP_SIZE_NORSTR]; - OSP_DEBUG_START; + OSP_TEST_START; /* OSP next status */ switch_snprintf(value, sizeof(value), "%d", status); switch_channel_set_variable_var_check(channel, OSP_VAR_NEXTSTATUS, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_NEXTSTATUS, value); + OSP_TEST("%s: '%s'", OSP_VAR_NEXTSTATUS, value); /* Destination count */ switch_snprintf(value, sizeof(value), "%d", results->count); switch_channel_set_variable_var_check(channel, OSP_VAR_ROUTECOUNT, value, SWITCH_FALSE); - OSP_DEBUG("%s: '%s'", OSP_VAR_ROUTECOUNT, value); + OSP_TEST("%s: '%s'", OSP_VAR_ROUTECOUNT, value); /* Dial string */ if (status == SWITCH_STATUS_SUCCESS) { @@ -2263,9 +2526,9 @@ static void osp_export_next( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_AUTOROUTE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_AUTOROUTE, value); + OSP_TEST("%s: '%s'", OSP_VAR_AUTOROUTE, value); - /* Termiantion cause */ + /* Termination cause */ if (results->cause) { switch_snprintf(value, sizeof(value), "%d", results->cause); switch_channel_set_variable_var_check(channel, OSP_VAR_TCCODE, value, SWITCH_FALSE); @@ -2273,35 +2536,42 @@ static void osp_export_next( value[0] = '\0'; switch_channel_set_variable(channel, OSP_VAR_TCCODE, NULL); } - OSP_DEBUG("%s: '%s'", OSP_VAR_TCCODE, value); + OSP_TEST("%s: '%s'", OSP_VAR_TCCODE, value); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Request auth and get first OSP route * param channel Originator channel - * param results Routing info + * param profilename OSP profile name * return */ static void osp_do_lookup( switch_channel_t *channel, - osp_results_t *results) + const char *profilename) { int error; + osp_results_t results; osp_profile_t *profile; osp_inbound_t inbound; osp_outbound_t outbound; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; - if (osp_find_profile(results->profile, &profile) == SWITCH_STATUS_FALSE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find profile '%s'\n", results->profile); + /* Cleanup buffer */ + memset(&results, 0, sizeof(results)); + results.profile = profilename; + results.transaction = OSP_INVALID_HANDLE; + results.protocol = OSPC_PROTNAME_UNKNOWN; + + if (osp_find_profile(results.profile, &profile) == SWITCH_STATUS_FALSE) { + OSP_ERROR("Failed to find profile '%s'", results.profile); } else if (profile->provider == OSP_INVALID_HANDLE) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disabled profile '%s'\n", results->profile); - } else if ((error = OSPPTransactionNew(profile->provider, &results->transaction)) != OSPC_ERR_NO_ERROR) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create transaction handle, error '%d'\n", error); + OSP_ERROR("Disabled profile '%s'", results.profile); + } else if ((error = OSPPTransactionNew(profile->provider, &results.transaction)) != OSPC_ERR_NO_ERROR) { + OSP_ERROR("Failed to create transaction handle, error '%d'", error); } else { /* Get inbound info */ osp_get_inbound(channel, &inbound); @@ -2310,9 +2580,9 @@ static void osp_do_lookup( osp_log_authreq(profile, &inbound); /* Do AuthReq */ - if (osp_request_auth(profile, &inbound, results) == SWITCH_STATUS_SUCCESS) { + if (osp_request_auth(profile, &inbound, &results) == SWITCH_STATUS_SUCCESS) { /* Get route */ - if ((osp_get_first(results) == SWITCH_STATUS_SUCCESS) || (osp_get_next(results) == SWITCH_STATUS_SUCCESS)) { + if ((osp_get_first(&results) == SWITCH_STATUS_SUCCESS) || (osp_get_next(&results) == SWITCH_STATUS_SUCCESS)) { /* Get outbound info */ osp_get_outbound(channel, &outbound); status = SWITCH_STATUS_SUCCESS; @@ -2321,80 +2591,99 @@ static void osp_do_lookup( } /* Export OSP lookup info */ - osp_export_lookup(channel, status, &outbound, results); + osp_export_lookup(channel, status, &results, &outbound); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Get next OSP route * param channel Originator channel - * param results Routing info * return */ static void osp_do_next( - switch_channel_t *channel, - osp_results_t *results) + switch_channel_t *channel) { + osp_results_t results; osp_outbound_t outbound; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; - if (osp_get_transaction(channel, SWITCH_FALSE, results) == SWITCH_STATUS_SUCCESS) { + if (osp_get_transaction(channel, SWITCH_FALSE, &results) == SWITCH_STATUS_SUCCESS) { /* Get next OSP route */ - if ((status = osp_get_next(results)) == SWITCH_STATUS_SUCCESS) { + if ((status = osp_get_next(&results)) == SWITCH_STATUS_SUCCESS) { /* Get outbound info */ osp_get_outbound(channel, &outbound); } } /* Export OSP next info */ - osp_export_next(channel, status, &outbound, results); + osp_export_next(channel, status, &results, &outbound); - OSP_DEBUG_END; + OSP_TEST_END; } /* * Report OSP usage * param channel Originator channel - * param originator Originate profile - * param terminator Terminate profile + * param originator Originator profile + * param originatee Originatee profile * param results Routing info * return SWITCH_STATUS_SUCCESS Successful, SWITCH_STATUS_FALSE Failed */ static switch_status_t osp_do_report( switch_channel_t *channel, switch_caller_profile_t *originator, - switch_caller_profile_t *terminator, - osp_results_t *results) + switch_caller_profile_t *originatee) { + osp_results_t results; osp_usage_t usage; switch_status_t status = SWITCH_STATUS_SUCCESS; - OSP_DEBUG_START; + OSP_TEST_START; - if (osp_get_transaction(channel, SWITCH_TRUE, results) == SWITCH_STATUS_SUCCESS) { - /* Do not report usage for failed AuthReq */ - if (results->total) { + if (osp_get_transaction(channel, SWITCH_TRUE, &results) == SWITCH_STATUS_SUCCESS) { + if (results.total) { /* Get usage info */ - osp_get_usage(channel, originator, terminator, results, &usage); + osp_get_usage(channel, originator, originatee, &results, &usage); /* Log usage info */ - osp_log_usageind(results, &usage); + osp_log_usageind(&results, &usage); /* Report OSP usage */ - status = osp_report_usage(results, &usage); + status = osp_report_usage(&results, &usage); } else { - OSP_DEBUG_MSG("Do not report usage"); + /* Do not report usage for failed AuthReq */ + OSP_TEST_MSG("Do not report usage"); } } - OSP_DEBUG_END; + OSP_TEST_END; return status; } +/* + * Log variables, copy from FS info application, only for debug purpose + * param session Session + */ +void osp_log_info( + switch_core_session_t *session) +{ + switch_event_t *event; + char *buffer; + + if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(switch_core_session_get_channel(session), event); + switch_event_serialize(event, &buffer, SWITCH_FALSE); + switch_assert(buffer); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ALERT, "CHANNEL_DATA:\n%s\n", buffer); + switch_event_destroy(&event); + free(buffer); + } +} + /* * OSP module CLI command * Macro expands to: @@ -2409,23 +2698,23 @@ SWITCH_STANDARD_API(osp_cli_function) osp_profile_t *profile; char *loglevel; - OSP_DEBUG_START; + OSP_TEST_START; if (session) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "This function cannot be called from the dialplan.\n"); - OSP_DEBUG_END; + OSP_ERROR("%s", "This function cannot be called from the dialplan."); + OSP_TEST_END; return SWITCH_STATUS_FALSE; } if (switch_strlen_zero(cmd)) { stream->write_function(stream, "Usage: osp status\n"); - OSP_DEBUG_END; + OSP_TEST_END; return SWITCH_STATUS_SUCCESS; } if (!(params = switch_safe_strdup(cmd))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate parameters\n"); - OSP_DEBUG_END; + OSP_CRIT("%s", "Failed to duplicate parameters"); + OSP_TEST_END; return SWITCH_STATUS_MEMERR; } @@ -2498,7 +2787,7 @@ SWITCH_STANDARD_API(osp_cli_function) stream->write_function(stream, " ssl-lifetime: %d\n", profile->lifetime); stream->write_function(stream, " http-max-connections: %d\n", profile->maxconnect); stream->write_function(stream, " http-persistence: %d\n", profile->persistence); - stream->write_function(stream, " http-retry-dalay: %d\n", profile->retrydelay); + stream->write_function(stream, " http-retry-delay: %d\n", profile->retrydelay); stream->write_function(stream, " http-retry-limit: %d\n", profile->retrylimit); stream->write_function(stream, " http-timeout: %d\n", profile->timeout); switch (profile->workmode) { @@ -2514,6 +2803,9 @@ SWITCH_STANDARD_API(osp_cli_function) case OSP_SRV_NPQUERY: stream->write_function(stream, " service-type: npquery\n"); break; + case OSP_SRV_CNAMQUERY: + stream->write_function(stream, " service-type: cnamquery\n"); + break; case OSP_SRV_VOICE: default: stream->write_function(stream, " service-type: voice\n"); @@ -2531,7 +2823,7 @@ SWITCH_STANDARD_API(osp_cli_function) switch_safe_free(params); - OSP_DEBUG_END; + OSP_TEST_END; return SWITCH_STATUS_SUCCESS; } @@ -2546,32 +2838,29 @@ SWITCH_STANDARD_APP(osp_lookup_function) int argc = 0; char *argv[2] = { 0 }; char *params = NULL; - osp_results_t results; + const char *profile; - OSP_DEBUG_START; + OSP_TEST_START; if (osp_global.shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "OSP application inavailable\n"); + OSP_WARN("%s", "OSP application unavailable"); } else if (!(channel = switch_core_session_get_channel(session))) { /* Make sure there is a valid channel when starting the OSP application */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to find origiantor channel\n"); + OSP_CRIT("%s", "Failed to find channel"); } else if (!(params = switch_core_session_strdup(session, data))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to alloc parameters\n"); + OSP_CRIT("%s", "Failed to allocate parameters"); } else { - memset(&results, 0, sizeof(osp_results_t)); if ((argc = switch_separate_string(params, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - results.profile = argv[0]; + profile = argv[0]; } else { - results.profile = OSP_DEF_PROFILE; + profile = OSP_DEF_PROFILE; } - results.transaction = OSP_INVALID_HANDLE; - results.protocol = OSPC_PROTNAME_UNKNOWN; /* Do OSP lookup */ - osp_do_lookup(channel, &results); + osp_do_lookup(channel, profile); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -2581,24 +2870,20 @@ SWITCH_STANDARD_APP(osp_lookup_function) SWITCH_STANDARD_APP(osp_next_function) { switch_channel_t *channel; - osp_results_t results; - OSP_DEBUG_START; + OSP_TEST_START; if (osp_global.shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "OSP application inavailable\n"); + OSP_WARN("%s", "OSP application unavailable"); } else if (!(channel = switch_core_session_get_channel(session))) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to find origiantor channel\n"); + /* Make sure there is a valid channel when starting the OSP application */ + OSP_CRIT("%s", "Failed to find originator channel"); } else { - memset(&results, 0, sizeof(osp_results_t)); - results.transaction = OSP_INVALID_HANDLE; - results.protocol = OSPC_PROTNAME_UNKNOWN; - /* Do OSP next */ - osp_do_next(channel, &results); + osp_do_next(channel); } - OSP_DEBUG_END; + OSP_TEST_END; } /* @@ -2611,39 +2896,33 @@ static switch_status_t osp_on_reporting( { switch_channel_t *channel; switch_caller_profile_t *originator; - switch_caller_profile_t *terminator; - osp_results_t results; + switch_caller_profile_t *originatee; switch_status_t status = SWITCH_STATUS_FALSE; - OSP_DEBUG_START; + OSP_TEST_START; if (osp_global.shutdown) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OSP application inavailable\n"); + OSP_CRIT("%s", "OSP application unavailable"); } else if (!(channel = switch_core_session_get_channel(session))) { /* Make sure there is a valid channel when starting the OSP application */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to find origiantor channel\n"); + OSP_CRIT("%s", "Failed to find channel"); + } else if (!(originator = switch_channel_get_caller_profile(channel))) { + OSP_CRIT("%s", "Failed to find profile"); } else if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) { /* A-leg */ - OSP_DEBUG_MSG("A-leg"); + OSP_TEST_MSG("A-leg"); - /* Get originator profile */ - if ((originator = switch_channel_get_caller_profile(channel))) { - /* Get terminator profile, may be NULL */ - terminator = switch_channel_get_originatee_caller_profile(channel); + /* Originatee profile */ + originatee = switch_channel_get_originatee_caller_profile(channel); - memset(&results, 0, sizeof(osp_results_t)); - results.transaction = OSP_INVALID_HANDLE; - results.protocol = OSPC_PROTNAME_UNKNOWN; - - /* Do OSP usage report */ - status = osp_do_report(channel, originator, terminator, &results); - } + /* Do OSP usage report */ + status = osp_do_report(channel, originator, originatee); } else { /* B-leg */ - OSP_DEBUG_MSG("B-leg"); + OSP_TEST_MSG("B-leg"); } - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2683,11 +2962,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load) switch_application_interface_t *app_interface; switch_status_t status = SWITCH_STATUS_SUCCESS; - OSP_DEBUG_START; + OSP_TEST_START; /* Load OSP module configuration */ if ((status = osp_load_config(pool)) != SWITCH_STATUS_SUCCESS) { - OSP_DEBUG_END; + OSP_TEST_END; return status; } @@ -2703,12 +2982,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load) /* Add OSP module applications */ SWITCH_ADD_APP(app_interface, "osplookup", "Perform an OSP lookup", "Perform an OSP lookup", osp_lookup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); - SWITCH_ADD_APP(app_interface, "ospnext", "Retrive next OSP route", "Retrive next OSP route", osp_next_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); + SWITCH_ADD_APP(app_interface, "ospnext", "Retrieve next OSP route", "Retrieve next OSP route", osp_next_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); /* Add OSP module state handlers */ switch_core_add_state_handler(&osp_handlers); - OSP_DEBUG_END; + OSP_TEST_END; /* Indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; @@ -2721,7 +3000,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load) */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_osp_shutdown) { - OSP_DEBUG_START; + OSP_TEST_START; /* Shutdown OSP module */ osp_global.shutdown = SWITCH_TRUE; @@ -2729,10 +3008,10 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_osp_shutdown) /* Cleanup OSP client end */ osp_cleanup_osptk(); - /* Remoeve OSP module state handlers */ + /* Remove OSP module state handlers */ switch_core_remove_state_handler(&osp_handlers); - OSP_DEBUG_END; + OSP_TEST_END; return SWITCH_STATUS_SUCCESS; } @@ -2747,4 +3026,3 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_osp_shutdown) * For VIM: * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet */ - diff --git a/src/mod/applications/mod_translate/mod_translate.c b/src/mod/applications/mod_translate/mod_translate.c index b3f9e96ad5..5fbf8fbe32 100644 --- a/src/mod/applications/mod_translate/mod_translate.c +++ b/src/mod/applications/mod_translate/mod_translate.c @@ -230,44 +230,25 @@ SWITCH_STANDARD_APP(translate_app_function) char *argv[32] = { 0 }; char *mydata = NULL; char *translated = NULL; - switch_channel_t *channel = switch_core_session_get_channel(session); - switch_memory_pool_t *pool = NULL; - switch_event_t *event = NULL; + switch_channel_t *channel = switch_core_session_get_channel(session); - switch_assert(session); - - if (!(mydata = switch_core_session_strdup(session, data))) { - goto end; + if (zstr(data)) { + return; } - if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { - char *areacode = switch_core_get_variable("default_areacode"); + mydata = switch_core_session_strdup(session, data); - if (session) { - pool = switch_core_session_get_pool(session); - } else { - switch_core_new_memory_pool(&pool); - switch_event_create(&event, SWITCH_EVENT_MESSAGE); + argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); - if (zstr(areacode)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "no default_areacode set, using default of 777\n"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "areacode", "777"); - } else { - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "areacode", areacode); - } - } - - translate_number(argv[0], argv[1], &translated, session, event, NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Translated: %s\n", translated); - - switch_channel_set_variable_var_check(channel, "translated", translated, SWITCH_FALSE); + if (!argc) { + return; } -end: - if (pool) { - switch_core_destroy_memory_pool(&pool); - } + translate_number(argv[0], argv[1], &translated, session, NULL, NULL); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Translated: %s\n", translated); + + switch_channel_set_variable_var_check(channel, "translated", translated, SWITCH_FALSE); return; } @@ -279,7 +260,6 @@ SWITCH_STANDARD_DIALPLAN(translate_dialplan_hunt) char *translated_cid_num = NULL; char *translate_profile = NULL; char *areacode = NULL; - switch_event_t *event = NULL; if (!caller_profile) { if (!(caller_profile = switch_channel_get_caller_profile(channel))) { @@ -292,16 +272,20 @@ SWITCH_STANDARD_DIALPLAN(translate_dialplan_hunt) caller_profile->caller_id_name, caller_profile->caller_id_number, caller_profile->destination_number); if ((translate_profile = (char *) switch_channel_get_variable(channel, "translate_profile"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "using translate_profile variable [%s] for translate profile\n", translate_profile); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "using translate_profile variable [%s] for translate profile\n", translate_profile); } else if ((translate_profile = (char *) switch_channel_get_variable(channel, "country"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "using country variable [%s] for translate profile\n", translate_profile); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "using country variable [%s] for translate profile\n", translate_profile); } else if ((translate_profile = (char *) switch_channel_get_variable(channel, "default_country"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "using default_country variable [%s] for translate profile\n", translate_profile); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "using default_country variable [%s] for translate profile\n", translate_profile); } else { translate_profile = "US"; } areacode = (char *) switch_channel_get_variable(channel, "areacode"); + if (zstr(areacode)) { areacode = (char *) switch_channel_get_variable(channel, "default_areacode"); if (!zstr(areacode)) { @@ -309,8 +293,8 @@ SWITCH_STANDARD_DIALPLAN(translate_dialplan_hunt) } } - translate_number((char *) caller_profile->destination_number, translate_profile, &translated_dest, session, event, NULL); - translate_number((char *) caller_profile->caller_id_number, translate_profile, &translated_cid_num, session, event, NULL); + translate_number((char *) caller_profile->destination_number, translate_profile, &translated_dest, session, NULL, NULL); + translate_number((char *) caller_profile->caller_id_number, translate_profile, &translated_cid_num, session, NULL, NULL); /* maybe we should translate ani/aniii here too? */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Profile: [%s] Translated Destination: [%s] Translated CID: [%s]\n", translate_profile, translated_dest, translated_cid_num); @@ -338,8 +322,10 @@ SWITCH_STANDARD_API(translate_function) int argc = 0; if (zstr(cmd)) { - goto usage; + stream->write_function(stream, "USAGE: %s\n", TRANSLATE_SYNTAX); + return SWITCH_STATUS_SUCCESS; } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", cmd); mydata = strdup(cmd); @@ -365,18 +351,12 @@ SWITCH_STANDARD_API(translate_function) } free(mydata); -end: - if (!session) { - if (pool) { - switch_core_destroy_memory_pool(&pool); - } + + if (pool) { + switch_core_destroy_memory_pool(&pool); } return SWITCH_STATUS_SUCCESS; - -usage: - stream->write_function(stream, "USAGE: %s\n", TRANSLATE_SYNTAX); - goto end; } SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_translate_shutdown) diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 43917d88e3..f2e2b3a1d7 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -28,7 +28,7 @@ * John Wehle (john@feith.com) * Raymond Chandler * Kristin King - * Emmanuel Schmidbauer + * Emmanuel Schmidbauer * * mod_voicemail.c -- Voicemail Module * @@ -181,6 +181,7 @@ struct vm_profile { switch_bool_t auto_playback_recordings; switch_bool_t db_password_override; switch_bool_t allow_empty_password_auth; + switch_bool_t send_full_vm_header; switch_thread_rwlock_t *rwlock; switch_memory_pool_t *pool; uint32_t flags; @@ -689,6 +690,7 @@ vm_profile_t *profile_set_config(vm_profile_t *profile) SWITCH_CONFIG_SET_ITEM(profile->config[i++], "allow-empty-password-auth", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->allow_empty_password_auth, SWITCH_TRUE, NULL, NULL, NULL); SWITCH_CONFIG_SET_ITEM(profile->config[i++], "auto-playback-recordings", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->auto_playback_recordings, SWITCH_FALSE, NULL, NULL, NULL); + SWITCH_CONFIG_SET_ITEM(profile->config[i++], "send-full-vm-header", SWITCH_CONFIG_BOOL, CONFIG_RELOADABLE, &profile->send_full_vm_header, SWITCH_FALSE, NULL, NULL, NULL); switch_assert(i < VM_PROFILE_CONFIGITEM_COUNT); @@ -1935,11 +1937,13 @@ static void update_mwi(vm_profile_t *profile, const char *id, const char *domain switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", yn); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Update-Reason", update_reason); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", id, domain_name); - /* - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, - total_new_urgent_messages, total_saved_urgent_messages); - */ - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); + + if (profile->send_full_vm_header) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d (%d/%d)", total_new_messages, total_saved_messages, + total_new_urgent_messages, total_saved_urgent_messages); + } else { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", "%d/%d", total_new_messages, total_saved_messages); + } switch_event_fire(&event); diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index e59565eec7..959311b58b 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -1244,27 +1244,27 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) codec_interface->implementations->codec_control = switch_opus_control; settings.stereo = 1; - if (x < 2) { - dft_fmtp = gen_fmtp(&settings, pool); - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 116, /* the IANA code number */ - "opus",/* the IANA code name */ - dft_fmtp, /* default fmtp to send (can be overridden by the init function) */ - rate, /* samples transferred per second */ - rate, /* actual samples transferred per second */ - bits, /* bits transferred per second */ - mss, /* number of microseconds per frame */ - samples, /* number of samples per frame */ - bytes * 2, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 2,/* number of channels represented */ - 1, /* number of frames per network packet */ - switch_opus_init, /* function to initialize a codec handle using this implementation */ - switch_opus_encode, /* function to encode raw data into encoded data */ - switch_opus_decode, /* function to decode encoded data into raw data */ - switch_opus_destroy); /* deinitalize a codec handle using this implementation */ - codec_interface->implementations->codec_control = switch_opus_control; - } + + dft_fmtp = gen_fmtp(&settings, pool); + switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ + 116, /* the IANA code number */ + "opus",/* the IANA code name */ + dft_fmtp, /* default fmtp to send (can be overridden by the init function) */ + rate, /* samples transferred per second */ + rate, /* actual samples transferred per second */ + bits, /* bits transferred per second */ + mss, /* number of microseconds per frame */ + samples, /* number of samples per frame */ + bytes * 2, /* number of bytes per frame decompressed */ + 0, /* number of bytes per frame compressed */ + 2,/* number of channels represented */ + 1, /* number of frames per network packet */ + switch_opus_init, /* function to initialize a codec handle using this implementation */ + switch_opus_encode, /* function to encode raw data into encoded data */ + switch_opus_decode, /* function to decode encoded data into raw data */ + switch_opus_destroy); /* deinitalize a codec handle using this implementation */ + codec_interface->implementations->codec_control = switch_opus_control; + bytes *= 2; samples *= 2; mss *= 2; diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 9e952f2196..72c29a9a5d 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -945,7 +945,7 @@ static int get_codecs(struct private_object *tech_pvt) } if (codec_string) { - if ((tech_pvt->num_codecs = switch_loadable_module_get_codecs_sorted(tech_pvt->codecs, + if ((tech_pvt->num_codecs = switch_loadable_module_get_codecs_sorted(tech_pvt->codecs, NULL, SWITCH_MAX_CODECS, codec_order_p, codec_order_last)) <= 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO codecs?\n"); return 0; diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 99e83add97..ce9da85965 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -142,7 +142,7 @@ static switch_status_t tech_init(loopback_private_t *tech_pvt, switch_core_sessi if ((var = switch_channel_get_variable(channel, "loopback_initial_codec"))) { char *dup = switch_core_session_strdup(session, var); uint32_t bit, channels; - iananame = switch_parse_codec_buf(dup, &interval, &rate, &bit, &channels, &codec_modname); + iananame = switch_parse_codec_buf(dup, &interval, &rate, &bit, &channels, &codec_modname, NULL); } } diff --git a/src/mod/endpoints/mod_opal/mod_opal.cpp b/src/mod/endpoints/mod_opal/mod_opal.cpp index 9e52eddefb..fd414d7675 100644 --- a/src/mod/endpoints/mod_opal/mod_opal.cpp +++ b/src/mod/endpoints/mod_opal/mod_opal.cpp @@ -730,7 +730,7 @@ void FSConnection::SetCodecs() { char *codec_order[SWITCH_MAX_CODECS]; int codec_order_last = switch_separate_string((char *)codec_string.GetPointer(), ',', codec_order, SWITCH_MAX_CODECS); - numCodecs = switch_loadable_module_get_codecs_sorted(codecs, SWITCH_MAX_CODECS, codec_order, codec_order_last); + numCodecs = switch_loadable_module_get_codecs_sorted(codecs, NULL, SWITCH_MAX_CODECS, codec_order, codec_order_last); } for (int i = 0; i < numCodecs; i++) { diff --git a/src/mod/endpoints/mod_skinny/skinny_api.c b/src/mod/endpoints/mod_skinny/skinny_api.c index aba3abf97a..f9f734f630 100644 --- a/src/mod/endpoints/mod_skinny/skinny_api.c +++ b/src/mod/endpoints/mod_skinny/skinny_api.c @@ -94,6 +94,7 @@ static switch_status_t skinny_api_list_devices(const char *line, const char *cur return status; } if (!(argc = switch_separate_string(myline, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) || argc < 4) { + switch_safe_free(myline); return status; } @@ -115,6 +116,8 @@ static switch_status_t skinny_api_list_devices(const char *line, const char *cur status = SWITCH_STATUS_SUCCESS; } + switch_safe_free(myline); + return status; } diff --git a/src/mod/endpoints/mod_skinny/skinny_server.c b/src/mod/endpoints/mod_skinny/skinny_server.c index ad635ab2e2..b1da93b4c4 100644 --- a/src/mod/endpoints/mod_skinny/skinny_server.c +++ b/src/mod/endpoints/mod_skinny/skinny_server.c @@ -116,9 +116,6 @@ switch_status_t skinny_create_incoming_session(listener_t *listener, uint32_t *l if (!button || !button->shortname[0]) { skinny_log_l(listener, SWITCH_LOG_CRIT, "Line %d not found on device\n", *line_instance_p); - if ( button ) { - switch_safe_free(button); - } goto error; } @@ -202,17 +199,13 @@ error: } listener->profile->ib_failed_calls++; - if ( button ) { - switch_safe_free(button); - } + switch_safe_free(button); return SWITCH_STATUS_FALSE; done: *session = nsession; listener->profile->ib_calls++; - if ( button ) { - switch_safe_free(button); - } + switch_safe_free(button); return SWITCH_STATUS_SUCCESS; } @@ -1246,27 +1239,27 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r listener->soft_key_set_set = switch_core_strdup(profile->pool, value); } else if (!strcasecmp(name, "ext-voicemail")) { if (!listener->ext_voicemail || strcmp(value,listener->ext_voicemail)) { - listener->ext_voicemail = switch_core_strdup(profile->pool, value); + listener->ext_voicemail = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-redial")) { if (!listener->ext_redial || strcmp(value,listener->ext_redial)) { - listener->ext_redial = switch_core_strdup(profile->pool, value); + listener->ext_redial = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-meetme")) { if (!listener->ext_meetme || strcmp(value,listener->ext_meetme)) { - listener->ext_meetme = switch_core_strdup(profile->pool, value); + listener->ext_meetme = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-pickup")) { if (!listener->ext_pickup || strcmp(value,listener->ext_pickup)) { - listener->ext_pickup = switch_core_strdup(profile->pool, value); + listener->ext_pickup = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-cfwdall")) { if (!listener->ext_cfwdall || strcmp(value,listener->ext_cfwdall)) { - listener->ext_cfwdall = switch_core_strdup(profile->pool, value); + listener->ext_cfwdall = switch_core_strdup(listener->pool, value); } } else if (!strcasecmp(name, "ext-autodial")) { if (!listener->ext_autodial || strcmp(value,listener->ext_autodial)) { - listener->ext_autodial = switch_core_strdup(profile->pool, value); + listener->ext_autodial = switch_core_strdup(listener->pool, value); } } } @@ -1531,11 +1524,12 @@ switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_mess } if ( !session ) { skinny_log_l_msg(listener, SWITCH_LOG_CRIT, "Unable to handle speed dial stimulus message, couldn't create incoming session.\n"); + switch_safe_free(button_speed_dial); return SWITCH_STATUS_FALSE; } skinny_session_process_dest(session, listener, line_instance, button_speed_dial->line, '\0', 0); - switch_safe_free(button_speed_dial); } + switch_safe_free(button_speed_dial); break; case SKINNY_BUTTON_HOLD: session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index bc20ac2968..5dfbfe87c8 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -501,6 +501,8 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending CANCEL to %s\n", switch_channel_get_name(channel)); if (!tech_pvt->got_bye) { switch_channel_set_variable(channel, "sip_hangup_disposition", "send_cancel"); + switch_channel_set_variable(channel, "sip_invite_failure_status", "487"); + switch_channel_set_variable(channel, "sip_invite_failure_phrase", "CANCEL"); } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { nua_cancel(tech_pvt->nh, @@ -644,6 +646,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) const char *val; const char *b_sdp = NULL; int is_proxy = 0; + int is_3pcc_proxy = 0; int is_3pcc = 0; char *sticky = NULL; const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); @@ -660,7 +663,8 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE); switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY nomedia - sending ack\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY nomedia - sending ack, SDP:\n%s\n", tech_pvt->mparams.local_sdp_str); + nua_ack(tech_pvt->nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), @@ -683,9 +687,10 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE); is_proxy = (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)); - is_3pcc = (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)); + is_3pcc_proxy = (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)); + is_3pcc = (!sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)); - if (b_sdp && is_proxy && !is_3pcc) { + if (b_sdp && is_proxy && !is_3pcc_proxy) { switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { @@ -696,32 +701,33 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } } else { /* This if statement check and handles the 3pcc proxy mode */ + if (is_3pcc) { + switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); + tech_pvt->mparams.local_sdp_str = NULL; + switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); + switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + } else if (is_3pcc_proxy) { if (!(sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY))) { switch_channel_set_flag(channel, CF_3PCC); } - if (!is_proxy) { - switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - tech_pvt->mparams.local_sdp_str = NULL; + switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); - switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); - switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); - } else { - switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); - - if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { - switch_core_media_patch_sdp(tech_pvt->session); - if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; - } + if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { + switch_core_media_patch_sdp(tech_pvt->session); + if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; } } + } + if (is_3pcc || is_3pcc_proxy) { /* Send the 200 OK */ if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX); + if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, @@ -747,31 +753,32 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END()); } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Sent a 200 OK, waiting for ACK\n"); + switch_safe_free(extra_headers); } - /* Unlock the session signal to allow the ack to make it in */ - // Maybe we should timeout? - switch_mutex_unlock(tech_pvt->sofia_mutex); + if (is_3pcc_proxy) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Sent a 200 OK, waiting for ACK\n"); + /* Unlock the session signal to allow the ack to make it in */ + // Maybe we should timeout? + switch_mutex_unlock(tech_pvt->sofia_mutex); - while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) { - switch_cond_next(); + while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) { + switch_cond_next(); + } + + /* Regain lock on sofia */ + switch_mutex_lock(tech_pvt->sofia_mutex); + + if (is_proxy) { + sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); + sofia_clear_flag(tech_pvt, TFLAG_3PCC); + switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_ANSWER); + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n"); + return SWITCH_STATUS_SUCCESS; } - - /* Regain lock on sofia */ - switch_mutex_lock(tech_pvt->sofia_mutex); - - if(is_proxy) { - sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); - sofia_clear_flag(tech_pvt, TFLAG_3PCC); - // This sends the message to the other leg that causes it to call the TFLAG_3PCC_INVITE code at the start of this function. - // Is there another message it would be better to hang this on though? - switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_ANSWER); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n"); - return SWITCH_STATUS_SUCCESS; } if ((is_proxy && !b_sdp) || sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || @@ -1427,8 +1434,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT: { + + if (zstr(msg->string_arg)) { /* no sdp requires proxy of ack */ + switch_core_session_t *other_session; + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK); + } + switch_core_session_rwunlock(other_session); + } + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Sending media re-direct:\n%s\n", - switch_channel_get_name(channel), msg->string_arg); + switch_channel_get_name(channel), switch_str_nil(msg->string_arg)); switch_core_media_set_local_sdp(session, msg->string_arg, SWITCH_TRUE); if (zstr(tech_pvt->mparams.local_sdp_str)) { @@ -1835,6 +1855,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); } else if (ua && ((switch_stristr("aastra", ua) && !switch_stristr("Intelligate", ua)) || (switch_stristr("cisco/spa50", ua) || switch_stristr("cisco/spa525", ua)) || + switch_stristr("cisco/spa30", ua) || switch_stristr("Grandstream GXP", ua) || switch_stristr("Yealink", ua) || switch_stristr("Mitel", ua) || switch_stristr("Panasonic", ua))) { snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" ", name, number, tech_pvt->profile->printable_sipip); @@ -2097,6 +2118,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi switch_mutex_unlock(tech_pvt->sofia_mutex); while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) { + switch_ivr_parse_all_events(session); switch_cond_next(); } @@ -2208,13 +2230,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi const char *val = NULL; const char *call_info = switch_channel_get_variable(channel, "presence_call_info_full"); const char *b_sdp = NULL; - int is_proxy = 0, is_3pcc = 0; + int is_proxy = 0, is_3pcc_proxy = 0; int send_sip_code = 183; const char * p_send_sip_msg = sip_183_Session_progress; b_sdp = switch_channel_get_variable(channel, SWITCH_B_SDP_VARIABLE); is_proxy = (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)); - is_3pcc = (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)); + is_3pcc_proxy = (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)); // send 180 instead of 183 if variable "early_use_180" is "true" if (switch_true(switch_channel_get_variable(channel, "early_use_180"))) { @@ -2222,7 +2244,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi p_send_sip_msg = sip_180_Ringing; } - if (b_sdp && is_proxy && !is_3pcc) { + if (b_sdp && is_proxy && !is_3pcc_proxy) { switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { @@ -2232,84 +2254,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi goto end_lock; } } - } else { - if (is_3pcc) { - switch_channel_set_flag(channel, CF_3PCC); - - if(!is_proxy) { - switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); - tech_pvt->mparams.local_sdp_str = NULL; - - switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0); - switch_core_session_set_ice(session); - switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL , 0, NULL, 0); - } else { - switch_core_media_set_local_sdp(session, b_sdp, SWITCH_TRUE); - - if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { - switch_core_media_patch_sdp(tech_pvt->session); - if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "failed to activate rtp\n"); - status = SWITCH_STATUS_FALSE; - goto end_lock; - } - } - } - /* Send the 183 */ - if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { - char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX); - if (sofia_use_soa(tech_pvt)) { - - nua_respond(tech_pvt->nh, send_sip_code, p_send_sip_msg, - TAG_IF(is_proxy, NUTAG_AUTOANSWER(0)), - SIPTAG_CONTACT_STR(tech_pvt->profile->url), - SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str), - TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), - SOATAG_REUSE_REJECTED(1), - SOATAG_RTP_SELECT(1), - SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), - TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), - TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote), - SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END()); - } else { - nua_respond(tech_pvt->nh, send_sip_code, p_send_sip_msg, - NUTAG_MEDIA_ENABLE(0), - SIPTAG_CONTACT_STR(tech_pvt->profile->url), - TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), - TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), - SIPTAG_CONTENT_TYPE_STR("application/sdp"), - SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), - TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote), - SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END()); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Sent a 183 SESSION PROGRESS, waiting for PRACK\n"); - switch_safe_free(extra_headers); - } - - /* Unlock the session signal to allow the ack to make it in */ - // Maybe we should timeout? - switch_mutex_unlock(tech_pvt->sofia_mutex); - - while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) { - switch_cond_next(); - } - - /* Regain lock on sofia */ - switch_mutex_lock(tech_pvt->sofia_mutex); - - if(is_proxy || !switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE)) { - sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); - sofia_clear_flag(tech_pvt, TFLAG_3PCC); - // This sends the message to the other leg that causes it to call the TFLAG_3PCC_INVITE code at the start of this function. - // Is there another message it would be better to hang this on though? - switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_ANSWER); - } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for PRACK\n"); - status = SWITCH_STATUS_SUCCESS; - goto end_lock; - } } if (!sofia_test_flag(tech_pvt, TFLAG_ANS) && !sofia_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 9a4dca3147..1ff30451da 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -344,6 +344,7 @@ typedef enum { TFLAG_REINVITED, TFLAG_PASS_ACK, TFLAG_KEEPALIVE, + TFLAG_SKIP_EARLY, /* No new flags below this line */ TFLAG_MAX } TFLAGS; @@ -738,6 +739,8 @@ struct sofia_profile { char *tls_verify_in_subjects_str; su_strlst_t *tls_verify_in_subjects; uint32_t sip_force_expires; + uint32_t sip_force_expires_min; + uint32_t sip_force_expires_max; uint32_t sip_expires_max_deviation; uint32_t sip_expires_late_margin; uint32_t sip_subscription_max_deviation; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index f2f458ffec..568f2cd7ae 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1279,30 +1279,41 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro switch_safe_free(dup); } -static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt) +static void tech_send_ack(nua_handle_t *nh, private_object_t *tech_pvt, const char *r_sdp) { const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from"); const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to"); - + int soa = sofia_use_soa(tech_pvt); if (sofia_test_pflag(tech_pvt->profile, PFLAG_TRACK_CALLS)) { const char *invite_full_via = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_via"); const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri"); + nua_ack(nh, TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_IF((zstr(tech_pvt->user_via) && !zstr(invite_full_via)), SIPTAG_VIA_STR(invite_full_via)), TAG_IF(!zstr(invite_route_uri), SIPTAG_ROUTE_STR(invite_route_uri)), + TAG_IF(r_sdp && soa, SOATAG_USER_SDP_STR(r_sdp)), + TAG_IF(r_sdp && soa, SOATAG_REUSE_REJECTED(1)), + TAG_IF(r_sdp && soa, SOATAG_AUDIO_AUX("cn telephone-event")), + TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)), + TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)), TAG_END()); - - } else { nua_ack(nh, TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)), TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), + TAG_IF(r_sdp && soa, SOATAG_USER_SDP_STR(r_sdp)), + TAG_IF(r_sdp && soa, SOATAG_REUSE_REJECTED(1)), + TAG_IF(r_sdp && soa, SOATAG_AUDIO_AUX("cn telephone-event")), + TAG_IF(r_sdp && !soa, SIPTAG_CONTENT_TYPE_STR("application/sdp")), + TAG_IF(r_sdp && !soa, SIPTAG_PAYLOAD_STR(r_sdp)), + TAG_IF(r_sdp && !soa, NUTAG_MEDIA_ENABLE(0)), TAG_END()); } @@ -1531,6 +1542,8 @@ static void our_sofia_event_callback(nua_event_t event, if (sip && channel) { switch_channel_set_variable(channel, "sip_hangup_disposition", "recv_cancel"); + switch_channel_set_variable(channel, "sip_invite_failure_status", "487"); + switch_channel_set_variable(channel, "sip_invite_failure_phrase", "CANCEL"); if (sip->sip_reason) { char *reason_header = sip_header_as_string(nh->nh_home, (void *) sip->sip_reason); @@ -1552,6 +1565,25 @@ static void our_sofia_event_callback(nua_event_t event, case nua_i_ack: { if (channel && sip) { + const char *r_sdp = NULL; + + if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK) && sip->sip_payload && sip->sip_payload->pl_data) { + r_sdp = sip->sip_payload->pl_data; + + if (tech_pvt->mparams.last_sdp_str) { + tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str; + } + tech_pvt->mparams.last_sdp_str = NULL; + + + if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) { + switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data); + tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data); + } else { + tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str; + } + } + if (sip->sip_to && sip->sip_to->a_tag) { switch_channel_set_variable(channel, "sip_to_tag", sip->sip_to->a_tag); } @@ -1579,11 +1611,10 @@ static void our_sofia_event_callback(nua_event_t event, sofia_clear_flag(tech_pvt, TFLAG_PASS_ACK); - if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { if (switch_core_session_compare(session, other_session)) { private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); - tech_send_ack(other_tech_pvt->nh, other_tech_pvt); + tech_send_ack(other_tech_pvt->nh, other_tech_pvt, r_sdp); } switch_core_session_rwunlock(other_session); } @@ -2027,15 +2058,18 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) sofia_dispatch_event_t *de = *dep; switch_memory_pool_t *pool; //sofia_profile_t *profile = (*dep)->profile; - + switch_thread_data_t *td; switch_core_new_memory_pool(&pool); *dep = NULL; de->pool = pool; + td = switch_core_alloc(pool, sizeof(*td)); + td->func = sofia_msg_thread_run_once; + td->obj = de; - + switch_thread_pool_launch_thread(&td); } void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) @@ -4255,6 +4289,8 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->dtmf_duration = 100; profile->rtp_digit_delay = 40; profile->sip_force_expires = 0; + profile->sip_force_expires_min = 0; + profile->sip_force_expires_max = 0; profile->sip_expires_max_deviation = 0; profile->sip_expires_late_margin = 60; profile->sip_subscription_max_deviation = 0; @@ -5509,6 +5545,20 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { profile->sip_expires_late_margin = 60; } + } else if (!strcasecmp(var, "sip-force-expires-min")) { + int32_t sip_force_expires_min = atoi(val); + if (sip_force_expires_min >= 0) { + profile->sip_force_expires_min = sip_force_expires_min; + } else { + profile->sip_force_expires_min = 0; + } + } else if (!strcasecmp(var, "sip-force-expires-max")) { + int32_t sip_force_expires_max = atoi(val); + if (sip_force_expires_max >= 0) { + profile->sip_force_expires_max = sip_force_expires_max; + } else { + profile->sip_force_expires_max = 0; + } } else if (!strcasecmp(var, "sip-force-expires")) { int32_t sip_force_expires = atoi(val); if (sip_force_expires >= 0) { @@ -6039,7 +6089,6 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status tagi_t tags[]) { char *call_info = NULL; - if (sip && session) { switch_channel_t *channel = switch_core_session_get_channel(session); const char *uuid; @@ -6052,6 +6101,21 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_channel_clear_flag(channel, CF_REQ_MEDIA); + if (status < 200) { + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + + if (sofia_test_flag(other_tech_pvt, TFLAG_3PCC)) { + sofia_set_flag_locked(tech_pvt, TFLAG_SKIP_EARLY); + } + switch_core_session_rwunlock(other_session); + } + + if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)) { + return; + } + } + if (status >= 900) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s status %d received.\n", switch_channel_get_name(channel), status); @@ -6065,8 +6129,13 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status if (status >= 400) { char status_str[5]; switch_snprintf(status_str, sizeof(status_str), "%d", status); + switch_channel_set_variable(channel, "sip_invite_failure_status", status_str); + switch_channel_set_variable(channel, "sip_invite_failure_phrase", phrase); switch_channel_set_variable_partner(channel, "sip_invite_failure_status", status_str); switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", phrase); + } else { + switch_channel_set_variable_partner(channel, "sip_invite_failure_status", NULL); + switch_channel_set_variable_partner(channel, "sip_invite_failure_phrase", NULL); } if (status >= 400 && sip->sip_reason && sip->sip_reason->re_protocol && (!strcasecmp(sip->sip_reason->re_protocol, "Q.850") @@ -6411,6 +6480,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) && (has_t38 || status > 299)))) { if (sofia_test_flag(tech_pvt, TFLAG_SENT_UPDATE)) { + const char *wait_for_ack = switch_channel_get_variable(channel, "sip_wait_for_aleg_ack"); sofia_clear_flag_locked(tech_pvt, TFLAG_SENT_UPDATE); if ((uuid = switch_channel_get_partner_uuid(channel)) && (other_session = switch_core_session_locate(uuid))) { @@ -6426,7 +6496,22 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_core_media_proxy_remote_addr(session, NULL); } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n", status, phrase); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n%s\n", status, phrase, switch_str_nil(r_sdp)); + + if (switch_true(wait_for_ack)) { + switch_core_session_t *other_session; + + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { + if (switch_core_session_compare(session, other_session)) { + private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); + + if (!sofia_test_flag(tech_pvt, TFLAG_3PCC) && !sofia_test_flag(other_tech_pvt, TFLAG_3PCC)) { + sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK); + } + } + switch_core_session_rwunlock(other_session); + } + } if (status == 491 && (switch_channel_test_flag(tech_pvt->channel, CF_T38_PASSTHRU) || switch_channel_test_flag(channel, CF_PROXY_MODE))) { @@ -6910,8 +6995,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (channel && (status == 180 || status == 183) && switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { const char *full_to = NULL; - const char *val; - if ((val = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(val)) { + const char *var; + if ((var = switch_channel_get_variable(channel, "sip_auto_answer")) && switch_true(var) && + !((var = switch_channel_get_variable(channel, "sip_auto_answer_suppress_notify")) && switch_true(var))) { full_to = switch_str_nil(switch_channel_get_variable(channel, "sip_full_to")); nua_notify(nh, @@ -6955,6 +7041,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, break; case nua_callstate_proceeding: + if (sofia_test_flag(tech_pvt, TFLAG_SKIP_EARLY)) { + sofia_clear_flag_locked(tech_pvt, TFLAG_SKIP_EARLY); + goto done; + } + switch (status) { case 180: switch_channel_mark_ring_ready(channel); @@ -7058,8 +7149,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { if (switch_core_session_compare(session, other_session)) { private_object_t *other_tech_pvt = switch_core_session_get_private(other_session); - sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK); - send_ack = 0; + + if (!sofia_test_flag(tech_pvt, TFLAG_3PCC) && !sofia_test_flag(other_tech_pvt, TFLAG_3PCC)) { + sofia_set_flag(other_tech_pvt, TFLAG_PASS_ACK); + send_ack = 0; + } } switch_core_session_rwunlock(other_session); } @@ -7131,7 +7225,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_flag(channel, CF_MEDIA_SET); switch_core_media_activate_rtp(session); - + nua_ack(tech_pvt->nh, TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_CONTACT_STR(tech_pvt->reply_contact), @@ -7172,7 +7266,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (send_ack) { - tech_send_ack(nh, tech_pvt); + tech_send_ack(nh, tech_pvt, NULL); } else { ss_state = nua_callstate_ready; goto state_process; @@ -7395,10 +7489,6 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_mark_pre_answered(channel); sofia_set_flag(tech_pvt, TFLAG_SDP); - if (sofia_test_flag(tech_pvt, TFLAG_3PCC) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my PRACK\n"); - sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); - } match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); if (match) { @@ -10439,13 +10529,20 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia } } else { if (!zstr(bridge_uuid)) { - switch_channel_mark_hold(b_channel, SWITCH_FALSE); - tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid); - if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS) - && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(b_channel, event); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id); - switch_event_fire(&event); + if (sip->sip_replaces && sip->sip_replaces->rp_params && sip->sip_replaces->rp_call_id && switch_channel_test_flag(b_channel, CF_BRIDGED) && + switch_true(switch_find_parameter(*(sip->sip_replaces->rp_params), "early-only", switch_core_session_get_pool(session)))) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercept rejected\n", bridge_uuid); + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "hangup:CALL_REJECTED"); + } else { + switch_channel_mark_hold(b_channel, SWITCH_FALSE); + tech_pvt->caller_profile->destination_number = switch_core_sprintf(tech_pvt->caller_profile->pool, "answer,intercept:%s", bridge_uuid); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "call %s intercepted\n", bridge_uuid); + if (sofia_test_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS) && + switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INTERCEPTED) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(b_channel, event); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "intercepted_by", sip->sip_call_id->i_id); + switch_event_fire(&event); + } } } else { const char *b_app = switch_channel_get_variable(b_channel, SWITCH_CURRENT_APPLICATION_VARIABLE); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index a4ee3c080a..7f7d8efba3 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -1683,6 +1683,18 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu } } + if ( (( exp_var = atoi(switch_event_get_header_nil(*v_event, "sip-force-expires-min")) )) || + (( exp_var = profile->sip_force_expires_min )) ) { + if ( (exp_var > 0) && (exptime < exp_var) ) { + exptime = exp_var; + } + } + if ( (( exp_var = atoi(switch_event_get_header_nil(*v_event, "sip-force-expires-max")) )) || + (( exp_var = profile->sip_force_expires_max )) ) { + if ( (exp_var > 0) && (exptime > exp_var) ) { + exptime = exp_var; + } + } if ( (( exp_var = atoi(switch_event_get_header_nil(*v_event, "sip-force-expires")) )) || (( exp_var = profile->sip_force_expires )) ) { if (exp_var > 0) { diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index a9ba87bf48..e463bf3f83 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -515,7 +515,9 @@ SWITCH_STANDARD_APP(socket_function) switch_ivr_parse_all_events(session); - if (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var))) { + if (switch_channel_get_state(channel) != CS_HIBERNATE && + !switch_channel_test_flag(channel, CF_REDIRECT) && !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_RESET) + && (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { switch_channel_set_state(channel, CS_EXECUTE); } @@ -2771,7 +2773,9 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) channel = switch_core_session_get_channel(listener->session); } - if (channel && (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { + if (channel && switch_channel_get_state(channel) != CS_HIBERNATE && + !switch_channel_test_flag(channel, CF_REDIRECT) && !switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_RESET) && + (switch_test_flag(listener, LFLAG_RESUME) || ((var = switch_channel_get_variable(channel, "socket_resume")) && switch_true(var)))) { switch_channel_set_state(channel, CS_RESET); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c index ab9b65386b..4de71398f4 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_commands.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_commands.c @@ -148,5 +148,5 @@ void add_kz_commands(switch_loadable_module_interface_t **module_interface, swit SWITCH_ADD_API(api_interface, "kz_uuid_setvar_multi", UUID_SET_DESC, uuid_setvar_multi_function, UUID_MULTISET_SYNTAX); switch_console_set_complete("add kz_uuid_setvar_multi ::console::list_uuid"); SWITCH_ADD_API(api_interface, "kz_uuid_setvar", UUID_MULTISET_DESC, uuid_setvar_function, UUID_SET_SYNTAX); - switch_console_set_complete("add kz_uuid_setvar ::console::list_uuid"); + switch_console_set_complete("add kz_uuid_setvar ::console::list_uuid"); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c index e6453d6490..352edaae82 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_dptools.c @@ -141,7 +141,7 @@ SWITCH_STANDARD_APP(multiset_function) { arg = switch_core_session_strdup(session, arg); argc = switch_split(arg, delim, array); - + for(i = 0; i < argc; i++) { base_set(session, array[i], SWITCH_STACK_BOTTOM); } @@ -178,7 +178,7 @@ SWITCH_STANDARD_APP(unset_function) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UNSET [%s]\n", (char *) data); switch_channel_set_variable(switch_core_session_get_channel(session), data, NULL); } - + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(channel, event); switch_event_fire(&event); @@ -242,7 +242,7 @@ void add_kz_dptools(switch_loadable_module_interface_t **module_interface, switc SWITCH_ADD_APP(app_interface, "kz_unset", UNSET_SHORT_DESC, UNSET_LONG_DESC, unset_function, UNSET_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_multiunset", MULTISET_SHORT_DESC, MULTISET_LONG_DESC, multiunset_function, MULTIUNSET_SYNTAX, - SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); + SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); SWITCH_ADD_APP(app_interface, "kz_export", EXPORT_SHORT_DESC, EXPORT_LONG_DESC, export_function, EXPORT_SYNTAX, SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c index 00eb06a126..cf43ce1f45 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_event_stream.c @@ -37,7 +37,7 @@ static char *my_dup(const char *s) { size_t len = strlen(s) + 1; void *new = malloc(len); switch_assert(new); - + return (char *) memcpy(new, s, len); } @@ -58,21 +58,21 @@ static int is_private_header(const char *name) { static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *event, switch_hash_t *filter) { switch_event_header_t *header; - + if (switch_event_create_subclass(clone, SWITCH_EVENT_CLONE, event->subclass_name) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_GENERR; } - + (*clone)->event_id = event->event_id; (*clone)->event_user_data = event->event_user_data; (*clone)->bind_user_data = event->bind_user_data; (*clone)->flags = event->flags; - + for (header = event->headers; header; header = header->next) { if (event->subclass_name && !strcmp(header->name, "Event-Subclass")) { continue; } - + if (strncmp(header->name, globals.kazoo_var_prefix, globals.var_prefix_length) && filter && !switch_core_hash_find(filter, header->name) @@ -82,7 +82,7 @@ static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *e { continue; } - + if (header->idx) { int i; for (i = 0; i < header->idx; i++) { @@ -92,33 +92,33 @@ static switch_status_t kazoo_event_dup(switch_event_t **clone, switch_event_t *e switch_event_add_header_string(*clone, SWITCH_STACK_BOTTOM, header->name, header->value); } } - + if (event->body) { (*clone)->body = DUP(event->body); } - + (*clone)->key = event->key; - + return SWITCH_STATUS_SUCCESS; } static void event_handler(switch_event_t *event) { switch_event_t *clone = NULL; ei_event_stream_t *event_stream = (ei_event_stream_t *) event->bind_user_data; - + /* if mod_kazoo or the event stream isn't running dont push a new event */ if (!switch_test_flag(event_stream, LFLAG_RUNNING) || !switch_test_flag(&globals, LFLAG_RUNNING)) { return; } - + if (event->event_id == SWITCH_EVENT_CUSTOM) { ei_event_binding_t *event_binding = event_stream->bindings; unsigned short int found = 0; - + if (!event->subclass_name) { return; } - + while(event_binding != NULL) { if (event_binding->type == SWITCH_EVENT_CUSTOM) { if(event_binding->subclass_name @@ -238,9 +238,9 @@ static void *SWITCH_THREAD_FUNC event_stream_loop(switch_thread_t *thread, void } else { ei_x_new_with_version(&ebuf); } - + ei_encode_switch_event(&ebuf, event); - + if (globals.event_stream_preallocate > 0 && ebuf.buffsz > globals.event_stream_preallocate) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "increased event stream buffer size to %d\n", ebuf.buffsz); } diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_node.c b/src/mod/event_handlers/mod_kazoo/kazoo_node.c index 0ffd3ffdf0..1efe7e3e82 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_node.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_node.c @@ -1092,7 +1092,7 @@ static void *SWITCH_THREAD_FUNC handle_node(switch_thread_t *thread, void *obj) ei_x_new(&received_msg->buf); } } - + while (switch_queue_trypop(ei_node->send_msgs, &pop) == SWITCH_STATUS_SUCCESS && ++send_msg_count <= globals.send_msg_batch) { ei_send_msg_t *send_msg = (ei_send_msg_t *) pop; diff --git a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c index 1284118daf..127f849cdc 100644 --- a/src/mod/event_handlers/mod_kazoo/kazoo_utils.c +++ b/src/mod/event_handlers/mod_kazoo/kazoo_utils.c @@ -477,6 +477,9 @@ switch_hash_t *create_default_filter() { switch_core_hash_insert(filter, "whistle_application_name", "1"); switch_core_hash_insert(filter, "whistle_application_response", "1"); switch_core_hash_insert(filter, "whistle_event_name", "1"); + switch_core_hash_insert(filter, "kazoo_application_name", "1"); + switch_core_hash_insert(filter, "kazoo_application_response", "1"); + switch_core_hash_insert(filter, "kazoo_event_name", "1"); switch_core_hash_insert(filter, "sip_auto_answer_notify", "1"); switch_core_hash_insert(filter, "eavesdrop_group", "1"); switch_core_hash_insert(filter, "origination_caller_id_name", "1"); @@ -489,6 +492,21 @@ switch_hash_t *create_default_filter() { switch_core_hash_insert(filter, "effective_caller_id_number", "1"); switch_core_hash_insert(filter, "effective_callee_id_name", "1"); switch_core_hash_insert(filter, "effective_callee_id_number", "1"); + switch_core_hash_insert(filter, "variable_destination_number", "1"); + switch_core_hash_insert(filter, "variable_effective_callee_id_name", "1"); + switch_core_hash_insert(filter, "variable_effective_callee_id_number", "1"); + switch_core_hash_insert(filter, "variable_record_silence_hits", "1"); + switch_core_hash_insert(filter, "variable_refer_uuid", "1"); + switch_core_hash_insert(filter, "variable_sip_call_id", "1"); + switch_core_hash_insert(filter, "variable_sip_h_Referred-By", "1"); + switch_core_hash_insert(filter, "variable_sip_h_X-AUTH-PORT", "1"); + switch_core_hash_insert(filter, "variable_sip_loopback_req_uri", "1"); + switch_core_hash_insert(filter, "variable_sip_received_port", "1"); + switch_core_hash_insert(filter, "variable_sip_refer_to", "1"); + switch_core_hash_insert(filter, "variable_sip_req_host", "1"); + switch_core_hash_insert(filter, "variable_sip_req_uri", "1"); + switch_core_hash_insert(filter, "variable_transfer_source", "1"); + switch_core_hash_insert(filter, "variable_uuid", "1"); /* Registration headers */ switch_core_hash_insert(filter, "call-id", "1"); @@ -570,6 +588,7 @@ switch_hash_t *create_default_filter() { switch_core_hash_insert(filter, "variable_fax_timezone", "1"); switch_core_hash_insert(filter, "variable_fax_doc_id", "1"); switch_core_hash_insert(filter, "variable_fax_doc_database", "1"); + switch_core_hash_insert(filter, "variable_has_t38", "1"); /* Secure headers */ switch_core_hash_insert(filter, "variable_sdp_secure_savp_only", "1"); diff --git a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c index ebf3af3f8c..dd305fe911 100644 --- a/src/mod/event_handlers/mod_kazoo/mod_kazoo.c +++ b/src/mod/event_handlers/mod_kazoo/mod_kazoo.c @@ -53,16 +53,16 @@ static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { char ipbuf[25]; const char *ip_addr; ei_node_t *ei_node; - + switch_socket_addr_get(&sa, SWITCH_FALSE, globals.acceptor); - + port = switch_sockaddr_get_port(sa); ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - + stream->write_function(stream, "Running %s\n", VERSION); stream->write_function(stream, "Listening for new Erlang connections on %s:%u with cookie %s\n", ip_addr, port, globals.ei_cookie); stream->write_function(stream, "Registered as Erlang node %s, visible as %s\n", globals.ei_cnode.thisnodename, globals.ei_cnode.thisalivename); - + if (globals.ei_compat_rel) { stream->write_function(stream, "Using Erlang compatibility mode: %d\n", globals.ei_compat_rel); } @@ -75,7 +75,7 @@ static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { stream->write_function(stream, "Connected to:\n"); while(ei_node != NULL) { unsigned int year, day, hour, min, sec, delta; - + delta = (switch_micro_time_now() - ei_node->created_time) / 1000000; sec = delta % 60; min = delta / 60 % 60; @@ -88,14 +88,14 @@ static switch_status_t api_erlang_status(switch_stream_handle_t *stream) { } } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) { switch_hash_index_t *hi = NULL; int column = 0; - + for (hi = (switch_hash_index_t *)switch_core_hash_first_iter(globals.event_filter, hi); hi; hi = switch_core_hash_next(&hi)) { const void *key; void *val; @@ -106,20 +106,20 @@ static switch_status_t api_erlang_event_filter(switch_stream_handle_t *stream) { column = 0; } } - + if (++column > 2) { stream->write_function(stream, "\n"); column = 0; } - + stream->write_function(stream, "%-50s", globals.kazoo_var_prefix); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_nodes_list(switch_stream_handle_t *stream) { ei_node_t *ei_node; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { @@ -127,14 +127,14 @@ static switch_status_t api_erlang_nodes_list(switch_stream_handle_t *stream) { ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_nodes_count(switch_stream_handle_t *stream) { ei_node_t *ei_node; int count = 0; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { @@ -142,9 +142,9 @@ static switch_status_t api_erlang_nodes_count(switch_stream_handle_t *stream) { ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + stream->write_function(stream, "%d\n", count); - + return SWITCH_STATUS_SUCCESS; } @@ -152,7 +152,7 @@ static switch_status_t api_complete_erlang_node(const char *line, const char *cu switch_console_callback_match_t *my_matches = NULL; switch_status_t status = SWITCH_STATUS_FALSE; ei_node_t *ei_node; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { @@ -160,34 +160,34 @@ static switch_status_t api_complete_erlang_node(const char *line, const char *cu ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + if (my_matches) { *matches = my_matches; status = SWITCH_STATUS_SUCCESS; } - + return status; } static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_stream, switch_stream_handle_t *stream) { ei_event_binding_t *binding; int column = 0; - + switch_mutex_lock(event_stream->socket_mutex); if (event_stream->connected == SWITCH_FALSE) { switch_sockaddr_t *sa; uint16_t port; char ipbuf[25] = {0}; const char *ip_addr; - + switch_socket_addr_get(&sa, SWITCH_TRUE, event_stream->acceptor); port = switch_sockaddr_get_port(sa); ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - + if (zstr(ip_addr)) { ip_addr = globals.ip; } - + stream->write_function(stream, "%s:%d -> disconnected\n" ,ip_addr, port); } else { @@ -195,7 +195,7 @@ static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_str ,event_stream->local_ip, event_stream->local_port ,event_stream->remote_ip, event_stream->remote_port); } - + binding = event_stream->bindings; while(binding != NULL) { if (binding->type == SWITCH_EVENT_CUSTOM) { @@ -203,22 +203,22 @@ static switch_status_t handle_node_api_event_stream(ei_event_stream_t *event_str } else { stream->write_function(stream, "%-50s", switch_event_name(binding->type)); } - + if (++column > 2) { stream->write_function(stream, "\n"); column = 0; } - + binding = binding->next; } switch_mutex_unlock(event_stream->socket_mutex); - + if (!column) { stream->write_function(stream, "\n"); } else { stream->write_function(stream, "\n\n"); } - + return SWITCH_STATUS_SUCCESS; } @@ -232,13 +232,13 @@ static switch_status_t handle_node_api_event_streams(ei_node_t *ei_node, switch_ event_stream = event_stream->next; } switch_mutex_unlock(ei_node->event_streams_mutex); - + return SWITCH_STATUS_SUCCESS; } static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream_handle_t *stream, uint32_t command) { unsigned int year, day, hour, min, sec, delta; - + switch (command) { case API_COMMAND_DISCONNECT: stream->write_function(stream, "Disconnecting erlang node %s at managers request\n", ei_node->peer_nodename); @@ -251,7 +251,7 @@ static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream hour = delta / 3600 % 24; day = delta / 86400 % 7; year = delta / 31556926 % 12; - + stream->write_function(stream, "Uptime %d years, %d days, %d hours, %d minutes, %d seconds\n", year, day, hour, min, sec); stream->write_function(stream, "Local Address %s:%d\n", ei_node->local_ip, ei_node->local_port); stream->write_function(stream, "Remote Address %s:%d\n", ei_node->remote_ip, ei_node->remote_port); @@ -265,28 +265,28 @@ static switch_status_t handle_node_api_command(ei_node_t *ei_node, switch_stream default: break; } - + return SWITCH_STATUS_SUCCESS; } static switch_status_t api_erlang_node_command(switch_stream_handle_t *stream, const char *nodename, uint32_t command) { ei_node_t *ei_node; - + switch_thread_rwlock_rdlock(globals.ei_nodes_lock); ei_node = globals.ei_nodes; while(ei_node != NULL) { int length = strlen(ei_node->peer_nodename); - + if (!strncmp(ei_node->peer_nodename, nodename, length)) { handle_node_api_command(ei_node, stream, command); switch_thread_rwlock_unlock(globals.ei_nodes_lock); return SWITCH_STATUS_SUCCESS; } - + ei_node = ei_node->next; } switch_thread_rwlock_unlock(globals.ei_nodes_lock); - + return SWITCH_STATUS_NOTFOUND; } @@ -296,7 +296,7 @@ static int read_cookie_from_file(char *filename) { char *end; struct stat buf; ssize_t res; - + if (!stat(filename, &buf)) { if ((buf.st_mode & S_IRWXG) || (buf.st_mode & S_IRWXO)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s must only be accessible by owner only.\n", filename); @@ -311,24 +311,24 @@ static int read_cookie_from_file(char *filename) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to open cookie file %s : %d.\n", filename, errno); return 2; } - + if ((res = read(fd, cookie, MAXATOMLEN)) < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to read cookie file %s : %d.\n", filename, errno); } - + cookie[MAXATOMLEN] = '\0'; - + /* replace any end of line characters with a null */ if ((end = strchr(cookie, '\n'))) { *end = '\0'; } - + if ((end = strchr(cookie, '\r'))) { *end = '\0'; } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set cookie from file %s: %s\n", filename, cookie); - + set_pref_ei_cookie(cookie); return 0; } else { @@ -340,7 +340,8 @@ static int read_cookie_from_file(char *filename) { static switch_status_t config(void) { char *cf = "kazoo.conf"; switch_xml_t cfg, xml, child, param; - globals.send_all_headers = globals.send_all_private_headers = 0; + globals.send_all_headers = 0; + globals.send_all_private_headers = 1; globals.connection_timeout = 500; globals.receive_timeout = 200; globals.receive_msg_preallocate = 2000; @@ -348,7 +349,7 @@ static switch_status_t config(void) { globals.send_msg_batch = 10; globals.event_stream_framing = 2; globals.port = 0; - + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open configuration file %s\n", cf); return SWITCH_STATUS_FALSE; @@ -357,7 +358,7 @@ static switch_status_t config(void) { for (param = switch_xml_child(child, "param"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); - + if (!strcmp(var, "listen-ip")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Set bind ip address: %s\n", val); set_pref_ip(val); @@ -412,19 +413,19 @@ static switch_status_t config(void) { } } } - + if ((child = switch_xml_child(cfg, "event-filter"))) { switch_hash_t *filter; - + switch_core_hash_init(&filter); for (param = switch_xml_child(child, "header"); param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); switch_core_hash_insert(filter, var, "1"); } - + globals.event_filter = filter; } - + switch_xml_free(xml); } @@ -432,17 +433,17 @@ static switch_status_t config(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid receive message preallocate value, disabled\n"); globals.receive_msg_preallocate = 0; } - + if (globals.event_stream_preallocate < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream preallocate value, disabled\n"); globals.event_stream_preallocate = 0; } - + if (globals.send_msg_batch < 1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid send message batch size, reverting to default\n"); globals.send_msg_batch = 10; } - + if (!globals.event_filter) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Event filter not found in configuration, using default\n"); globals.event_filter = create_default_filter(); @@ -452,7 +453,7 @@ static switch_status_t config(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid event stream framing value, using default\n"); globals.event_stream_framing = 2; } - + if (zstr(globals.kazoo_var_prefix)) { set_pref_kazoo_var_prefix("variable_ecallmgr*"); globals.var_prefix_length = 17; //ignore the * @@ -461,33 +462,33 @@ static switch_status_t config(void) { * free the pointer if it was not drawn from the XML */ char *buf; int size = switch_snprintf(NULL, 0, "variable_%s*", globals.kazoo_var_prefix) + 1; - + switch_malloc(buf, size); switch_snprintf(buf, size, "variable_%s*", globals.kazoo_var_prefix); switch_safe_free(globals.kazoo_var_prefix); globals.kazoo_var_prefix = buf; globals.var_prefix_length = size - 2; //ignore the * } - + if (!globals.num_worker_threads) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Number of worker threads not found in configuration, using default\n"); globals.num_worker_threads = 10; } - + if (zstr(globals.ip)) { set_pref_ip("0.0.0.0"); } - + if (zstr(globals.ei_cookie)) { int res; char *home_dir = getenv("HOME"); char path_buf[1024]; - + if (!zstr(home_dir)) { /* $HOME/.erlang.cookie */ switch_snprintf(path_buf, sizeof (path_buf), "%s%s%s", home_dir, SWITCH_PATH_SEPARATOR, ".erlang.cookie"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Checking for cookie at path: %s\n", path_buf); - + res = read_cookie_from_file(path_buf); if (res) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No cookie or valid cookie file specified, using default cookie\n"); @@ -495,15 +496,15 @@ static switch_status_t config(void) { } } } - + if (!globals.ei_nodename) { set_pref_ei_nodename("freeswitch"); } - + if (!globals.nat_map) { globals.nat_map = 0; } - + return SWITCH_STATUS_SUCCESS; } @@ -512,38 +513,38 @@ static switch_status_t create_acceptor() { uint16_t port; char ipbuf[25]; const char *ip_addr; - + /* if the config has specified an erlang release compatibility then pass that along to the erlang interface */ if (globals.ei_compat_rel) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Compatability with OTP R%d requested\n", globals.ei_compat_rel); ei_set_compat_rel(globals.ei_compat_rel); } - + if (!(globals.acceptor = create_socket_with_port(globals.pool, globals.port))) { return SWITCH_STATUS_SOCKERR; } - + switch_socket_addr_get(&sa, SWITCH_FALSE, globals.acceptor); - + port = switch_sockaddr_get_port(sa); ip_addr = switch_get_addr(ipbuf, sizeof (ipbuf), sa); - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor listening on %s:%u\n", ip_addr, port); - + /* try to initialize the erlang interface */ if (create_ei_cnode(ip_addr, globals.ei_nodename, &globals.ei_cnode) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_SOCKERR; } - + /* tell the erlang port manager where we can be reached. this returns a file descriptor pointing to epmd or -1 */ if ((globals.epmdfd = ei_publish(&globals.ei_cnode, port)) == -1) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to publish port to epmd. Try starting it yourself or run an erl shell with the -sname or -name option.\n"); return SWITCH_STATUS_SOCKERR; } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected to epmd and published erlang cnode name %s at port %d\n", globals.ei_cnode.thisnodename, port); - + return SWITCH_STATUS_SUCCESS; } @@ -552,7 +553,7 @@ SWITCH_STANDARD_API(exec_api_cmd) char *argv[1024] = { 0 }; int unknown_command = 1, argc = 0; char *mycmd = NULL; - + const char *usage_string = "USAGE:\n" "--------------------------------------------------------------------------------------------------------------------\n" "erlang status - provides an overview of the current status\n" @@ -564,28 +565,28 @@ SWITCH_STANDARD_API(exec_api_cmd) "erlang node event_streams - lists the event streams for an Erlang node\n" "erlang node fetch_bindings - lists the XML fetch bindings for an Erlang node\n" "---------------------------------------------------------------------------------------------------------------------\n"; - + if (zstr(cmd)) { stream->write_function(stream, "%s", usage_string); return SWITCH_STATUS_SUCCESS; } - + if (!(mycmd = strdup(cmd))) { return SWITCH_STATUS_MEMERR; } - + if (!(argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { stream->write_function(stream, "%s", usage_string); switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; } - + if (zstr(argv[0])) { stream->write_function(stream, "%s", usage_string); switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; } - + if (!strncmp(argv[0], "status", 6)) { unknown_command = 0; api_erlang_status(stream); @@ -615,11 +616,11 @@ SWITCH_STANDARD_API(exec_api_cmd) api_erlang_node_command(stream, argv[1], API_COMMAND_BINDINGS); } } - + if (unknown_command) { stream->write_function(stream, "%s", usage_string); } - + switch_safe_free(mycmd); return SWITCH_STATUS_SUCCESS; } @@ -627,28 +628,28 @@ SWITCH_STANDARD_API(exec_api_cmd) SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { switch_api_interface_t *api_interface = NULL; switch_application_interface_t *app_interface = NULL; - + memset(&globals, 0, sizeof(globals)); - + globals.pool = pool; globals.ei_nodes = NULL; - + if(config() != SWITCH_STATUS_SUCCESS) { // TODO: what would we need to clean up here? switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Improper configuration!\n"); return SWITCH_STATUS_TERM; } - + if(create_acceptor() != SWITCH_STATUS_SUCCESS) { // TODO: what would we need to clean up here switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to create erlang connection acceptor!\n"); close_socket(&globals.acceptor); return SWITCH_STATUS_TERM; } - + /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - + /* create an api for cli debug commands */ SWITCH_ADD_API(api_interface, "erlang", KAZOO_DESC, exec_api_cmd, KAZOO_SYNTAX); switch_console_set_complete("add erlang status"); @@ -660,13 +661,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { switch_console_set_complete("add erlang node ::erlang::node event_streams"); switch_console_set_complete("add erlang node ::erlang::node fetch_bindings"); switch_console_add_complete_func("::erlang::node", api_complete_erlang_node); - + switch_thread_rwlock_create(&globals.ei_nodes_lock, pool); - + switch_set_flag(&globals, LFLAG_RUNNING); - + /* create all XML fetch agents */ - bind_fetch_agents(); + bind_fetch_agents(); /* add our modified commands */ add_kz_commands(module_interface, api_interface); @@ -680,13 +681,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_kazoo_load) { SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) { int sanity = 0; - + switch_console_set_complete("del erlang"); switch_console_del_complete_func("::erlang::node"); - + /* stop taking new requests and start shuting down the threads */ switch_clear_flag(&globals, LFLAG_RUNNING); - + /* give everyone time to cleanly shutdown */ while (switch_atomic_read(&globals.threads)) { switch_yield(100000); @@ -695,52 +696,52 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_kazoo_shutdown) { break; } } - + if (globals.event_filter) { switch_core_hash_destroy(&globals.event_filter); } - + switch_thread_rwlock_wrlock(globals.ei_nodes_lock); switch_thread_rwlock_unlock(globals.ei_nodes_lock); switch_thread_rwlock_destroy(globals.ei_nodes_lock); - + /* close the connection to epmd and the acceptor */ close_socketfd(&globals.epmdfd); close_socket(&globals.acceptor); - + /* remove all XML fetch agents */ unbind_fetch_agents(); - + /* Close the port we reserved for uPnP/Switch behind firewall, if necessary */ // if (globals.nat_map && switch_nat_get_type()) { // switch_nat_del_mapping(globals.port, SWITCH_NAT_TCP); // } - + /* clean up our allocated preferences */ switch_safe_free(globals.ip); switch_safe_free(globals.ei_cookie); switch_safe_free(globals.ei_nodename); switch_safe_free(globals.kazoo_var_prefix); - + return SWITCH_STATUS_SUCCESS; } SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) { switch_os_socket_t os_socket; - + switch_atomic_inc(&globals.threads); - + switch_os_sock_get(&os_socket, globals.acceptor); - + while (switch_test_flag(&globals, LFLAG_RUNNING)) { int nodefd; ErlConnect conn; - + /* zero out errno because ei_accept doesn't differentiate between a */ /* failed authentication or a socket failure, or a client version */ /* mismatch or a godzilla attack (and a godzilla attack is highly likely) */ errno = 0; - + /* wait here for an erlang node to connect, timming out to check if our module is still running every now-and-again */ if ((nodefd = ei_accept_tmo(&globals.ei_cnode, (int) os_socket, &conn, globals.connection_timeout)) == ERL_ERROR) { if (erl_errno == ETIMEDOUT) { @@ -753,19 +754,19 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_kazoo_runtime) { } continue; } - + if (!switch_test_flag(&globals, LFLAG_RUNNING)) { break; } - + /* NEW ERLANG NODE CONNECTION! Hello friend! */ new_kazoo_node(nodefd, &conn); } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Erlang connection acceptor shut down\n"); - + switch_atomic_dec(&globals.threads); - + return SWITCH_STATUS_TERM; } diff --git a/src/mod/formats/mod_imagick/mod_imagick.c b/src/mod/formats/mod_imagick/mod_imagick.c index 2ded733f3e..7680e65a13 100644 --- a/src/mod/formats/mod_imagick/mod_imagick.c +++ b/src/mod/formats/mod_imagick/mod_imagick.c @@ -61,8 +61,15 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_imagick_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_imagick_shutdown); SWITCH_MODULE_DEFINITION(mod_imagick, mod_imagick_load, mod_imagick_shutdown, NULL); +typedef enum pdf_loading_state_s { + PLS_LOADING, + PLS_BREAK, + PLS_DONE +} pdf_loading_state_t; + struct pdf_file_context { switch_memory_pool_t *pool; + switch_mutex_t *mutex; switch_image_t *img; int reads; int sent; @@ -75,16 +82,64 @@ struct pdf_file_context { Image *images; ExceptionInfo *exception; int autoplay; + const char *path; + int lazy; + char *lazy_cookie; + pdf_loading_state_t loading_state; switch_time_t next_play_time; }; typedef struct pdf_file_context pdf_file_context_t; +static void *SWITCH_THREAD_FUNC open_pdf_thread_run(switch_thread_t *thread, void *obj) +{ + pdf_file_context_t *context = (pdf_file_context_t *)obj; + int pagenumber = context->lazy; + char path[1024]; + + while (context->loading_state == PLS_LOADING) { + Image *tmp_images; + switch_snprintf(path, sizeof(path), "%s[%d]", context->path, pagenumber); + switch_set_string(context->image_info->filename, path); + if ((tmp_images = ReadImages(context->image_info, context->exception))) { + pagenumber++; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s page %d loaded\n", context->path, pagenumber); + AppendImageToList(&context->images, tmp_images); + context->pagecount = pagenumber; + } else { + switch_event_t *event = NULL; + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, "imagick::info") == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "loaded"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "filename", context->path); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "pagecount", "%d", context->pagecount); + if (context->lazy_cookie) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "cookie", context->lazy_cookie); + } + switch_event_fire(&event); + } + + break; + } + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "read file: %s %s, pagecount: %d\n", + context->path, context->loading_state == PLS_BREAK ? "break" : "done", pagenumber); + + switch_mutex_lock(context->mutex); + context->loading_state = PLS_DONE; + switch_mutex_unlock(context->mutex); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Read Images Thread Ended.\n"); + return NULL; +} + static switch_status_t imagick_file_open(switch_file_handle_t *handle, const char *path) { pdf_file_context_t *context; char *ext; unsigned int flags = 0; + char range_path[1024]; if ((ext = strrchr((char *)path, '.')) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Format\n"); @@ -121,13 +176,15 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha context->exception = AcquireExceptionInfo(); context->image_info = AcquireImageInfo(); - switch_set_string(context->image_info->filename, path); + context->path = switch_core_strdup(handle->memory_pool, path); if (handle->params) { const char *max = switch_event_get_header(handle->params, "img_ms"); const char *autoplay = switch_event_get_header(handle->params, "autoplay"); const char *density = switch_event_get_header(handle->params, "density"); const char *quality = switch_event_get_header(handle->params, "quality"); + const char *lazy = switch_event_get_header(handle->params, "lazy"); + const char *lazy_cookie = switch_event_get_header(handle->params, "cookie"); int tmp; if (max) { @@ -148,6 +205,28 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha if (tmp > 0) context->image_info->quality = tmp; } + + if (lazy) { + int tmp = atoi(lazy); + + if (tmp >= 0) { + context->lazy = tmp; + } else { + context->lazy = 1; + } + } + + if (lazy_cookie) { + context->lazy_cookie = switch_core_strdup(handle->memory_pool, lazy_cookie); + } + } + + if (context->lazy) { + switch_snprintf(range_path, sizeof(range_path), "%s[0-%d]", path, context->lazy - 1); + switch_set_string(context->image_info->filename, range_path); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "loading first %d page%s\n", context->lazy, context->lazy > 1 ? "s" : ""); + } else { + switch_set_string(context->image_info->filename, path); } context->images = ReadImages(context->image_info, context->exception); @@ -175,7 +254,20 @@ static switch_status_t imagick_file_open(switch_file_handle_t *handle, const cha handle->private_info = context; context->pool = handle->memory_pool; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s], pagecount: %d\n", path, context->pagecount); + if (context->lazy) { + switch_thread_t *thread; + switch_threadattr_t *thd_attr = NULL; + + switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, context->pool); + context->loading_state = PLS_LOADING; + switch_thread_create(&thread, thd_attr, open_pdf_thread_run, context, context->pool); + } + + if (context->lazy) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File %s, read the first %d page(s)", path, context->lazy); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File %s", path); + } return SWITCH_STATUS_SUCCESS; } @@ -184,6 +276,18 @@ static switch_status_t imagick_file_close(switch_file_handle_t *handle) { pdf_file_context_t *context = (pdf_file_context_t *)handle->private_info; + if (context->lazy) { + switch_mutex_lock(context->mutex); + if (context->loading_state == PLS_LOADING) context->loading_state = PLS_BREAK; + switch_mutex_unlock(context->mutex); + + while (context->loading_state != PLS_DONE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "waiting for pdf loading thread done, loading_state: %d\n", context->loading_state); + switch_yield(1000000); + switch_cond_next(); + } + } + switch_img_free(&context->img); if (context->images) DestroyImageList(context->images); diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index c02addd90f..1f3c1e8851 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -2000,6 +2000,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_RTCP_VIDEO_INTERVAL_MSEC_get() { } +SWIGEXPORT int SWIGSTDCALL CSharp_MAX_FMTP_LEN_get() { + int jresult ; + int result; + + result = (int)(256); + jresult = result; + return jresult; +} + + SWIGEXPORT double SWIGSTDCALL CSharp_JITTER_VARIANCE_THRESHOLD_get() { double jresult ; double result; @@ -17340,7 +17350,7 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_loadable_module_get_codec_interface( } -SWIGEXPORT char * SWIGSTDCALL CSharp_switch_parse_codec_buf(char * jarg1, void * jarg2, void * jarg3, void * jarg4, void * jarg5, void * jarg6) { +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_parse_codec_buf(char * jarg1, void * jarg2, void * jarg3, void * jarg4, void * jarg5, void * jarg6, void * jarg7) { char * jresult ; char *arg1 = (char *) 0 ; uint32_t *arg2 = (uint32_t *) 0 ; @@ -17348,6 +17358,7 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_parse_codec_buf(char * jarg1, void * uint32_t *arg4 = (uint32_t *) 0 ; uint32_t *arg5 = (uint32_t *) 0 ; char **arg6 = (char **) 0 ; + char **arg7 = (char **) 0 ; char *result = 0 ; arg1 = (char *)jarg1; @@ -17356,7 +17367,8 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_switch_parse_codec_buf(char * jarg1, void * arg4 = (uint32_t *)jarg4; arg5 = (uint32_t *)jarg5; arg6 = (char **)jarg6; - result = (char *)switch_parse_codec_buf(arg1,arg2,arg3,arg4,arg5,arg6); + arg7 = (char **)jarg7; + result = (char *)switch_parse_codec_buf(arg1,arg2,arg3,arg4,arg5,arg6,arg7); jresult = SWIG_csharp_string_callback((const char *)result); return jresult; } @@ -17612,19 +17624,21 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs(void * jarg1 } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs_sorted(void * jarg1, int jarg2, void * jarg3, int jarg4) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_loadable_module_get_codecs_sorted(void * jarg1, void * jarg2, int jarg3, void * jarg4, int jarg5) { int jresult ; switch_codec_implementation_t **arg1 = (switch_codec_implementation_t **) 0 ; - int arg2 ; - char **arg3 = (char **) 0 ; - int arg4 ; + char (*arg2)[256] ; + int arg3 ; + char **arg4 = (char **) 0 ; + int arg5 ; int result; arg1 = (switch_codec_implementation_t **)jarg1; - arg2 = (int)jarg2; - arg3 = (char **)jarg3; - arg4 = (int)jarg4; - result = (int)switch_loadable_module_get_codecs_sorted((switch_codec_implementation const **)arg1,arg2,arg3,arg4); + arg2 = (char (*)[256])jarg2; + arg3 = (int)jarg3; + arg4 = (char **)jarg4; + arg5 = (int)jarg5; + result = (int)switch_loadable_module_get_codecs_sorted((switch_codec_implementation const **)arg1,(char (*)[256])arg2,arg3,arg4,arg5); jresult = result; return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 7323796fa7..06d3765dc9 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -3447,8 +3447,8 @@ else return ret; } - public static string switch_parse_codec_buf(string buf, SWIGTYPE_p_unsigned_long interval, SWIGTYPE_p_unsigned_long rate, SWIGTYPE_p_unsigned_long bit, SWIGTYPE_p_unsigned_long channels, ref string modname) { - string ret = freeswitchPINVOKE.switch_parse_codec_buf(buf, SWIGTYPE_p_unsigned_long.getCPtr(interval), SWIGTYPE_p_unsigned_long.getCPtr(rate), SWIGTYPE_p_unsigned_long.getCPtr(bit), SWIGTYPE_p_unsigned_long.getCPtr(channels), ref modname); + public static string switch_parse_codec_buf(string buf, SWIGTYPE_p_unsigned_long interval, SWIGTYPE_p_unsigned_long rate, SWIGTYPE_p_unsigned_long bit, SWIGTYPE_p_unsigned_long channels, ref string modname, ref string fmtp) { + string ret = freeswitchPINVOKE.switch_parse_codec_buf(buf, SWIGTYPE_p_unsigned_long.getCPtr(interval), SWIGTYPE_p_unsigned_long.getCPtr(rate), SWIGTYPE_p_unsigned_long.getCPtr(bit), SWIGTYPE_p_unsigned_long.getCPtr(channels), ref modname, ref fmtp); return ret; } @@ -3561,8 +3561,8 @@ else return ret; } - public static int switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation array, int arraylen, ref string prefs, int preflen) { - int ret = freeswitchPINVOKE.switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation.getCPtr(array), arraylen, ref prefs, preflen); + public static int switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation array, SWIGTYPE_p_a_256__char fmtp_array, int arraylen, ref string prefs, int preflen) { + int ret = freeswitchPINVOKE.switch_loadable_module_get_codecs_sorted(SWIGTYPE_p_p_switch_codec_implementation.getCPtr(array), SWIGTYPE_p_a_256__char.getCPtr(fmtp_array), arraylen, ref prefs, preflen); return ret; } @@ -7611,6 +7611,7 @@ else public static readonly int SWITCH_DEFAULT_VIDEO_SIZE = freeswitchPINVOKE.SWITCH_DEFAULT_VIDEO_SIZE_get(); public static readonly string SWITCH_RTCP_AUDIO_INTERVAL_MSEC = freeswitchPINVOKE.SWITCH_RTCP_AUDIO_INTERVAL_MSEC_get(); public static readonly string SWITCH_RTCP_VIDEO_INTERVAL_MSEC = freeswitchPINVOKE.SWITCH_RTCP_VIDEO_INTERVAL_MSEC_get(); + public static readonly int MAX_FMTP_LEN = freeswitchPINVOKE.MAX_FMTP_LEN_get(); public static readonly double JITTER_VARIANCE_THRESHOLD = freeswitchPINVOKE.JITTER_VARIANCE_THRESHOLD_get(); public static readonly double IPDV_THRESHOLD = freeswitchPINVOKE.IPDV_THRESHOLD_get(); public static readonly int LOST_BURST_ANALYZE = freeswitchPINVOKE.LOST_BURST_ANALYZE_get(); @@ -8385,6 +8386,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTCP_VIDEO_INTERVAL_MSEC_get")] public static extern string SWITCH_RTCP_VIDEO_INTERVAL_MSEC_get(); + [DllImport("mod_managed", EntryPoint="CSharp_MAX_FMTP_LEN_get")] + public static extern int MAX_FMTP_LEN_get(); + [DllImport("mod_managed", EntryPoint="CSharp_JITTER_VARIANCE_THRESHOLD_get")] public static extern double JITTER_VARIANCE_THRESHOLD_get(); @@ -12151,7 +12155,7 @@ class freeswitchPINVOKE { public static extern IntPtr switch_loadable_module_get_codec_interface(string jarg1, string jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_parse_codec_buf")] - public static extern string switch_parse_codec_buf(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5, ref string jarg6); + public static extern string switch_parse_codec_buf(string jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5, ref string jarg6, ref string jarg7); [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_dialplan_interface")] public static extern IntPtr switch_loadable_module_get_dialplan_interface(string jarg1); @@ -12211,7 +12215,7 @@ class freeswitchPINVOKE { public static extern int switch_loadable_module_get_codecs(HandleRef jarg1, int jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_loadable_module_get_codecs_sorted")] - public static extern int switch_loadable_module_get_codecs_sorted(HandleRef jarg1, int jarg2, ref string jarg3, int jarg4); + public static extern int switch_loadable_module_get_codecs_sorted(HandleRef jarg1, HandleRef jarg2, int jarg3, ref string jarg4, int jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_api_execute")] public static extern int switch_api_execute(string jarg1, string jarg2, HandleRef jarg3, HandleRef jarg4); @@ -20471,6 +20475,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_a_256__char { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_a_256__char(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_a_256__char() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_a_256__char obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.12 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_a_2__icand_s { private HandleRef swigCPtr; diff --git a/src/switch_console.c b/src/switch_console.c index 6100bb22df..d9435a17af 100644 --- a/src/switch_console.c +++ b/src/switch_console.c @@ -352,7 +352,7 @@ SWITCH_DECLARE(switch_status_t) switch_console_execute(char *xcmd, int rec, swit int argc; char *argv[128]; int x; - char *dup = strdup(xcmd); + char *dup = NULL; char *cmd; switch_status_t status = SWITCH_STATUS_FALSE; @@ -363,6 +363,10 @@ SWITCH_DECLARE(switch_status_t) switch_console_execute(char *xcmd, int rec, swit goto end; } + while (*xcmd == ' ') xcmd++; + + dup = strdup(xcmd); + if (!strncasecmp(xcmd, "alias", 5)) { argc = 1; argv[0] = xcmd; diff --git a/src/switch_core.c b/src/switch_core.c index 4a8865612b..039531bb86 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -93,6 +93,7 @@ static void send_heartbeat(void) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Max-Sessions", "%u", switch_core_session_limit(0)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Last", "%u", runtime.sps_last); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-Max", "%u", runtime.sps_peak); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec-FiveMin", "%u", runtime.sps_peak_fivemin); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 8a25514604..f1295b0ee5 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -189,7 +189,7 @@ struct switch_media_handle_s { char *codec_order[SWITCH_MAX_CODECS]; int codec_order_last; const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS]; - + char fmtp[SWITCH_MAX_CODECS][MAX_FMTP_LEN]; int payload_space; char *origin; @@ -669,6 +669,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core switch_media_type_t type, const char *iananame, uint32_t rate, + const char *fmtp_in, switch_payload_t *ptP, switch_payload_t *recv_ptP, char **fmtpP) @@ -690,10 +691,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_get_payload_code(switch_core switch_mutex_lock(smh->sdp_mutex); for (pmap = engine->payload_map; pmap ; pmap = pmap->next) { + char *fmtp_a = pmap->rm_fmtp; if (!pmap->allocated) continue; - if (!strcasecmp(pmap->iananame, iananame) && (!rate || (rate == pmap->rate))) { + if (!fmtp_a) fmtp_a = ""; + if (!fmtp_in) fmtp_in = ""; + + + if (!strcasecmp(pmap->iananame, iananame) && !strcasecmp(fmtp_a, fmtp_in) && (!rate || (rate == pmap->rate))) { pt = pmap->pt; recv_pt = pmap->recv_pt; fmtp = pmap->rm_fmtp; @@ -1866,7 +1872,7 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses tmp_codec_string = switch_core_session_strdup(smh->session, codec_string); switch_channel_set_variable(session->channel, "rtp_use_codec_string", codec_string); smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS); - smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last); + smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, smh->fmtp, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last); } @@ -2704,11 +2710,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio return SWITCH_STATUS_GENERR; } - - if (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec)) { - return SWITCH_STATUS_FALSE; - } - if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { if (engine->read_impl.encoded_bytes_per_packet) { bytes = engine->read_impl.encoded_bytes_per_packet; @@ -3347,10 +3348,14 @@ static switch_bool_t ip_possible(switch_media_handle_t *smh, const char *ip) static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_session_t *sdp, sdp_media_t *m) { switch_rtp_engine_t *engine = &smh->engines[type]; - sdp_attribute_t *attr; + sdp_attribute_t *attr = NULL, *attrs[2] = { 0 }; int i = 0, got_rtcp_mux = 0; const char *val; - int ice_seen = 0, cid = 0, ai = 0; + int ice_seen = 0, cid = 0, ai = 0, attr_idx = 0, cand_seen = 0; + + if (switch_true(switch_channel_get_variable_dup(smh->session->channel, "ignore_sdp_ice", SWITCH_FALSE, -1))) { + return SWITCH_STATUS_BREAK; + } //if (engine->ice_in.is_chosen[0] && engine->ice_in.is_chosen[1]) { //return SWITCH_STATUS_SUCCESS; @@ -3365,157 +3370,161 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t engine->remote_ssrc = 0; if (m) { - attr = m->m_attributes; + attrs[0] = m->m_attributes; + attrs[1] = sdp->sdp_attributes; } else { - attr = sdp->sdp_attributes; + attrs[0] = sdp->sdp_attributes; } - for (; attr; attr = attr->a_next) { - char *data; - char *fields[15]; - int argc = 0, j = 0; + for (attr_idx = 0; attr_idx < 2 && !(ice_seen && cand_seen); attr_idx++) { + for (attr = attrs[attr_idx]; attr; attr = attr->a_next) { + char *data; + char *fields[15]; + int argc = 0, j = 0; - if (zstr(attr->a_name)) { - continue; - } + if (zstr(attr->a_name)) { + continue; + } - if (!strcasecmp(attr->a_name, "ice-ufrag")) { - if (engine->ice_in.ufrag && !strcmp(engine->ice_in.ufrag, attr->a_value)) { - engine->new_ice = 0; - } else { - engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value); - engine->new_ice = 1; - } - ice_seen++; - } else if (!strcasecmp(attr->a_name, "ice-pwd")) { - if (!engine->ice_in.pwd || strcmp(engine->ice_in.pwd, attr->a_value)) { - engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value); - } - } else if (!strcasecmp(attr->a_name, "ice-options")) { - engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value); - } else if (!strcasecmp(attr->a_name, "setup")) { - if (!strcasecmp(attr->a_value, "passive") || !strcasecmp(attr->a_value, "actpass")) { - if (!engine->dtls_controller) { - engine->new_dtls = 1; - engine->new_ice = 1; - } - engine->dtls_controller = 1; - } else if (!strcasecmp(attr->a_value, "active")) { - if (engine->dtls_controller) { - engine->new_dtls = 1; - engine->new_ice = 1; - } - engine->dtls_controller = 0; - } - } else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) { - char *p; - - engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value); - - if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) { - *p++ = '\0'; - - if (switch_channel_test_flag(smh->session->channel, CF_REINVITE) && !switch_channel_test_flag(smh->session->channel, CF_RECOVERING) && - !zstr(engine->remote_dtls_fingerprint.str) && !strcmp(engine->remote_dtls_fingerprint.str, p)) { - engine->new_dtls = 0; + if (!strcasecmp(attr->a_name, "ice-ufrag")) { + if (engine->ice_in.ufrag && !strcmp(engine->ice_in.ufrag, attr->a_value)) { + engine->new_ice = 0; } else { - switch_set_string(engine->remote_dtls_fingerprint.str, p); - engine->new_dtls = 1; + engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value); engine->new_ice = 1; } - } + ice_seen++; + } else if (!strcasecmp(attr->a_name, "ice-pwd")) { + if (!engine->ice_in.pwd || strcmp(engine->ice_in.pwd, attr->a_value)) { + engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value); + } + } else if (!strcasecmp(attr->a_name, "ice-options")) { + engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value); + } else if (!strcasecmp(attr->a_name, "setup")) { + if (!strcasecmp(attr->a_value, "passive") || !strcasecmp(attr->a_value, "actpass")) { + if (!engine->dtls_controller) { + engine->new_dtls = 1; + engine->new_ice = 1; + } + engine->dtls_controller = 1; + } else if (!strcasecmp(attr->a_value, "active")) { + if (engine->dtls_controller) { + engine->new_dtls = 1; + engine->new_ice = 1; + } + engine->dtls_controller = 0; + } + } else if (switch_rtp_has_dtls() && dtls_ok(smh->session) && !strcasecmp(attr->a_name, "fingerprint") && !zstr(attr->a_value)) { + char *p; + + engine->remote_dtls_fingerprint.type = switch_core_session_strdup(smh->session, attr->a_value); + + if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) { + *p++ = '\0'; + + if (switch_channel_test_flag(smh->session->channel, CF_REINVITE) && !switch_channel_test_flag(smh->session->channel, CF_RECOVERING) && + !zstr(engine->remote_dtls_fingerprint.str) && !strcmp(engine->remote_dtls_fingerprint.str, p)) { + engine->new_dtls = 0; + } else { + switch_set_string(engine->remote_dtls_fingerprint.str, p); + engine->new_dtls = 1; + engine->new_ice = 1; + } + } - //if (strcasecmp(engine->remote_dtls_fingerprint.type, "sha-256")) { - // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Unsupported fingerprint type.\n"); + //if (strcasecmp(engine->remote_dtls_fingerprint.type, "sha-256")) { + // switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Unsupported fingerprint type.\n"); //engine->local_dtls_fingerprint.type = NULL; //engine->remote_dtls_fingerprint.type = NULL; - //} + //} - generate_local_fingerprint(smh, type); - switch_channel_set_flag(smh->session->channel, CF_DTLS); + generate_local_fingerprint(smh, type); + switch_channel_set_flag(smh->session->channel, CF_DTLS); - } else if (!engine->remote_ssrc && !strcasecmp(attr->a_name, "ssrc") && attr->a_value) { - engine->remote_ssrc = (uint32_t) atol(attr->a_value); + } else if (!engine->remote_ssrc && !strcasecmp(attr->a_name, "ssrc") && attr->a_value) { + engine->remote_ssrc = (uint32_t) atol(attr->a_value); - if (engine->rtp_session && engine->remote_ssrc) { - switch_rtp_set_remote_ssrc(engine->rtp_session, engine->remote_ssrc); - } + if (engine->rtp_session && engine->remote_ssrc) { + switch_rtp_set_remote_ssrc(engine->rtp_session, engine->remote_ssrc); + } #ifdef RTCP_MUX - } else if (!strcasecmp(attr->a_name, "rtcp-mux")) { - engine->rtcp_mux = SWITCH_TRUE; - engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port; - got_rtcp_mux++; + } else if (!strcasecmp(attr->a_name, "rtcp-mux")) { + engine->rtcp_mux = SWITCH_TRUE; + engine->remote_rtcp_port = engine->cur_payload_map->remote_sdp_port; + got_rtcp_mux++; #endif - } else if (!strcasecmp(attr->a_name, "candidate")) { - switch_channel_set_flag(smh->session->channel, CF_ICE); + } else if (!strcasecmp(attr->a_name, "candidate")) { + switch_channel_set_flag(smh->session->channel, CF_ICE); - if (!engine->cand_acl_count) { - engine->cand_acl[engine->cand_acl_count++] = "wan.auto"; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, Defaulting to wan.auto\n"); - } + if (!engine->cand_acl_count) { + engine->cand_acl[engine->cand_acl_count++] = "wan.auto"; + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, Defaulting to wan.auto\n"); + } - if (!switch_stristr(" udp ", attr->a_value)) { - continue; - } + if (!switch_stristr(" udp ", attr->a_value)) { + continue; + } - data = switch_core_session_strdup(smh->session, attr->a_value); + data = switch_core_session_strdup(smh->session, attr->a_value); - argc = switch_split(data, ' ', fields); + argc = switch_split(data, ' ', fields); - cid = fields[1] ? atoi(fields[1]) - 1 : 0; + cid = fields[1] ? atoi(fields[1]) - 1 : 0; - if (argc < 5 || engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n"); - continue; - } + if (argc < 5 || engine->ice_in.cand_idx[cid] >= MAX_CAND - 1) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "Invalid data\n"); + continue; + } - for (i = 0; i < argc; i++) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]); - } + for (i = 0; i < argc; i++) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]); + } - if (!ip_possible(smh, fields[4])) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, - "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n", - type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", - cid+1, fields[2], fields[7], fields[4], fields[5]); - continue; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, - "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n", - type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", - cid+1, fields[2], fields[7], fields[4], fields[5]); - } + if (!ip_possible(smh, fields[4])) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, + "Drop %s Candidate cid: %d proto: %s type: %s addr: %s:%s (no network path)\n", + type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", + cid+1, fields[2], fields[7], fields[4], fields[5]); + continue; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, + "Save %s Candidate cid: %d proto: %s type: %s addr: %s:%s\n", + type == SWITCH_MEDIA_TYPE_VIDEO ? "video" : "audio", + cid+1, fields[2], fields[7], fields[4], fields[5]); + } - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].foundation = switch_core_session_strdup(smh->session, fields[0]); - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].component_id = atoi(fields[1]); - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].transport = switch_core_session_strdup(smh->session, fields[2]); - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].priority = atol(fields[3]); - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_addr = switch_core_session_strdup(smh->session, fields[4]); - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_port = (switch_port_t)atoi(fields[5]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].foundation = switch_core_session_strdup(smh->session, fields[0]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].component_id = atoi(fields[1]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].transport = switch_core_session_strdup(smh->session, fields[2]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].priority = atol(fields[3]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_addr = switch_core_session_strdup(smh->session, fields[4]); + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].con_port = (switch_port_t)atoi(fields[5]); - j = 6; + j = 6; - while(j < argc && fields[j+1]) { - if (!strcasecmp(fields[j], "typ")) { - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].cand_type = switch_core_session_strdup(smh->session, fields[j+1]); - } else if (!strcasecmp(fields[j], "raddr")) { - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].raddr = switch_core_session_strdup(smh->session, fields[j+1]); - } else if (!strcasecmp(fields[j], "rport")) { - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].rport = (switch_port_t)atoi(fields[j+1]); - } else if (!strcasecmp(fields[j], "generation")) { - engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].generation = switch_core_session_strdup(smh->session, fields[j+1]); - } + while(j < argc && fields[j+1]) { + if (!strcasecmp(fields[j], "typ")) { + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].cand_type = switch_core_session_strdup(smh->session, fields[j+1]); + } else if (!strcasecmp(fields[j], "raddr")) { + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].raddr = switch_core_session_strdup(smh->session, fields[j+1]); + } else if (!strcasecmp(fields[j], "rport")) { + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].rport = (switch_port_t)atoi(fields[j+1]); + } else if (!strcasecmp(fields[j], "generation")) { + engine->ice_in.cands[engine->ice_in.cand_idx[cid]][cid].generation = switch_core_session_strdup(smh->session, fields[j+1]); + } - j += 2; + j += 2; + } + + cand_seen++; + engine->ice_in.cand_idx[cid]++; } - - engine->ice_in.cand_idx[cid]++; } } @@ -3795,6 +3804,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s const char *tmp; int m_idx = 0; int nm_idx = 0; + int vmatch_pt = 0; switch_assert(session); @@ -4438,6 +4448,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s const switch_codec_implementation_t *search[1]; char *prefs[1]; char tmp[80]; + char fmtp[SWITCH_MAX_CODECS][MAX_FMTP_LEN]; int num; const switch_codec_implementation_t *timp = NULL; @@ -4449,7 +4460,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s codec_ms, near_match->number_of_channels); prefs[0] = tmp; - num = switch_loadable_module_get_codecs_sorted(search, 1, prefs, 1); + num = switch_loadable_module_get_codecs_sorted(search, fmtp, 1, prefs, 1); if (num) { timp = search[0]; @@ -4657,8 +4668,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (best_te) { smh->mparams->te_rate = best_te_rate; - - if (smh->mparams->dtmf_type == DTMF_AUTO) { + + if (smh->mparams->dtmf_type == DTMF_AUTO || smh->mparams->dtmf_type == DTMF_2833 || + switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF)) { if (sdp_type == SDP_TYPE_REQUEST) { smh->mparams->te = smh->mparams->recv_te = (switch_payload_t) best_te; switch_channel_set_variable(session->channel, "dtmf_type", "rfc2833"); @@ -4754,6 +4766,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } } + if (switch_true(switch_channel_get_variable_dup(session->channel, "inherit_codec", SWITCH_FALSE, -1))) { + vmatch_pt = 1; + } + + compare: for (map = m->m_rtpmaps; map; map = map->rm_next) { @@ -4815,15 +4832,15 @@ 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]; - if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { + if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) { continue; } @@ -4831,8 +4848,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_test_flag(session->channel, CF_NOVIDEO)) { continue; } - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n", + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "Video Codec Compare [%s:%d]/[%s:%d]\n", rm_encoding, map->rm_pt, imp->iananame, imp->ianacode); if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0; @@ -4840,12 +4857,24 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s vmatch = strcasecmp(rm_encoding, imp->iananame) ? 0 : 1; } - if (vmatch && (map->rm_rate == imp->samples_per_second)) { + if (vmatch && vmatch_pt) { + const char *other_pt = switch_channel_get_variable_partner(channel, "rtp_video_pt"); + + if (other_pt) { + int opt = atoi(other_pt); + + if (map->rm_pt != opt) { + vmatch = 0; + } + } + } + + if (vmatch) { matches[m_idx].imp = imp; matches[m_idx].map = map; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n", - imp->iananame, imp->ianacode); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "Video Codec Compare [%s:%d] +++ is saved as a match\n", + imp->iananame, map->rm_pt); m_idx++; } @@ -4853,6 +4882,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } } + if (vmatch_pt && !m_idx) { + vmatch_pt = 0; + goto compare; + } + if (smh->crypto_mode == CRYPTO_MODE_MANDATORY && got_video_crypto < 1) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Crypto not negotiated but required.\n"); vmatch = 0; @@ -4917,8 +4951,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s #endif } - - switch_snprintf(tmp, sizeof(tmp), "%d", v_engine->cur_payload_map->remote_sdp_port); switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_IP_VARIABLE, v_engine->cur_payload_map->remote_sdp_ip); switch_channel_set_variable(session->channel, SWITCH_REMOTE_VIDEO_PORT_VARIABLE, tmp); @@ -6218,11 +6250,11 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co engine = &smh->engines[type]; -#ifdef RTCP_MUX - if (!engine->rtcp_mux) {// && type == SWITCH_MEDIA_TYPE_AUDIO) { - engine->rtcp_mux = SWITCH_TRUE; - } -#endif + //#ifdef RTCP_MUX + //if (!engine->rtcp_mux) {// && type == SWITCH_MEDIA_TYPE_AUDIO) { + // engine->rtcp_mux = SWITCH_TRUE; + //} + //#endif if (!smh->msid) { switch_stun_random_string(tmp, 32, NULL); @@ -6671,7 +6703,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (!strcasecmp(val, "passthru")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating RTCP PASSTHRU PORT %d\n", remote_rtcp_port); switch_rtp_activate_rtcp(a_engine->rtp_session, -1, remote_rtcp_port, a_engine->rtcp_mux > 0); - } else if (remote_rtcp_port) { + } else { int interval = atoi(val); if (interval < 100 || interval > 500000) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, @@ -7345,6 +7377,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, fmtp = smh->fmtps[i]; } + if (smh->ianacodes[i] > 95 || switch_channel_test_flag(session->channel, CF_VERBOSE_SDP)) { int channels = get_channels(imp->iananame, imp->number_of_channels); @@ -7682,7 +7715,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; - if (switch_true(switch_channel_get_variable(session->channel, "rtcp_mux"))) { + if (sdp_type == SDP_TYPE_REQUEST || switch_true(switch_channel_get_variable(session->channel, "rtcp_mux"))) { a_engine->rtcp_mux = 1; v_engine->rtcp_mux = 1; } @@ -7791,8 +7824,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_payload_t orig_pt = 0; char *orig_fmtp = NULL; - //smh->ianacodes[i] = imp->ianacode; - if (smh->ianacodes[i] > 64) { if (smh->mparams->dtmf_type == DTMF_2833 && smh->mparams->te > 95 && smh->mparams->te == smh->payload_space) { smh->payload_space++; @@ -7805,7 +7836,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (orig_session && switch_core_session_get_payload_code(orig_session, imp->codec_type == SWITCH_CODEC_TYPE_AUDIO ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO, - imp->iananame, imp->samples_per_second, &orig_pt, NULL, &orig_fmtp) == SWITCH_STATUS_SUCCESS) { + imp->iananame, imp->samples_per_second, smh->fmtp[i], &orig_pt, NULL, &orig_fmtp) == SWITCH_STATUS_SUCCESS) { + if (orig_pt == smh->mparams->te) { smh->mparams->te = (switch_payload_t)smh->payload_space++; } @@ -8354,7 +8386,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\r\n"); - if (v_engine->codec_negotiated) { const char *of; payload_map_t *pmap; @@ -8372,7 +8403,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess v_engine->cur_payload_map->pt, v_engine->cur_payload_map->rm_encoding, v_engine->cur_payload_map->rm_rate); - if (switch_channel_test_flag(session->channel, CF_RECOVERING)) { pass_fmtp = v_engine->cur_payload_map->rm_fmtp; } else { @@ -8387,11 +8417,16 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (ov_fmtp) { pass_fmtp = ov_fmtp; - } else if (switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) { - pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp"); + } else { + + pass_fmtp = v_engine->cur_payload_map->fmtp_out; + + if (!pass_fmtp || switch_true(switch_channel_get_variable_dup(session->channel, "rtp_mirror_fmtp", SWITCH_FALSE, -1))) { + pass_fmtp = switch_channel_get_variable(session->channel, "rtp_video_fmtp"); + } } } - + if (pass_fmtp) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fmtp:%d %s\r\n", v_engine->cur_payload_map->pt, pass_fmtp); } @@ -8403,7 +8438,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (pmap->pt != v_engine->cur_payload_map->pt && pmap->negotiated) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%ld\r\n", pmap->pt, pmap->iananame, pmap->rate); - } } switch_mutex_unlock(smh->sdp_mutex); @@ -8413,7 +8447,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (append_video) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s%s", append_video, end_of(append_video) == '\n' ? "" : "\r\n"); } - + if (v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendonly\r\n"); } else if (v_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) { @@ -8468,6 +8502,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess imp->samples_per_second); } + + if (!zstr(ov_fmtp)) { fmtp = (char *) ov_fmtp; } else { @@ -8476,7 +8512,9 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess fmtp = switch_event_get_header(map, imp->iananame); } - if (smh->fmtps[i]) { + if (!zstr(smh->fmtp[i])) { + fmtp = smh->fmtp[i]; + } else if (smh->fmtps[i]) { fmtp = smh->fmtps[i]; } @@ -10099,7 +10137,6 @@ SWITCH_DECLARE(void) switch_core_media_set_sdp_codec_string(switch_core_session_ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Setting NULL SDP is invalid\n"); return; } - if ((parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) { if ((sdp = sdp_session(parser))) { @@ -10186,6 +10223,8 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess int num_codecs = 0; char *codec_order[SWITCH_MAX_CODECS]; const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS] = { 0 }; + char fmtp[SWITCH_MAX_CODECS][MAX_FMTP_LEN]; + switch_channel_t *channel = switch_core_session_get_channel(session); int prefer_sdp = 0; const char *var; @@ -10206,7 +10245,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess char *tmp_codec_string; if ((tmp_codec_string = strdup(codec_string))) { num_codecs = switch_separate_string(tmp_codec_string, ',', codec_order, SWITCH_MAX_CODECS); - num_codecs = switch_loadable_module_get_codecs_sorted(codecs, SWITCH_MAX_CODECS, codec_order, num_codecs); + num_codecs = switch_loadable_module_get_codecs_sorted(codecs, fmtp, SWITCH_MAX_CODECS, codec_order, num_codecs); switch_safe_free(tmp_codec_string); } } else { @@ -10286,6 +10325,8 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) { for (map = m->m_rtpmaps; map; map = map->rm_next) { + match = 0; + if (map->rm_pt > 127 || already_did[map->rm_pt]) { continue; } @@ -10306,7 +10347,6 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (match) { add_audio_codec(map, imp, ptime, buf, sizeof(buf)); - break; } } @@ -10319,6 +10359,8 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess continue; } for (map = m->m_rtpmaps; map; map = map->rm_next) { + match = 0; + if (map->rm_pt > 127 || already_did[map->rm_pt]) { continue; } @@ -10336,7 +10378,6 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess if (match) { add_audio_codec(map, imp, ptime, buf, sizeof(buf)); - break; } } } @@ -10352,43 +10393,86 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Cannot find a c= line in the sdp at media or session level!\n"); break; } - for (i = 0; i < num_codecs; i++) { - const switch_codec_implementation_t *imp = codecs[i]; - if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO || imp->ianacode > 127 || already_did[imp->ianacode]) { - continue; - } - - if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND && - switch_channel_test_flag(session->channel, CF_NOVIDEO)) { - continue; - } + if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) { for (map = m->m_rtpmaps; map; map = map->rm_next) { + match = 0; + if (map->rm_pt > 127 || already_did[map->rm_pt]) { continue; } - if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { - match = (map->rm_pt == imp->ianacode) ? 1 : 0; - } else { - if (map->rm_encoding) { - match = !strcasecmp(map->rm_encoding, imp->iananame) && - ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)); + for (i = 0; i < num_codecs; i++) { + const switch_codec_implementation_t *imp = codecs[i]; + + if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { + match = (map->rm_pt == imp->ianacode) ? 1 : 0; } else { - match = 0; + if (map->rm_encoding) { + match = !strcasecmp(map->rm_encoding, imp->iananame) && + ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)); + } else { + match = 0; + } + } + + if (match) { + if (map->rm_fmtp) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s~%s", imp->modname, imp->iananame, map->rm_fmtp); + } else { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame); + } + already_did[imp->ianacode] = 1; } } + } - if (match) { - switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame); - already_did[imp->ianacode] = 1; - break; + } else { + for (i = 0; i < num_codecs; i++) { + const switch_codec_implementation_t *imp = codecs[i]; + + if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO || imp->ianacode > 127 || already_did[imp->ianacode]) { + continue; + } + + if (switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_INBOUND && + switch_channel_test_flag(session->channel, CF_NOVIDEO)) { + continue; + } + + for (map = m->m_rtpmaps; map; map = map->rm_next) { + match = 0; + + if (map->rm_pt > 127 || already_did[map->rm_pt]) { + continue; + } + + if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) { + match = (map->rm_pt == imp->ianacode) ? 1 : 0; + } else { + if (map->rm_encoding) { + match = !strcasecmp(map->rm_encoding, imp->iananame) && + ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)); + } else { + match = 0; + } + } + + if (match) { + if (map->rm_fmtp) { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s~%s", imp->modname, imp->iananame, map->rm_fmtp); + } else { + switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame); + } + already_did[imp->ianacode] = 1; + } } } } } } + if (buf[0] == ',') { switch_channel_set_variable(channel, "ep_codec_string", buf + 1); } @@ -10600,7 +10684,7 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_codec_string"))) { char *tmp_codec_string = switch_core_session_strdup(smh->session, tmp); smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS); - smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last); + smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, smh->fmtp, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last); } if ((tmp = switch_channel_get_variable(session->channel, "rtp_2833_send_payload"))) { diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 7b1ae8f1c2..90fa1fc96d 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -37,6 +37,7 @@ //#define DEBUG_ALLOC //#define DEBUG_ALLOC2 +//#define DEBUG_ALLOC_CUTOFF 0 /* Lower to zero to log all pool allocations when DEBUG_ALLOC is defined */ //#define DESTROY_POOLS //#define INSTANTLY_DESTROY_POOLS //#define LOCK_MORE @@ -45,6 +46,9 @@ #ifndef SWITCH_POOL_RECYCLE #define PER_POOL_LOCK 1 #endif +#ifndef DEBUG_ALLOC_CUTOFF +#define DEBUG_ALLOC_CUTOFF 500 +#endif static struct { #ifdef USE_MEM_LOCK @@ -79,7 +83,7 @@ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t * #endif #ifdef DEBUG_ALLOC - if (memory > 500) + if (memory > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p %p Session Allocate %s %d\n", (void *) session->pool, (void *) session, apr_pool_tag(session->pool, NULL), (int) memory); #endif @@ -247,7 +251,7 @@ SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t #ifdef DEBUG_ALLOC len = strlen(todup); - if (len > 500) + if (len > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p %p Sess Strdup Allocate %s %ld\n", (void *) session->pool, (void *)session, apr_pool_tag(session->pool, NULL), strlen(todup)); #endif @@ -286,7 +290,7 @@ SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, co len = strlen(todup) + 1; #ifdef DEBUG_ALLOC - if (len > 500) + if (len > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Strdup Allocate %s %d\n", (void *) pool, apr_pool_tag(pool, NULL), (int)len); #endif @@ -457,7 +461,7 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, swi #endif #ifdef DEBUG_ALLOC - if (memory > 500) + if (memory > DEBUG_ALLOC_CUTOFF) switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Allocate %s %d\n", (void *) pool, apr_pool_tag(pool, NULL), (int) memory); /*switch_assert(memory < 20000); */ diff --git a/src/switch_core_session.c b/src/switch_core_session.c index a4a64d96e5..aa0f92f222 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -719,6 +719,7 @@ static const char *message_names[] = { "UNBRIDGE", "TRANSFER", "RINGING", + "ALERTING", "MEDIA", "3P_MEDIA", "NOMEDIA", diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index ff1ee6ff9f..fe64efaf9a 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -2346,11 +2346,12 @@ static void core_event_handler(switch_event_t *event) case SWITCH_EVENT_CHANNEL_EXECUTE: { new_sql() = switch_mprintf("update channels set application='%q',application_data='%q'," - "presence_id='%q',presence_data='%q' where uuid='%q'", + "presence_id='%q',presence_data='%q',accountcode='%q' where uuid='%q'", switch_event_get_header_nil(event, "application"), switch_event_get_header_nil(event, "application-data"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "unique-id") ); @@ -2361,18 +2362,20 @@ static void core_event_handler(switch_event_t *event) { if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set " - "presence_id='%q',presence_data='%q', call_uuid='%q',%s where uuid='%q'", + "presence_id='%q',presence_data='%q',accountcode='%q',call_uuid='%q',%s where uuid='%q'", switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "channel-call-uuid"), extra_cols, switch_event_get_header_nil(event, "unique-id")); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set " - "presence_id='%q',presence_data='%q', call_uuid='%q' where uuid='%q'", + "presence_id='%q',presence_data='%q',accountcode='%q',call_uuid='%q' where uuid='%q'", switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "channel-call-uuid"), switch_event_get_header_nil(event, "unique-id")); } @@ -2463,7 +2466,7 @@ static void core_event_handler(switch_event_t *event) if ((extra_cols = parse_presence_data_cols(event))) { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," "sent_callee_name='%q',sent_callee_num='%q'," - "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',%s " + "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',accountcode='%q',%s " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "caller-caller-id-name"), @@ -2478,13 +2481,14 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), extra_cols, switch_event_get_header_nil(event, "unique-id")); free(extra_cols); } else { new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q'," "sent_callee_name='%q',sent_callee_num='%q'," - "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q' " + "ip_addr='%s',dest='%q',dialplan='%q',context='%q',presence_id='%q',presence_data='%q',accountcode='%q' " "where uuid='%s'", switch_event_get_header_nil(event, "channel-state"), switch_event_get_header_nil(event, "caller-caller-id-name"), @@ -2499,6 +2503,7 @@ static void core_event_handler(switch_event_t *event) switch_event_get_header_nil(event, "caller-context"), switch_event_get_header_nil(event, "channel-presence-id"), switch_event_get_header_nil(event, "channel-presence-data"), + switch_event_get_header_nil(event, "variable_accountcode"), switch_event_get_header_nil(event, "unique-id")); } break; @@ -2705,6 +2710,7 @@ static char create_channels_sql[] = " hostname VARCHAR(256),\n" " presence_id VARCHAR(4096),\n" " presence_data VARCHAR(4096),\n" + " accountcode VARCHAR(256),\n" " callstate VARCHAR(64),\n" " callee_name VARCHAR(1024),\n" " callee_num VARCHAR(256),\n" @@ -2804,6 +2810,7 @@ static char detailed_calls_sql[] = "a.hostname as hostname," "a.presence_id as presence_id," "a.presence_data as presence_data," + "a.accountcode as accountcode," "a.callstate as callstate," "a.callee_name as callee_name," "a.callee_num as callee_num," @@ -2835,6 +2842,7 @@ static char detailed_calls_sql[] = "b.hostname as b_hostname," "b.presence_id as b_presence_id," "b.presence_data as b_presence_data," + "b.accountcode as b_accountcode," "b.callstate as b_callstate," "b.callee_name as b_callee_name," "b.callee_num as b_callee_num," @@ -2874,6 +2882,7 @@ static char basic_calls_sql[] = "a.presence_id as presence_id," "a.presence_data as presence_data," + "a.accountcode as accountcode," "a.callstate as callstate," "a.callee_name as callee_name," "a.callee_num as callee_num," @@ -2897,6 +2906,7 @@ static char basic_calls_sql[] = "b.presence_id as b_presence_id," "b.presence_data as b_presence_data," + "b.accountcode as b_accountcode," "b.callstate as b_callstate," "b.callee_name as b_callee_name," "b.callee_num as b_callee_num," @@ -3437,7 +3447,7 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_ char *err; int result = 0; - switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name, initial_cid_name, initial_cid_num, initial_ip_addr, initial_dest, initial_dialplan, initial_context from channels", "DROP TABLE channels", create_channels_sql); + switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid, read_bit_rate, sent_callee_name, initial_cid_name, initial_cid_num, initial_ip_addr, initial_dest, initial_dialplan, initial_context, accountcode from channels", "DROP TABLE channels", create_channels_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select call_uuid from calls", "DROP TABLE calls", create_calls_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select * from basic_calls where sent_callee_name=''", "DROP VIEW basic_calls", basic_calls_sql); switch_cache_db_test_reactive(sql_manager.dbh, "select * from detailed_calls where sent_callee_name=''", "DROP VIEW detailed_calls", detailed_calls_sql); diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 46755e3b59..62d5daf600 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -552,7 +552,12 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if ((bypass_media_after_bridge || switch_channel_test_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE)) && switch_channel_test_flag(chan_a, CF_ANSWERED) && switch_channel_test_flag(chan_b, CF_ANSWERED)) { - switch_ivr_3p_nomedia(switch_core_session_get_uuid(session_a), SMF_REBRIDGE); + + if (switch_true(switch_channel_get_variable_dup(chan_a, "bypass_media_after_bridge_oldschool", SWITCH_FALSE, -1))) { + switch_ivr_nomedia(switch_core_session_get_uuid(session_a), SMF_REBRIDGE); + } else { + switch_ivr_3p_nomedia(switch_core_session_get_uuid(session_a), SMF_REBRIDGE); + } bypass_media_after_bridge = 0; switch_channel_clear_flag(chan_b, CF_BYPASS_MEDIA_AFTER_BRIDGE); goto end_of_bridge_loop; diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index d856131dd8..4a1d6da68c 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -2252,6 +2252,13 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t const char *transfer_on_failure) { switch_channel_t *channel = switch_core_session_get_channel(session); + char *var_name_invalid = NULL; + + if (!zstr(digits_regex) && !zstr(var_name)) { + var_name_invalid = switch_mprintf("%s_invalid", var_name); + switch_channel_set_variable(channel, var_name_invalid, NULL); + switch_safe_free(var_name_invalid); + } while (switch_channel_ready(channel) && max_tries) { switch_status_t status; @@ -2277,21 +2284,20 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t if (!(status == SWITCH_STATUS_TOO_SMALL && strlen(digit_buffer) == 0)) { if (status == SWITCH_STATUS_SUCCESS) { if (!zstr(digit_buffer)) { - char *invalid_var = NULL; if (zstr(digits_regex)) { return SWITCH_STATUS_SUCCESS; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "Test Regex [%s][%s]\n", digit_buffer, digits_regex); - invalid_var = switch_mprintf("%s_invalid", var_name); if (switch_regex_match(digit_buffer, digits_regex) == SWITCH_STATUS_SUCCESS) { - switch_channel_set_variable(channel, invalid_var, NULL); - switch_safe_free(invalid_var); return SWITCH_STATUS_SUCCESS; } else { switch_channel_set_variable(channel, var_name, NULL); - switch_channel_set_variable(channel, invalid_var, digit_buffer); - switch_safe_free(invalid_var); + if (!zstr(var_name)) { + var_name_invalid = switch_mprintf("%s_invalid", var_name); + switch_channel_set_variable(channel, var_name_invalid, digit_buffer); + switch_safe_free(var_name_invalid); + } } } } diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index bc4289ac37..ba8a1c4a75 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -205,15 +205,15 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable for (impl = ptr->implementations; impl; impl = impl->next) { if (impl->bits_per_second) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Adding Codec %s %d %s %dhz %dms %dbps\n", + "Adding Codec %s %d %s %dhz %dms %dch %dbps\n", impl->iananame, impl->ianacode, ptr->interface_name, impl->actual_samples_per_second, - impl->microseconds_per_packet / 1000, impl->bits_per_second); + impl->microseconds_per_packet / 1000, impl->number_of_channels, impl->bits_per_second); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "Adding Codec %s %d %s %dhz %dms (VBR)\n", + "Adding Codec %s %d %s %dhz %dms %dch (VBR)\n", impl->iananame, impl->ianacode, - ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000); + ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000, impl->number_of_channels); } node = switch_core_alloc(new_module->pool, sizeof(*node)); @@ -2340,7 +2340,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs(const switch_codec_impleme } -SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname) +SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit, uint32_t *channels, char **modname, char **fmtp) { char *cur, *next = NULL, *name, *p; @@ -2380,10 +2380,17 @@ SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uin name = p; } + if ((p = strchr(name, '~'))) { + *p++ = '\0'; + if (fmtp) { + *fmtp = p; + } + } + return name; } -SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, int arraylen, char **prefs, int preflen) +SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_implementation_t **array, char fmtp_array[SWITCH_MAX_CODECS][MAX_FMTP_LEN], int arraylen, char **prefs, int preflen) { int x, i = 0, j = 0; switch_codec_interface_t *codec_interface; @@ -2392,14 +2399,14 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ switch_mutex_lock(loadable_modules.mutex); for (x = 0; x < preflen; x++) { - char *name, buf[256], jbuf[256], *modname = NULL; + char *name, buf[256], jbuf[256], *modname = NULL, *fmtp = NULL; uint32_t interval = 0, rate = 0, bit = 0, channels = 1; switch_copy_string(buf, prefs[x], sizeof(buf)); - name = switch_parse_codec_buf(buf, &interval, &rate, &bit, &channels, &modname); + name = switch_parse_codec_buf(buf, &interval, &rate, &bit, &channels, &modname, &fmtp); for(j = 0; j < x; j++) { - char *jname, *jmodname = NULL; + char *jname, *jmodname = NULL, *jfmtp = NULL; uint32_t jinterval = 0, jrate = 0, jbit = 0, jchannels = 1; uint32_t ointerval = interval, orate = rate, ochannels = channels; @@ -2416,7 +2423,7 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ } switch_copy_string(jbuf, prefs[j], sizeof(jbuf)); - jname = switch_parse_codec_buf(jbuf, &jinterval, &jrate, &jbit, &jchannels, &jmodname); + jname = switch_parse_codec_buf(jbuf, &jinterval, &jrate, &jbit, &jchannels, &jmodname, &jfmtp); if (jinterval == 0) { jinterval = switch_default_ptime(jname, 0); @@ -2430,7 +2437,8 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ jchannels = 1; } - if (!strcasecmp(name, jname) && ointerval == jinterval && orate == jrate && ochannels == jchannels) { + if (!strcasecmp(name, jname) && ointerval == jinterval && orate == jrate && ochannels == jchannels && + !strcasecmp(switch_str_nil(fmtp), switch_str_nil(jfmtp))) { goto next_x; } } @@ -2462,7 +2470,9 @@ SWITCH_DECLARE(int) switch_loadable_module_get_codecs_sorted(const switch_codec_ } } - + if (!zstr(fmtp)) { + switch_set_string(fmtp_array[i], fmtp); + } array[i++] = imp; goto found; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index f30d82f5b7..0649be6c2d 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5175,7 +5175,11 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval) { switch_core_timer_sync(&rtp_session->timer); } - + + if (rtp_session->session) { + switch_ivr_parse_all_messages(rtp_session->session); + } + block = 0; } diff --git a/src/switch_vpx.c b/src/switch_vpx.c index 6ad449f14e..ebfe51da97 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -360,7 +360,7 @@ static switch_status_t init_encoder(switch_codec_t *codec) vpx_codec_enc_cfg_t *config = &context->config; int token_parts = 1; int cpus = switch_core_cpu_count(); - int sane; + int sane, threads = 1; if (!context->codec_settings.video.width) { context->codec_settings.video.width = 1280; @@ -404,7 +404,9 @@ static switch_status_t init_encoder(switch_codec_t *codec) config->rc_target_bitrate = context->bandwidth; config->g_lag_in_frames = 0; config->kf_max_dist = 360;//2000; - config->g_threads = cpus - 1;//(cpus > 1) ? 2 : 1; + threads = cpus / 4; + if (threads < 0) threads = 1; + config->g_threads = threads; if (context->is_vp9) { //config->rc_dropframe_thresh = 2;