diff --git a/Makefile.am b/Makefile.am index 75cc95c30a..282f63642b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -224,7 +224,7 @@ library_include_HEADERS = \ src/include/switch_types.h \ src/include/switch_utils.h \ src/include/switch_rtp.h \ - src/include/switch_vidderbuffer.h \ + src/include/switch_jitterbuffer.h \ src/include/switch_rtcp_frame.h \ src/include/switch_stun.h \ src/include/switch_nat.h \ @@ -234,7 +234,6 @@ library_include_HEADERS = \ src/include/switch_cpp.h \ src/include/switch_curl.h \ src/include/switch_json.h \ - src/include/switch_stfu.h \ src/include/switch_utf8.h \ src/include/switch_vpx.h \ libs/libteletone/src/libteletone_detect.h \ @@ -290,7 +289,7 @@ libfreeswitch_la_SOURCES = \ src/switch_resample.c \ src/switch_regex.c \ src/switch_rtp.c \ - src/switch_vidderbuffer.c \ + src/switch_jitterbuffer.c \ src/switch_ivr_bridge.c \ src/switch_ivr_originate.c \ src/switch_ivr_async.c \ @@ -315,7 +314,6 @@ libfreeswitch_la_SOURCES = \ src/switch_json.c \ src/switch_curl.c \ src/switch_hashtable.c\ - src/switch_stfu.c \ src/switch_utf8.c \ libs/libtpl-1.5/src/tpl.c \ libs/libteletone/src/libteletone_detect.c \ diff --git a/conf/testing/autoload_configs/opus.conf.xml b/conf/testing/autoload_configs/opus.conf.xml index 2ac3f66f86..022cc15912 100644 --- a/conf/testing/autoload_configs/opus.conf.xml +++ b/conf/testing/autoload_configs/opus.conf.xml @@ -1,7 +1,14 @@ + + + + + + + + + diff --git a/conf/vanilla/autoload_configs/modules.conf.xml b/conf/vanilla/autoload_configs/modules.conf.xml index d78669b66d..78c9a42e8f 100644 --- a/conf/vanilla/autoload_configs/modules.conf.xml +++ b/conf/vanilla/autoload_configs/modules.conf.xml @@ -91,7 +91,7 @@ - + diff --git a/conf/vanilla/autoload_configs/opus.conf.xml b/conf/vanilla/autoload_configs/opus.conf.xml index 2ac3f66f86..98a6b7fd1d 100644 --- a/conf/vanilla/autoload_configs/opus.conf.xml +++ b/conf/vanilla/autoload_configs/opus.conf.xml @@ -1,8 +1,15 @@ + - + + + + + + + + + diff --git a/configure.ac b/configure.ac index f2b1357562..170da8f7a5 100644 --- a/configure.ac +++ b/configure.ac @@ -559,13 +559,12 @@ AC_SUBST(SYS_XMLRPC_CFLAGS) AC_SUBST(SYS_XMLRPC_LDFLAGS) AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"]) -PKG_CHECK_MODULES([LUA],[lua5.2],[have_lua=yes],[have_lua=no]) -if test "${have_lua}" = "no" ; then - PKG_CHECK_MODULES([LUA],[lua5.1],[have_lua=yes],[have_lua=no]) -fi -if test "${have_lua}" = "no" ; then - PKG_CHECK_MODULES([LUA],[lua],[have_lua=yes],[have_lua=no]) -fi +for luaversion in lua5.2 lua-5.2 lua5.1 lua-5.1 lua; do + PKG_CHECK_MODULES([LUA],[${luaversion}],[have_lua=yes],[have_lua=no]) + if test ${have_lua} = yes; then + break + fi +done if test x"${LUA_LIBS}" = x"" ; then LUA_LIBS="-llua" fi diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index df94f3dffa..e514ab1a94 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -362,7 +362,8 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch Package: libfreeswitch1 Architecture: any -Depends: \${shlibs:Depends}, \${misc:Depends} +Depends: \${shlibs:Depends}, \${misc:Depends}, + libyuv, libvpx (>= 1.4.0) | libvpx2 Recommends: Suggests: libfreeswitch1-dbg Description: Cross-Platform Scalable Multi-Protocol Soft Switch @@ -370,7 +371,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch . This package contains the FreeSWITCH core library. -Package: python-esl +Package: python-esl Section: python Architecture: any Depends: \${shlibs:Depends}, \${misc:Depends}, \${python:Depends} diff --git a/debian/control-modules b/debian/control-modules index caf64760ce..c009c96ee0 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -113,6 +113,12 @@ Module: applications/mod_hash Description: Hash This module provides a hash API, a key-value in-memory datastore. +Module: applications/mod_hiredis +Description: Redis client support + This module provides a mechanism to use Redis as a datastore. +Build-Depends: libhiredis-dev +Depends: libhiredis0.10 + Module: applications/mod_httapi Description: HT-TAPI Hypertext Telephony API This module provides an API for controlling the switch by responding diff --git a/debian/copyright b/debian/copyright index b94e3fe90c..b3e6c6692b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -488,27 +488,27 @@ License: BSD-2-clause * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * - * This work was supported in part by funding from the Defense Advanced - * Research Projects Agency and the National Science Foundation of the + * This work was supported in part by funding from the Defense Advanced + * Research Projects Agency and the National Science Foundation of the * United States of America, and the CMU Sphinx Speech Consortium. * - * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND - * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND + * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ==================================================================== @@ -1515,24 +1515,24 @@ License: BSD-3-clause Files: libs/libsndfile/src/GSM610/* Copyright: 1992, 1993, 1994 by Jutta Degener and Carsten Bormann License: - Their work was released under the following license which is + Their work was released under the following license which is assumed to be compatible with The GNU Lesser General Public License. - + . ---------------------------------------------------------------------------- - + . Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin - + . Any use of this software is permitted provided that this notice is not removed and that neither the authors nor the Technische Universitaet Berlin are deemed to have made any representations as to the suitability of this software for any purpose nor are held responsible for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. - + . As a matter of courtesy, the authors request to be informed about uses this software has found, about bugs in this software, and about any improvements that may be of general interest. - + . Berlin, 28.11.1994 Jutta Degener (jutta@cs.tu-berlin.de) Carsten Bormann (cabo@cs.tu-berlin.de) @@ -1863,7 +1863,7 @@ Copyright: 2004 Polycom, Inc 2006 Michael Jerris 2001-2009 Steve Underwood 2001-2006 Steve Underwood -Comment: Disclaimer: non-comercial use,gital Equipment Corporation, Maynard, Massachusetts. +Comment: Disclaimer: non-comercial use,gital Equipment Corporation, Maynard, Massachusetts. License: patent-mess Files: libs/libg722_1/autogen.sh @@ -1878,24 +1878,24 @@ License: LGPL-2.1 License: OpenLDAP /* Portions Copyright 1998-2002 The OpenLDAP Foundation * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. A copy of this license is available at * http://www.OpenLDAP.org/license.html or in file LICENSE in the * top-level directory of the distribution. - * + * * OpenLDAP is a registered trademark of the OpenLDAP Foundation. - * + * * Individual files and/or contributed packages may be copyright by * other parties and subject to additional restrictions. - * + * * This work is derived from the University of Michigan LDAP v3.3 * distribution. Information concerning this software is available * at: http://www.umich.edu/~dirsvcs/ldap/ - * + * * This work also contains materials derived from public sources. - * + * * Additional information about OpenLDAP can be obtained at: * http://www.openldap.org/ */ diff --git a/debian/freeswitch-mod-python.install.tmpl b/debian/freeswitch-mod-python.install.tmpl new file mode 100644 index 0000000000..7f855822a1 --- /dev/null +++ b/debian/freeswitch-mod-python.install.tmpl @@ -0,0 +1 @@ +/usr/lib/python*/*-packages/freeswitch.py diff --git a/debian/freeswitch-systemd.freeswitch.conf b/debian/freeswitch-systemd.freeswitch.conf deleted file mode 100644 index 77dfd6908c..0000000000 --- a/debian/freeswitch-systemd.freeswitch.conf +++ /dev/null @@ -1 +0,0 @@ -d /run/freeswitch 0755 freeswitch freeswitch - diff --git a/debian/freeswitch-systemd.freeswitch.service b/debian/freeswitch-systemd.freeswitch.service index c7cf65e4d7..5a46d8731c 100644 --- a/debian/freeswitch-systemd.freeswitch.service +++ b/debian/freeswitch-systemd.freeswitch.service @@ -8,14 +8,12 @@ After=syslog.target network.target local-fs.target ; service Type=forking PIDFile=/run/freeswitch/freeswitch.pid -PermissionsStartOnly=true -ExecStartPre=/bin/mkdir -p /run/freeswitch -ExecStartPre=/bin/chown freeswitch:freeswitch /run/freeswitch ExecStart=/usr/bin/freeswitch -ncwait -nonat TimeoutSec=45s Restart=always ; exec -WorkingDirectory=/var/log/freeswitch +RuntimeDirectory=freeswitch +RuntimeDirectoryMode=0755 User=freeswitch Group=freeswitch LimitCORE=infinity diff --git a/debian/freeswitch-systemd.install b/debian/freeswitch-systemd.install index 7a72d039e7..d647282ecd 100644 --- a/debian/freeswitch-systemd.install +++ b/debian/freeswitch-systemd.install @@ -1,3 +1 @@ /lib/systemd/system/freeswitch.service -/usr/lib/tmpfiles.d/freeswitch.conf - diff --git a/debian/freeswitch.postinst b/debian/freeswitch.postinst index 934101febc..b19277fe8b 100644 --- a/debian/freeswitch.postinst +++ b/debian/freeswitch.postinst @@ -30,9 +30,9 @@ case "$1" in chown freeswitch $x done if [ ! -d "/etc/freeswitch" ]; then - mkdir -p /etc/freeswitch/tls/ - cp -a /usr/share/freeswitch/conf/vanilla/* /etc/freeswitch/ - + mkdir -p /etc/freeswitch/tls/ + chown freeswitch:freeswitch /etc/freeswitch/tls + cp -a /usr/share/freeswitch/conf/vanilla/* /etc/freeswitch/ fi ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/debian/rules b/debian/rules index 46f1f9a221..b2e43d68d0 100755 --- a/debian/rules +++ b/debian/rules @@ -100,10 +100,6 @@ override_dh_auto_install: dh_auto_install -- -C libs/esl pymod-install mkdir -p debian/tmp/lib/systemd/system install -m0644 debian/freeswitch-systemd.freeswitch.service debian/tmp/lib/systemd/system/freeswitch.service - - mkdir -p debian/tmp/usr/lib/tmpfiles.d - install -m0644 debian/freeswitch-systemd.freeswitch.conf debian/tmp/usr/lib/tmpfiles.d/freeswitch.conf - rm -f debian/tmp/usr/share/freeswitch/grammar/model/communicator/COPYING override_dh_installinit: diff --git a/debian/util.sh b/debian/util.sh index 0200409300..be2a7bb004 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -468,7 +468,7 @@ commands: -j Build debs in parallel -k Don't override pbuilder image configurations -K [/path/to/keyring.asc] - Use custom keyring file for sources.list in build environment + Use custom keyring file for sources.list in build environment in the format of: apt-key exportall > /path/to/file.asc -l -m [ quicktest | non-dfsg ] @@ -497,7 +497,7 @@ commands: -d Enable cowbuilder debug hook -k Don't override pbuilder image configurations -K [/path/to/keyring.asc] - Use custom keyring file for sources.list in build environment + Use custom keyring file for sources.list in build environment in the format of: apt-key exportall > /path/to/file.asc -t Use system /etc/apt/sources.list in build environment -T [/path/to/sources.list] diff --git a/docs/Doxygen.conf b/docs/Doxygen.conf index 41920106dc..08b3a978ff 100644 --- a/docs/Doxygen.conf +++ b/docs/Doxygen.conf @@ -1279,9 +1279,6 @@ PREDEFINED =SWITCH_DECLARE(type)=type \ SPAN_DECLARE(type)=type \ SPAN_DECLARE_NONSTD(type)=type \ SPAN_DECLARE_DATA= \ - STFU_DECLARE(type)=type \ - STFU_DECLARE_NONSTD(type)=type \ - STFU_DECLARE_DATA= \ FT_DECLARE(type)=type \ FT_DECLARE_NONSTD(type)=type \ FT_DECLARE_INLINE(type)=type \ diff --git a/html5/verto/demo/js/verto-min.js b/html5/verto/demo/js/verto-min.js index 4ad744cd44..2ea234eb45 100644 --- a/html5/verto/demo/js/verto-min.js +++ b/html5/verto/demo/js/verto-min.js @@ -1,5 +1,5 @@ -var iceTimerSent=0;var iceTimerCompleted=0;var iceTimer;(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} +(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} function findLineInRange(sdpLines,startLine,endLine,prefix,substr){var realEndLine=(endLine!=-1)?endLine:sdpLines.length;for(var i=startLine;iw&&$.FSRTC.validRes[i][1]>h){w=$.FSRTC.validRes[i][0];h=$.FSRTC.validRes[i][1];}} return[w,h];} -var resList=[[320,180],[320,240],[640,360],[640,480],[1280,720],[1920,1080]];var resI=0;var ttl=0;var checkRes=function(cam,func){if(resI>=resList.length){if(func)return func();return;} +var resList=[[320,180],[320,240],[640,360],[640,480],[1280,720],[1920,1080]];var resI=0;var ttl=0;var checkRes=function(cam,func){if(resI>=resList.length){var res={'validRes':$.FSRTC.validRes,'bestResSupported':$.FSRTC.bestResSupported()};localStorage.setItem("res_"+cam,$.toJSON(res));if(func)return func(res);return;} var video={mandatory:{},optional:[]} if(cam){video.optional=[{sourceId:cam}];} w=resList[resI][0];h=resList[resI][1];resI++;video.mandatory={"minWidth":w,"minHeight":h,"maxWidth":w,"maxHeight":h};if(window.moz){video=video.mandatory;if(!video.width)video.width=video.minWidth;if(!video.height)video.height=video.minHeight;if(!video.frameRate)video.frameRate=video.minFrameRate;} getUserMedia({constraints:{audio:ttl++==0,video:video},onsuccess:function(e){e.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=[];$.FSRTC.validRes=[];resI=0;checkRes(cam,func);} -$.FSRTC.checkPerms=function(){getUserMedia({constraints:{audio:true,video:true,},onsuccess:function(e){e.stop();console.info("media perm init complete");},onerror:function(e){console.error("media perm init error");}});}})(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.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={};} if(this.options.sessid){params.sessid=this.options.sessid;} var request={jsonrpc:'2.0',method:method,params:params,id:this._current_id++};if(!success_cb){success_cb=function(e){console.log("Success: ",e);};} if(!error_cb){error_cb=function(e){console.log("Error: ",e);};} @@ -118,10 +125,14 @@ for(i=0;i-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);} dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;} dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;} -if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.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="

"+""+""+""+""+ +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("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}});};} +$.verto.modfuncs={};$.verto.confMan=function(verto,params){var confMan=this;confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;confMan.canvasCount=confMan.params.laData.canvasCount;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var snapshot_id="snapshot_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="

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

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

";jq.append(vlhtml);} $("#"+snapshot_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("vid-write-png",null,file);}});} $("#"+play_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("play",null,file);}});$("#"+stop_id).click(function(){confMan.modCommand("stop",null,"all");});$("#"+recording_id).click(function(){var file=prompt("Please enter file name","");if(file){confMan.modCommand("recording",null,["start",file]);}});$("#"+rec_stop_id).click(function(){confMan.modCommand("recording",null,["stop","all"]);});} @@ -199,28 +221,30 @@ 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;} -var atitle="";var awidth=0;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("");} +var atitle="";var awidth=0;verto.subscribe(confMan.params.laData.chatChannel,{handler:function(v,e){if(typeof(confMan.params.chatCallback)==="function"){confMan.params.chatCallback(v,e);}}});if(confMan.params.laData.role==="moderator"){atitle="Action";awidth=600;if(confMan.params.mainModID){genMainMod($(confMan.params.mainModID));$(confMan.params.displayID).html("Moderator Controls Ready

");}else{$(confMan.params.mainModID).html("");} verto.subscribe(confMan.params.laData.modChannel,{handler:function(v,e){if(confMan.params.onBroadcast){confMan.params.onBroadcast(verto,confMan,e.data);} if(e.data["conf-command"]==="list-videoLayouts"){for(var j=0;j
");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.destroy=function(){var confMan=this;confMan.destroyed=true;if(confMan.lt){confMan.lt.destroy();} +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:"any",useMic:"any",useSpeak:"any",tag:verto.options.tag,localTag:verto.options.localTag,login:verto.options.login,videoParams:verto.options.videoParams},params);dialog.useCamera=verto.options.deviceParams.useCamera;dialog.useMic=verto.options.deviceParams.useMic;dialog.useSpeak=verto.options.deviceParams.useSpeak;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=params.useCamera;dialog.useMic=params.useMic;dialog.useSpeak=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;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(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;} if(!dialog.params.remote_caller_id_name){dialog.params.remote_caller_id_name="Nobody";} if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number="UNKNOWN";} RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;} -RTCcallbacks.onICESDP=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.SDP);dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.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.videoStream,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;} +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;} obj.dialogParams[i]=dialog.params[i];} dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;} return false;} $.verto.dialog.prototype.setState=function(state){var dialog=this;if(dialog.state==$.verto.enum.state.ringing){dialog.stopRinging();} if(dialog.state==state||!checkStateChange(dialog.state,state)){console.error("Dialog "+dialog.callID+": INVALID state change from "+dialog.state.name+" to "+state.name);dialog.hangup();return false;} -console.info("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;} +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);} @@ -238,15 +262,18 @@ dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.proto 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={};} -params.sdp=dialog.params.sdp;dialog.useCamera=dialog.verto.options.deviceParams.useCamera;dialog.useMic=dialog.verto.options.deviceParams.useMic;dialog.useSpeak=dialog.verto.options.deviceParams.useSpeak;if(params){if(params.useVideo){dialog.useVideo(true);} -dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;dialog.useCamera=params.useCamera;dialog.useMic=params.useMic;dialog.useSpeak=params.useSpeak;} +params.sdp=dialog.params.sdp;if(params){if(params.useVideo){dialog.useVideo(true);} +dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_number=params.callee_id_number;if(params.useCamera){dialog.useCamera=params.useCamera;} +if(params.useMic){dialog.useMic=params.useMic;} +if(params.useSpeak){dialog.useSpeak=params.useSpeak;}} dialog.rtc.createAnswer(params);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;} if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;} if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;} dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;} -dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1,hangup:1},requesting:{trying:1,hangup:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$.verto.unloadJobs=[];$(window).bind('beforeunload',function(){for(var f in $.verto.unloadJobs){$.verto.unloadJobs[f]();} +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", "Ítalo Rossi ", "Stefan Yohansson ", - "João Mesquita " + "João Mesquita ", + "Ken Rice " ] diff --git a/html5/verto/verto_communicator/src/css/verto.css b/html5/verto/verto_communicator/src/css/verto.css index 94976e7d48..df7efea2f7 100644 --- a/html5/verto/verto_communicator/src/css/verto.css +++ b/html5/verto/verto_communicator/src/css/verto.css @@ -36,13 +36,19 @@ body { height: 100%; } +.modal-content .modal-footer button.btn-pull-left { + padding-left: 16px; + padding-right: 16px; + margin-left: 5px; +} + /* This is an technique to align the block centered vertically and horizontally in a page. */ .centered-block-frame { + display: flex; display: -webkit-flex; /* Safari */ -webkit-justify-content: center; /* Safari 6.1+ */ -webkit-align-items: center; - display: flex; justify-content: center; align-items: center; object-fit:inherit; @@ -72,6 +78,10 @@ button.btn i { z-index:1001; } +.googlelogin { + margin: 5px 0px; +} + .navbar .navbar-nav > li.navbar-item-icon > a { padding: 18px; height: 60px; @@ -483,6 +493,7 @@ body .modal-body .btn-group .btn.active { #incall .panel { background: #333; + padding-top: 5px; } #incall .hangup-button { @@ -842,6 +853,14 @@ body .modal-body .btn-group .btn.active { /*color: #DDD;*/ } +.members-name { + width: 160px; + overflow: hidden; + text-overflow: ellipsis; + margin-top: 5px; + white-space: nowrap; +} + .chat-members .chat-member-item { padding: 8px 16px; height: 56px; @@ -873,7 +892,7 @@ body .modal-body .btn-group .btn.active { margin: 0; font-size: 16px; display: inline-block; - line-height: 40px; + line-height: 18px; } .chat-members .chat-members-status i { diff --git a/html5/verto/verto_communicator/src/index.html b/html5/verto/verto_communicator/src/index.html index 0719ad4e9c..5945f72fe5 100644 --- a/html5/verto/verto_communicator/src/index.html +++ b/html5/verto/verto_communicator/src/index.html @@ -71,6 +71,7 @@ + @@ -121,9 +122,9 @@ - + diff --git a/html5/verto/verto_communicator/src/partials/chat.html b/html5/verto/verto_communicator/src/partials/chat.html index dea02ff15c..06eee1da7d 100644 --- a/html5/verto/verto_communicator/src/partials/chat.html +++ b/html5/verto/verto_communicator/src/partials/chat.html @@ -21,7 +21,7 @@ -

{{ member.name }}

+

{{ member.name }}
({{ member.number }})

+ +
+ +
+
+ + +
diff --git a/html5/verto/verto_communicator/src/partials/modal_settings.html b/html5/verto/verto_communicator/src/partials/modal_settings.html index ba7d03940e..0f258c2802 100644 --- a/html5/verto/verto_communicator/src/partials/modal_settings.html +++ b/html5/verto/verto_communicator/src/partials/modal_settings.html @@ -112,6 +112,7 @@
diff --git a/html5/verto/verto_communicator/src/partials/video_call.html b/html5/verto/verto_communicator/src/partials/video_call.html index 8c5ec45e7f..da339e4878 100644 --- a/html5/verto/verto_communicator/src/partials/video_call.html +++ b/html5/verto/verto_communicator/src/partials/video_call.html @@ -17,9 +17,6 @@ -
+ diff --git a/html5/verto/verto_communicator/src/storageService/services/storage.js b/html5/verto/verto_communicator/src/storageService/services/storage.js index b457678b35..7120db18de 100644 --- a/html5/verto/verto_communicator/src/storageService/services/storage.js +++ b/html5/verto/verto_communicator/src/storageService/services/storage.js @@ -4,39 +4,40 @@ .module('storageService') .service('storage', ['$rootScope', '$localStorage', function($rootScope, $localStorage) { - var data = $localStorage; + var data = $localStorage, + defaultSettings = { + ui_connected: false, + ws_connected: false, + cur_call: 0, + called_number: '', + useVideo: true, + call_history: {}, + history_control: [], + call_start: false, + name: '', + email: '', + login: '', + password: '', + userStatus: 'disconnected', + mutedVideo: false, + mutedMic: false, + selectedVideo: null, + selectedAudio: null, + selectedShare: null, + useStereo: true, + useSTUN: true, + useDedenc: false, + mirrorInput: false, + outgoingBandwidth: 'default', + incomingBandwidth: 'default', + vidQual: undefined, + askRecoverCall: false, + googNoiseSuppression: true, + googHighpassFilter: true, + googEchoCancellation: true + }; - data.$default({ - ui_connected: false, - ws_connected: false, - cur_call: 0, - called_number: '', - useVideo: true, - call_history: {}, - history_control: [], - call_start: false, - name: '', - email: '', - login: '', - password: '', - userStatus: 'disconnected', - mutedVideo: false, - mutedMic: false, - selectedVideo: null, - selectedAudio: null, - selectedShare: null, - useStereo: true, - useSTUN: true, - useDedenc: false, - mirrorInput: false, - outgoingBandwidth: 'default', - incomingBandwidth: 'default', - vidQual: undefined, - askRecoverCall: false, - googNoiseSuppression: true, - googHighpassFilter: true, - googEchoCancellation: true - }); + data.$default(defaultSettings); function changeData(verto_data) { jQuery.extend(true, data, verto_data); @@ -51,6 +52,9 @@ data.cur_call = 0; data.userStatus = 'disconnected'; }, + factoryReset: function() { + data.$reset(defaultSettings); + }, }; } ]); diff --git a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js index c12eee4d6b..2c7cffc381 100644 --- a/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js +++ b/html5/verto/verto_communicator/src/vertoApp/vertoApp.module.js @@ -13,6 +13,7 @@ 'cgPrompt', '720kb.tooltips', 'ui.gravatar', + 'directive.g+signin', ]); vertoApp.config(['$routeProvider', 'gravatarServiceProvider', @@ -33,11 +34,6 @@ templateUrl: 'partials/incall.html', controller: 'InCallController' }). - /*when('/contributors', { - title: 'Contributors', - templateUrl: 'partials/contributors.html', - controller: 'ContributorsController', - }).*/ when('/browser-upgrade', { title: '', templateUrl: 'partials/browser_upgrade.html', @@ -95,4 +91,4 @@ } ]); -})(); \ No newline at end of file +})(); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js index dde658af16..8c7589c93d 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/DialPadController.js @@ -31,7 +31,18 @@ * fill dialpad via querystring [?autocall=\d+] */ if ($location.search().autocall) { - $rootScope.dialpadNumber = $location.search().autocall; + $rootScope.dialpadNumber = $location.search().autocall; + delete $location.search().autocall; + call($rootScope.dialpadNumber); + } + + /** + * fill in dialpad via config.json + */ + if ('autocall' in verto.data) { + $rootScope.dialpadNumber = verto.data.autocall; + delete verto.data.autocall; + call($rootScope.dialpadNumber); } /** @@ -49,10 +60,7 @@ verto.data.call.transfer($rootScope.dialpadNumber); }; - /** - * Call to the number in the $rootScope.dialpadNumber. - */ - $rootScope.call = function(extension) { + function call(extension) { storage.data.onHold = false; storage.data.cur_call = 0; $rootScope.dialpadNumber = extension; @@ -79,6 +87,13 @@ CallHistory.add($rootScope.dialpadNumber, 'outbound'); $location.path('/incall'); } + + /** + * Call to the number in the $rootScope.dialpadNumber. + */ + $rootScope.call = function(extension) { + return call(extension); + } } ]); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js index c093be086f..47eb987a28 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/InCallController.js @@ -20,6 +20,14 @@ if (storage.data.videoCall) { $scope.callTemplate = 'partials/video_call.html'; } + + $rootScope.$on('call.conference', function(event, data) { + $timeout(function() { + if($scope.chatStatus) { + $scope.openChat(); + } + }); + }); $rootScope.$on('call.video', function(event, data) { $timeout(function() { @@ -78,4 +86,4 @@ } ]); -})(); \ No newline at end of file +})(); diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js index 6ea36372cf..bae60ac31e 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/LoginController.js @@ -1,25 +1,60 @@ (function() { - 'use strict'; + 'use strict'; - angular - .module('vertoControllers') - .controller('LoginController', ['$scope', '$http', '$location', - 'verto', - function($scope, $http, $location, verto) { - $scope.checkBrowser(); + angular + .module('vertoControllers') + .controller('LoginController', ['$scope', '$http', '$location', 'verto', + function($scope, $http, $location, verto) { + $scope.checkBrowser(); - /** - * using stored data (localStorage) for logon - */ - verto.data.name = $scope.storage.data.name; - verto.data.email = $scope.storage.data.email; - if ($scope.storage.data.login != '' && $scope.storage.data.password != '') { - verto.data.login = $scope.storage.data.login; - verto.data.password = $scope.storage.data.password; - } + /* + * Load the Configs before logging in + * with cache buster + */ + + $http.get(window.location.pathname + '/config.json?cachebuster=' + Math.floor((Math.random()*1000000)+1)) + .success(function(data) { + + /* save these for later as we're about to possibly over write them */ + var name = verto.data.name; + var email = verto.data.email; + + console.debug("googlelogin: " + data.googlelogin); + if (data.googlelogin){ + $scope.googlelogin = data.googlelogin; + $scope.googleclientid = data.googleclientid; + } + + angular.extend(verto.data, data); + + /** + * use stored data (localStorage) for login, allow config.json to take precedence + */ + + if (name != '' && data.name == '') { + verto.data.name = name; + } + if (email != '' && data.email == '') { + verto.data.email = email; + } + if (verto.data.login == '' && verto.data.password == '' && $scope.storage.data.login != '' && $scope.storage.data.password != '') { + verto.data.login = $scope.storage.data.login; + verto.data.password = $scope.storage.data.password; + } + + if (verto.data.autologin == "true" && !verto.data.autologin_done) { + console.debug("auto login per config.json"); + verto.data.autologin_done = true; + $scope.login(); + } + }); + + verto.data.name = $scope.storage.data.name; + verto.data.email = $scope.storage.data.email; + + console.debug('Executing LoginController.'); + } + ]); + +})(); - console.debug('Executing LoginController.'); - } - ]); - -})(); \ No newline at end of file diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js index f7e3d5bb91..0363d91f27 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/MainController.js @@ -12,7 +12,7 @@ $scope.verto = verto; $scope.storage = storage; $scope.call_history = angular.element("#call_history").hasClass('active'); - $scope.chatStatus = angular.element('#wrapper').hasClass('toggled'); + $rootScope.chatStatus = angular.element('#wrapper').hasClass('toggled'); /** * (explanation) scope in another controller extends rootScope (singleton) @@ -83,11 +83,15 @@ * Logout the user from verto server and * redirects him to login page. */ - $scope.logout = function() { + $rootScope.logout = function() { var disconnect = function() { var disconnectCallback = function(v, connected) { console.debug('Redirecting to login page.'); storage.reset(); + if (typeof gapi !== 'undefined'){ + console.debug(gapi); + gapi.auth.signOut(); + } $location.path('/login'); }; @@ -202,20 +206,20 @@ }; $scope.toggleChat = function() { - if ($scope.chatStatus && $rootScope.activePane === 'chat') { + if ($rootScope.chatStatus && $rootScope.activePane === 'chat') { $rootScope.chat_counter = 0; } angular.element('#wrapper').toggleClass('toggled'); - $scope.chatStatus = angular.element('#wrapper').hasClass('toggled'); + $rootScope.chatStatus = angular.element('#wrapper').hasClass('toggled'); }; - $scope.openChat = function() { - $scope.chatStatus = false; + $rootScope.openChat = function() { + $rootScope.chatStatus = false; angular.element('#wrapper').removeClass('toggled'); }; $scope.closeChat = function() { - $scope.chatStatus = true; + $rootScope.chatStatus = true; angular.element('#wrapper').addClass('toggled'); }; @@ -240,11 +244,9 @@ Fullscreen.cancel(); } - - console.log($scope.chatStatus); - if (!$scope.chatStatus) { + if (!$rootScope.chatStatus) { angular.element('#wrapper').toggleClass('toggled'); - $scope.chatStatus = angular.element('#wrapper').hasClass('toggled'); + $rootScope.chatStatus = angular.element('#wrapper').hasClass('toggled'); } $rootScope.dialpadNumber = ''; @@ -277,6 +279,40 @@ }); + $scope.$on('event:google-plus-signin-success', function (event,authResult) { + // Send login to server or save into cookie + console.log('Google+ Login Success'); + console.log(authResult); + gapi.client.load('plus', 'v1', gapiClientLoaded); + }); + + function gapiClientLoaded() { + gapi.client.plus.people.get({userId: 'me'}).execute(handleEmailResponse); + } + + function handleEmailResponse(resp){ + var primaryEmail; + for (var i=0; i < resp.emails.length; i++) { + if (resp.emails[i].type === 'account') primaryEmail = resp.emails[i].value; + } + console.debug("Primary Email: " + primaryEmail ); + console.debug("display name: " + resp.displayName); + console.debug("imageurl: " + resp.image.url); + console.debug(resp); + console.debug(verto.data); + verto.data.email = primaryEmail; + verto.data.name = resp.displayName; + storage.data.name = verto.data.name; + storage.data.email = verto.data.email; + + $scope.login(); + } + + $scope.$on('event:google-plus-signin-failure', function (event,authResult) { + // Auth failure or signout detected + console.log('Google+ Login Failure'); + }); + $rootScope.callActive = function(data) { verto.data.mutedMic = storage.data.mutedMic; verto.data.mutedVideo = storage.data.mutedVideo; @@ -355,7 +391,9 @@ //}; // //verto.hangup(hangupCallback); - + if (verto.data.shareCall) { + verto.screenshareHangup(); + } verto.hangup(); }; diff --git a/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js b/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js index 48e430d578..b144d3026e 100644 --- a/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js +++ b/html5/verto/verto_communicator/src/vertoControllers/controllers/ModalSettingsController.js @@ -24,7 +24,16 @@ $scope.refreshDeviceList = function() { return verto.refreshDevices(); - } + }; + + $scope.resetSettings = function() { + if (confirm('Factory Reset Settings?')) { + storage.factoryReset(); + $scope.logout(); + $scope.ok(); + window.location.reload(); + }; + }; } ]); diff --git a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js index 3c5586012f..940ae1059d 100644 --- a/html5/verto/verto_communicator/src/vertoService/services/vertoService.js +++ b/html5/verto/verto_communicator/src/vertoService/services/vertoService.js @@ -199,13 +199,20 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora bandwidth: bandwidth, refreshDevicesCallback : function refreshDevicesCallback() { - data.videoDevices = []; + data.videoDevices = [{ + id: 'none', + label: 'No Camera' + }]; data.shareDevices = [{ id: 'screen', label: 'Screen' }]; data.audioDevices = []; + if(!storage.data.selectedShare) { + storage.data.selectedShare = data.shareDevices[0]['id']; + } + for (var i in jQuery.verto.videoDevices) { var device = jQuery.verto.videoDevices[i]; if (!device.label) { @@ -328,6 +335,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora function startConference(v, dialog, pvtData) { $rootScope.$emit('call.video', 'video'); + $rootScope.$emit('call.conference', 'conference'); data.chattingWith = pvtData.chatID; data.confRole = pvtData.role; @@ -413,6 +421,7 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora function stopConference() { console.log('stopConference()'); if (data.liveArray) { + data.liveArray.destroy(); console.log('Has data.liveArray.'); $rootScope.$emit('members.clear'); data.liveArray = null; @@ -503,6 +512,10 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora if (d.params.screenShare) { cleanShareCall(that); } else { + if (data.liveArray) { + data.liveArray.destroy(); + } + if (data.conf) { data.conf.destroy(); } diff --git a/html5/verto/video_demo/js/verto-min.js b/html5/verto/video_demo/js/verto-min.js index 8235c77def..622cfa10a4 100644 --- a/html5/verto/video_demo/js/verto-min.js +++ b/html5/verto/video_demo/js/verto-min.js @@ -1,5 +1,5 @@ -var iceTimerSent=0;var iceTimerCompleted=0;var iceTimer;(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} +(function($){function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLines,0,-1,prefix,substr);} function findLineInRange(sdpLines,startLine,endLine,prefix,substr){var realEndLine=(endLine!=-1)?endLine:sdpLines.length;for(var i=startLine;i$.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: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);} @@ -270,6 +276,6 @@ dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog 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 + + + + + + + SIMCLIST_NO_DUMPRESTORE;_CRT_SECURE_NO_WARNINGS;KS_EXPORTS;%(PreprocessorDefinitions) + $(ProjectDir)\src\include;$(ProjectDir)\src\win\sys;$(ProjectDir)\src\win;%(AdditionalIncludeDirectories) + 4574;4100;4127;4668;4255;4706;4710;4820 + + + + \ No newline at end of file diff --git a/libs/libks/libks.sln b/libs/libks/libks.sln new file mode 100644 index 0000000000..fe03d30e74 --- /dev/null +++ b/libs/libks/libks.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libks", "libks.vcxproj", "{70D178D8-1100-4152-86C0-809A91CFF832}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testpools", "test\testpools\testpools.vcxproj", "{766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}" + ProjectSection(ProjectDependencies) = postProject + {70D178D8-1100-4152-86C0-809A91CFF832} = {70D178D8-1100-4152-86C0-809A91CFF832} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x64.ActiveCfg = Debug|x64 + {70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x64.Build.0 = Debug|x64 + {70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x86.ActiveCfg = Debug|Win32 + {70D178D8-1100-4152-86C0-809A91CFF832}.Debug|x86.Build.0 = Debug|Win32 + {70D178D8-1100-4152-86C0-809A91CFF832}.Release|x64.ActiveCfg = Release|x64 + {70D178D8-1100-4152-86C0-809A91CFF832}.Release|x64.Build.0 = Release|x64 + {70D178D8-1100-4152-86C0-809A91CFF832}.Release|x86.ActiveCfg = Release|Win32 + {70D178D8-1100-4152-86C0-809A91CFF832}.Release|x86.Build.0 = Release|Win32 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Debug|x64.ActiveCfg = Debug|x64 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Debug|x64.Build.0 = Debug|x64 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Debug|x86.ActiveCfg = Debug|Win32 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Debug|x86.Build.0 = Debug|Win32 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Release|x64.ActiveCfg = Release|x64 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Release|x64.Build.0 = Release|x64 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Release|x86.ActiveCfg = Release|Win32 + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libs/libks/libks.vcxproj b/libs/libks/libks.vcxproj new file mode 100644 index 0000000000..1a40dd2f02 --- /dev/null +++ b/libs/libks/libks.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {70D178D8-1100-4152-86C0-809A91CFF832} + Win32Proj + 8.1 + + + + DynamicLibrary + true + v140 + + + DynamicLibrary + false + v140 + + + DynamicLibrary + true + v140 + + + DynamicLibrary + false + v140 + + + + + + + + + + + + + + + + + + + + + + + + + true + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + + + true + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + EnableAllWarnings + ProgramDatabase + Disabled + %(AdditionalIncludeDirectories) + + + MachineX86 + true + Windows + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;%(PreprocessorDefinitions) + MultiThreadedDLL + EnableAllWarnings + ProgramDatabase + %(AdditionalIncludeDirectories) + + + MachineX86 + true + Windows + true + true + + + + + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;%(PreprocessorDefinitions) + ProgramDatabase + EnableAllWarnings + + + + + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBKS_EXPORTS;%(PreprocessorDefinitions) + EnableAllWarnings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libs/libks/libks.vcxproj.filters b/libs/libks/libks.vcxproj.filters new file mode 100644 index 0000000000..3b2d013492 --- /dev/null +++ b/libs/libks/libks.vcxproj.filters @@ -0,0 +1,93 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/libs/libks/src/include/ks.h b/libs/libks/src/include/ks.h index 2b14891ac4..16dffd024a 100644 --- a/libs/libks/src/include/ks.h +++ b/libs/libks/src/include/ks.h @@ -35,6 +35,7 @@ #define _KS_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -42,160 +43,8 @@ extern "C" { #define ks_copy_string(_x, _y, _z) strncpy(_x, _y, _z - 1) #define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x)) -#define KS_VA_NONE "%s", "" -typedef enum { - KS_POLL_READ = (1 << 0), - KS_POLL_WRITE = (1 << 1), - KS_POLL_ERROR = (1 << 2) -} ks_poll_t; - -#ifdef WIN32 -#define KS_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY -#define KS_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE -#define KS_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY -#define KS_SEQ_BRED FOREGROUND_RED -#define KS_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY -#define KS_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED -#define KS_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY -#define KS_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE -#define KS_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY -#define KS_SEQ_BGREEN FOREGROUND_GREEN -#define KS_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY -#define KS_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN -#define KS_SEQ_DEFAULT_COLOR KS_SEQ_FWHITE -#define KS_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY -#define KS_SEQ_BBLUE FOREGROUND_BLUE -#define KS_SEQ_FBLACK 0 | FOREGROUND_INTENSITY -#define KS_SEQ_BBLACK 0 -#else -#define KS_SEQ_ESC "\033[" -/* Ansi Control character suffixes */ -#define KS_SEQ_HOME_CHAR 'H' -#define KS_SEQ_HOME_CHAR_STR "H" -#define KS_SEQ_CLEARLINE_CHAR '1' -#define KS_SEQ_CLEARLINE_CHAR_STR "1" -#define KS_SEQ_CLEARLINEEND_CHAR "K" -#define KS_SEQ_CLEARSCR_CHAR0 '2' -#define KS_SEQ_CLEARSCR_CHAR1 'J' -#define KS_SEQ_CLEARSCR_CHAR "2J" -#define KS_SEQ_DEFAULT_COLOR KS_SEQ_ESC KS_SEQ_END_COLOR /* Reset to Default fg/bg color */ -#define KS_SEQ_AND_COLOR ";" /* To add multiple color definitions */ -#define KS_SEQ_END_COLOR "m" /* To end color definitions */ -/* Foreground colors values */ -#define KS_SEQ_F_BLACK "30" -#define KS_SEQ_F_RED "31" -#define KS_SEQ_F_GREEN "32" -#define KS_SEQ_F_YELLOW "33" -#define KS_SEQ_F_BLUE "34" -#define KS_SEQ_F_MAGEN "35" -#define KS_SEQ_F_CYAN "36" -#define KS_SEQ_F_WHITE "37" -/* Background colors values */ -#define KS_SEQ_B_BLACK "40" -#define KS_SEQ_B_RED "41" -#define KS_SEQ_B_GREEN "42" -#define KS_SEQ_B_YELLOW "43" -#define KS_SEQ_B_BLUE "44" -#define KS_SEQ_B_MAGEN "45" -#define KS_SEQ_B_CYAN "46" -#define KS_SEQ_B_WHITE "47" -/* Preset escape sequences - Change foreground colors only */ -#define KS_SEQ_FBLACK KS_SEQ_ESC KS_SEQ_F_BLACK KS_SEQ_END_COLOR -#define KS_SEQ_FRED KS_SEQ_ESC KS_SEQ_F_RED KS_SEQ_END_COLOR -#define KS_SEQ_FGREEN KS_SEQ_ESC KS_SEQ_F_GREEN KS_SEQ_END_COLOR -#define KS_SEQ_FYELLOW KS_SEQ_ESC KS_SEQ_F_YELLOW KS_SEQ_END_COLOR -#define KS_SEQ_FBLUE KS_SEQ_ESC KS_SEQ_F_BLUE KS_SEQ_END_COLOR -#define KS_SEQ_FMAGEN KS_SEQ_ESC KS_SEQ_F_MAGEN KS_SEQ_END_COLOR -#define KS_SEQ_FCYAN KS_SEQ_ESC KS_SEQ_F_CYAN KS_SEQ_END_COLOR -#define KS_SEQ_FWHITE KS_SEQ_ESC KS_SEQ_F_WHITE KS_SEQ_END_COLOR -#define KS_SEQ_BBLACK KS_SEQ_ESC KS_SEQ_B_BLACK KS_SEQ_END_COLOR -#define KS_SEQ_BRED KS_SEQ_ESC KS_SEQ_B_RED KS_SEQ_END_COLOR -#define KS_SEQ_BGREEN KS_SEQ_ESC KS_SEQ_B_GREEN KS_SEQ_END_COLOR -#define KS_SEQ_BYELLOW KS_SEQ_ESC KS_SEQ_B_YELLOW KS_SEQ_END_COLOR -#define KS_SEQ_BBLUE KS_SEQ_ESC KS_SEQ_B_BLUE KS_SEQ_END_COLOR -#define KS_SEQ_BMAGEN KS_SEQ_ESC KS_SEQ_B_MAGEN KS_SEQ_END_COLOR -#define KS_SEQ_BCYAN KS_SEQ_ESC KS_SEQ_B_CYAN KS_SEQ_END_COLOR -#define KS_SEQ_BWHITE KS_SEQ_ESC KS_SEQ_B_WHITE KS_SEQ_END_COLOR -/* Preset escape sequences */ -#define KS_SEQ_HOME KS_SEQ_ESC KS_SEQ_HOME_CHAR_STR -#define KS_SEQ_CLEARLINE KS_SEQ_ESC KS_SEQ_CLEARLINE_CHAR_STR -#define KS_SEQ_CLEARLINEEND KS_SEQ_ESC KS_SEQ_CLEARLINEEND_CHAR -#define KS_SEQ_CLEARSCR KS_SEQ_ESC KS_SEQ_CLEARSCR_CHAR KS_SEQ_HOME -#endif - -#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) -#define _XOPEN_SOURCE 600 -#endif - -#ifndef HAVE_STRINGS_H -#define HAVE_STRINGS_H 1 -#endif -#ifndef HAVE_SYS_SOCKET_H -#define HAVE_SYS_SOCKET_H 1 -#endif - -#ifndef __WINDOWS__ -#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) -#define __WINDOWS__ -#endif -#endif - -#ifdef _MSC_VER -#ifndef __inline__ -#define __inline__ __inline -#endif -#if (_MSC_VER >= 1400) /* VC8+ */ -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE -#endif -#ifndef _CRT_NONSTDC_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE -#endif -#endif -#ifndef strcasecmp -#define strcasecmp(s1, s2) _stricmp(s1, s2) -#endif -#ifndef strncasecmp -#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) -#endif -#ifndef snprintf -#define snprintf _snprintf -#endif -#ifndef S_IRUSR -#define S_IRUSR _S_IREAD -#endif -#ifndef S_IWUSR -#define S_IWUSR _S_IWRITE -#endif -#undef HAVE_STRINGS_H -#undef HAVE_SYS_SOCKET_H -#endif - -#include -#ifndef WIN32 -#include -#endif - -#include -#include -#include -#include -#ifndef WIN32 -#include -#include -#include -#include -#include -#include -#endif - -#ifdef HAVE_STRINGS_H -#include -#endif -#include - #if (_MSC_VER >= 1400) // VC8+ #define ks_assert(expr) assert(expr);__analysis_assume( expr ) #endif @@ -209,66 +58,9 @@ typedef enum { #define ks_strlen_zero_buf(s) (*(s) == '\0') #define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1) -#ifdef WIN32 -#include -#include -typedef SOCKET ks_socket_t; -typedef unsigned __int64 uint64_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int8 uint8_t; -typedef __int64 int64_t; -typedef __int32 int32_t; -typedef __int16 int16_t; -typedef __int8 int8_t; -typedef intptr_t ks_ssize_t; -typedef int ks_filehandle_t; -#define KS_SOCK_INVALID INVALID_SOCKET -#define strerror_r(num, buf, size) strerror_s(buf, size, num) -#if defined(KS_DECLARE_STATIC) -#define KS_DECLARE(type) type __stdcall -#define KS_DECLARE_NONSTD(type) type __cdecl -#define KS_DECLARE_DATA -#elif defined(KS_EXPORTS) -#define KS_DECLARE(type) __declspec(dllexport) type __stdcall -#define KS_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl -#define KS_DECLARE_DATA __declspec(dllexport) -#else -#define KS_DECLARE(type) __declspec(dllimport) type __stdcall -#define KS_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl -#define KS_DECLARE_DATA __declspec(dllimport) -#endif -#else -#define KS_DECLARE(type) type -#define KS_DECLARE_NONSTD(type) type -#define KS_DECLARE_DATA -#include -#include -#include -#include -#include -#include -#include -#define KS_SOCK_INVALID -1 -typedef int ks_socket_t; -typedef ssize_t ks_ssize_t; -typedef int ks_filehandle_t; -#endif - #include "math.h" #include "ks_json.h" -typedef int16_t ks_port_t; -typedef size_t ks_size_t; - -typedef enum { - KS_SUCCESS, - KS_FAIL, - KS_BREAK, - KS_DISCONNECTED, - KS_GENERR -} ks_status_t; - #define BUF_CHUNK 65536 * 50 #define BUF_START 65536 * 100 @@ -279,37 +71,6 @@ typedef enum { #define ks_set_flag(obj, flag) (obj)->flags |= (flag) #define ks_clear_flag(obj, flag) (obj)->flags &= ~(flag) -/*! \brief Used internally for truth test */ -typedef enum { - KS_TRUE = 1, - KS_FALSE = 0 -} ks_bool_t; - -#ifndef __FUNCTION__ -#define __FUNCTION__ (const char *)__func__ -#endif - -#define KS_PRE __FILE__, __FUNCTION__, __LINE__ -#define KS_LOG_LEVEL_DEBUG 7 -#define KS_LOG_LEVEL_INFO 6 -#define KS_LOG_LEVEL_NOTICE 5 -#define KS_LOG_LEVEL_WARNING 4 -#define KS_LOG_LEVEL_ERROR 3 -#define KS_LOG_LEVEL_CRIT 2 -#define KS_LOG_LEVEL_ALERT 1 -#define KS_LOG_LEVEL_EMERG 0 - -#define KS_LOG_DEBUG KS_PRE, KS_LOG_LEVEL_DEBUG -#define KS_LOG_INFO KS_PRE, KS_LOG_LEVEL_INFO -#define KS_LOG_NOTICE KS_PRE, KS_LOG_LEVEL_NOTICE -#define KS_LOG_WARNING KS_PRE, KS_LOG_LEVEL_WARNING -#define KS_LOG_ERROR KS_PRE, KS_LOG_LEVEL_ERROR -#define KS_LOG_CRIT KS_PRE, KS_LOG_LEVEL_CRIT -#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT -#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG -typedef void (*ks_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...); -typedef void (*ks_listen_callback_t)(ks_socket_t server_sock, ks_socket_t client_sock, struct sockaddr_in *addr); - KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap); diff --git a/libs/libks/src/include/ks_platform.h b/libs/libks/src/include/ks_platform.h new file mode 100644 index 0000000000..a310e474d0 --- /dev/null +++ b/libs/libks/src/include/ks_platform.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2007-2014, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _KS_PLATFORM_H_ +#define _KS_PLATFORM_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) +#define _XOPEN_SOURCE 600 +#endif + +#ifndef HAVE_STRINGS_H +#define HAVE_STRINGS_H 1 +#endif +#ifndef HAVE_SYS_SOCKET_H +#define HAVE_SYS_SOCKET_H 1 +#endif + +#ifndef __WINDOWS__ +#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32) +#define __WINDOWS__ +#endif +#endif + +#ifdef _MSC_VER +#ifndef __inline__ +#define __inline__ __inline +#endif +#if (_MSC_VER >= 1400) /* VC8+ */ +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif +#endif +#ifndef strcasecmp +#define strcasecmp(s1, s2) _stricmp(s1, s2) +#endif +#ifndef strncasecmp +#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) +#endif +#if (_MSC_VER < 1900) /* VC 2015 */ +#ifndef snprintf +#define snprintf _snprintf +#endif +#endif +#ifndef S_IRUSR +#define S_IRUSR _S_IREAD +#endif +#ifndef S_IWUSR +#define S_IWUSR _S_IWRITE +#endif +#undef HAVE_STRINGS_H +#undef HAVE_SYS_SOCKET_H +#endif + +#include +#ifndef WIN32 +#include +#endif + +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif +#include + + +#ifdef WIN32 +#include +#include +typedef SOCKET ks_socket_t; +typedef unsigned __int64 uint64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int8 uint8_t; +typedef __int64 int64_t; +typedef __int32 int32_t; +typedef __int16 int16_t; +typedef __int8 int8_t; +typedef intptr_t ks_ssize_t; +typedef int ks_filehandle_t; +#define KS_SOCK_INVALID INVALID_SOCKET +#define strerror_r(num, buf, size) strerror_s(buf, size, num) +#if defined(KS_DECLARE_STATIC) +#define KS_DECLARE(type) type __stdcall +#define KS_DECLARE_NONSTD(type) type __cdecl +#define KS_DECLARE_DATA +#elif defined(KS_EXPORTS) +#define KS_DECLARE(type) __declspec(dllexport) type __stdcall +#define KS_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl +#define KS_DECLARE_DATA __declspec(dllexport) +#else +#define KS_DECLARE(type) __declspec(dllimport) type __stdcall +#define KS_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl +#define KS_DECLARE_DATA __declspec(dllimport) +#endif +#else // !WIN32 +#define KS_DECLARE(type) type +#define KS_DECLARE_NONSTD(type) type +#define KS_DECLARE_DATA +#include +#include +#include +#include +#include +#include +#include +#define KS_SOCK_INVALID -1 +typedef int ks_socket_t; +typedef ssize_t ks_ssize_t; +typedef int ks_filehandle_t; +#endif + + + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ +#endif /* defined(_KS_PLATFORM_H_) */ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/include/ks_types.h b/libs/libks/src/include/ks_types.h new file mode 100644 index 0000000000..ec25e35265 --- /dev/null +++ b/libs/libks/src/include/ks_types.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2007-2014, Anthony Minessale II + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of the original author; nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _KS_TYPES_H_ +#define _KS_TYPES_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* defined(__cplusplus) */ + +#include + +#define KS_VA_NONE "%s", "" + + +typedef enum { + KS_POLL_READ = (1 << 0), + KS_POLL_WRITE = (1 << 1), + KS_POLL_ERROR = (1 << 2) +} ks_poll_t; + +#ifdef WIN32 +#define KS_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY +#define KS_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE +#define KS_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY +#define KS_SEQ_BRED FOREGROUND_RED +#define KS_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY +#define KS_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED +#define KS_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY +#define KS_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE +#define KS_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY +#define KS_SEQ_BGREEN FOREGROUND_GREEN +#define KS_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY +#define KS_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN +#define KS_SEQ_DEFAULT_COLOR KS_SEQ_FWHITE +#define KS_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY +#define KS_SEQ_BBLUE FOREGROUND_BLUE +#define KS_SEQ_FBLACK 0 | FOREGROUND_INTENSITY +#define KS_SEQ_BBLACK 0 +#else +#define KS_SEQ_ESC "\033[" +/* Ansi Control character suffixes */ +#define KS_SEQ_HOME_CHAR 'H' +#define KS_SEQ_HOME_CHAR_STR "H" +#define KS_SEQ_CLEARLINE_CHAR '1' +#define KS_SEQ_CLEARLINE_CHAR_STR "1" +#define KS_SEQ_CLEARLINEEND_CHAR "K" +#define KS_SEQ_CLEARSCR_CHAR0 '2' +#define KS_SEQ_CLEARSCR_CHAR1 'J' +#define KS_SEQ_CLEARSCR_CHAR "2J" +#define KS_SEQ_DEFAULT_COLOR KS_SEQ_ESC KS_SEQ_END_COLOR /* Reset to Default fg/bg color */ +#define KS_SEQ_AND_COLOR ";" /* To add multiple color definitions */ +#define KS_SEQ_END_COLOR "m" /* To end color definitions */ +/* Foreground colors values */ +#define KS_SEQ_F_BLACK "30" +#define KS_SEQ_F_RED "31" +#define KS_SEQ_F_GREEN "32" +#define KS_SEQ_F_YELLOW "33" +#define KS_SEQ_F_BLUE "34" +#define KS_SEQ_F_MAGEN "35" +#define KS_SEQ_F_CYAN "36" +#define KS_SEQ_F_WHITE "37" +/* Background colors values */ +#define KS_SEQ_B_BLACK "40" +#define KS_SEQ_B_RED "41" +#define KS_SEQ_B_GREEN "42" +#define KS_SEQ_B_YELLOW "43" +#define KS_SEQ_B_BLUE "44" +#define KS_SEQ_B_MAGEN "45" +#define KS_SEQ_B_CYAN "46" +#define KS_SEQ_B_WHITE "47" +/* Preset escape sequences - Change foreground colors only */ +#define KS_SEQ_FBLACK KS_SEQ_ESC KS_SEQ_F_BLACK KS_SEQ_END_COLOR +#define KS_SEQ_FRED KS_SEQ_ESC KS_SEQ_F_RED KS_SEQ_END_COLOR +#define KS_SEQ_FGREEN KS_SEQ_ESC KS_SEQ_F_GREEN KS_SEQ_END_COLOR +#define KS_SEQ_FYELLOW KS_SEQ_ESC KS_SEQ_F_YELLOW KS_SEQ_END_COLOR +#define KS_SEQ_FBLUE KS_SEQ_ESC KS_SEQ_F_BLUE KS_SEQ_END_COLOR +#define KS_SEQ_FMAGEN KS_SEQ_ESC KS_SEQ_F_MAGEN KS_SEQ_END_COLOR +#define KS_SEQ_FCYAN KS_SEQ_ESC KS_SEQ_F_CYAN KS_SEQ_END_COLOR +#define KS_SEQ_FWHITE KS_SEQ_ESC KS_SEQ_F_WHITE KS_SEQ_END_COLOR +#define KS_SEQ_BBLACK KS_SEQ_ESC KS_SEQ_B_BLACK KS_SEQ_END_COLOR +#define KS_SEQ_BRED KS_SEQ_ESC KS_SEQ_B_RED KS_SEQ_END_COLOR +#define KS_SEQ_BGREEN KS_SEQ_ESC KS_SEQ_B_GREEN KS_SEQ_END_COLOR +#define KS_SEQ_BYELLOW KS_SEQ_ESC KS_SEQ_B_YELLOW KS_SEQ_END_COLOR +#define KS_SEQ_BBLUE KS_SEQ_ESC KS_SEQ_B_BLUE KS_SEQ_END_COLOR +#define KS_SEQ_BMAGEN KS_SEQ_ESC KS_SEQ_B_MAGEN KS_SEQ_END_COLOR +#define KS_SEQ_BCYAN KS_SEQ_ESC KS_SEQ_B_CYAN KS_SEQ_END_COLOR +#define KS_SEQ_BWHITE KS_SEQ_ESC KS_SEQ_B_WHITE KS_SEQ_END_COLOR +/* Preset escape sequences */ +#define KS_SEQ_HOME KS_SEQ_ESC KS_SEQ_HOME_CHAR_STR +#define KS_SEQ_CLEARLINE KS_SEQ_ESC KS_SEQ_CLEARLINE_CHAR_STR +#define KS_SEQ_CLEARLINEEND KS_SEQ_ESC KS_SEQ_CLEARLINEEND_CHAR +#define KS_SEQ_CLEARSCR KS_SEQ_ESC KS_SEQ_CLEARSCR_CHAR KS_SEQ_HOME +#endif + +typedef int16_t ks_port_t; +typedef size_t ks_size_t; + +typedef enum { + KS_SUCCESS, + KS_FAIL, + KS_BREAK, + KS_DISCONNECTED, + KS_GENERR +} ks_status_t; + +/*! \brief Used internally for truth test */ +typedef enum { + KS_TRUE = 1, + KS_FALSE = 0 +} ks_bool_t; + +#ifndef __FUNCTION__ +#define __FUNCTION__ (const char *)__func__ +#endif + +#define KS_PRE __FILE__, __FUNCTION__, __LINE__ +#define KS_LOG_LEVEL_DEBUG 7 +#define KS_LOG_LEVEL_INFO 6 +#define KS_LOG_LEVEL_NOTICE 5 +#define KS_LOG_LEVEL_WARNING 4 +#define KS_LOG_LEVEL_ERROR 3 +#define KS_LOG_LEVEL_CRIT 2 +#define KS_LOG_LEVEL_ALERT 1 +#define KS_LOG_LEVEL_EMERG 0 + +#define KS_LOG_DEBUG KS_PRE, KS_LOG_LEVEL_DEBUG +#define KS_LOG_INFO KS_PRE, KS_LOG_LEVEL_INFO +#define KS_LOG_NOTICE KS_PRE, KS_LOG_LEVEL_NOTICE +#define KS_LOG_WARNING KS_PRE, KS_LOG_LEVEL_WARNING +#define KS_LOG_ERROR KS_PRE, KS_LOG_LEVEL_ERROR +#define KS_LOG_CRIT KS_PRE, KS_LOG_LEVEL_CRIT +#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT +#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG +typedef void (*ks_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...); +typedef void (*ks_listen_callback_t)(ks_socket_t server_sock, ks_socket_t client_sock, struct sockaddr_in *addr); + + +#ifdef __cplusplus +} +#endif /* defined(__cplusplus) */ + + +#endif /* defined(_KS_TYPES_H_) */ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ + diff --git a/libs/libks/src/include/mpool.h b/libs/libks/src/include/mpool.h index 23ac93fb91..b1c1ba7c58 100644 --- a/libs/libks/src/include/mpool.h +++ b/libs/libks/src/include/mpool.h @@ -24,6 +24,7 @@ #ifndef __MPOOL_H__ #define __MPOOL_H__ +#include "ks.h" #include /* @@ -34,7 +35,7 @@ * Choose a best fit algorithm not first fit. This takes more CPU * time but will result in a tighter heap. */ -#define MPOOL_FLAG_BEST_FIT (1<<0) +#define MPOOL_FLAG_BEST_FIT (1<<0) /* * By default the library adds 2 bytes onto all allocations to insert @@ -43,7 +44,7 @@ * going to be performed on the pool and to not waste memory on these * bytes. */ -#define MPOOL_FLAG_NO_FREE (1<<1) +#define MPOOL_FLAG_NO_FREE (1<<1) /* * This enables very heavy packing at the possible expense of CPU. @@ -58,48 +59,47 @@ * and then it will give up. This flag forces it to look until it * finds it. */ -#define MPOOL_FLAG_HEAVY_PACKING (1<<2) +#define MPOOL_FLAG_HEAVY_PACKING (1<<2) /* - * Use sbrk not mmap to allocate pages. This is not recommended for - * normal use. + * Use MMAP_ANONYMOUS instead of /dev/zero */ -#define MPOOL_FLAG_USE_SBRK (1<<3) +#define MPOOL_FLAG_ANONYMOUS (1<<3) /* * Mpool error codes */ -#define MPOOL_ERROR_NONE 1 /* no error */ -#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */ -#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */ -#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */ -#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */ -#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */ -#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */ -#define MPOOL_ERROR_NO_MEM 8 /* no memory available */ -#define MPOOL_ERROR_MMAP 9 /* problems with mmap */ -#define MPOOL_ERROR_SIZE 10 /* error processing requested size */ -#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */ -#define MPOOL_ERROR_MEM 12 /* invalid memory address */ -#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */ -#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */ -#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */ -#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */ -#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */ -#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/ -#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */ -#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */ -#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */ +#define MPOOL_ERROR_NONE 1 /* no error */ +#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */ +#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */ +#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */ +#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */ +#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */ +#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */ +#define MPOOL_ERROR_NO_MEM 8 /* no memory available */ +#define MPOOL_ERROR_MMAP 9 /* problems with mmap */ +#define MPOOL_ERROR_SIZE 10 /* error processing requested size */ +#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */ +#define MPOOL_ERROR_MEM 12 /* invalid memory address */ +#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */ +#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */ +#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */ +#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */ +#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */ +#define MPOOL_ERROR_UNUSED 18 /* UNUSED */ +#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */ +#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */ +#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */ /* * Mpool function IDs for the mpool_log_func callback function. */ -#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */ -#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */ -#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */ -#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */ -#define MPOOL_FUNC_FREE 5 /* mpool_free function called */ -#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */ +#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */ +#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */ +#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */ +#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */ +#define MPOOL_FUNC_FREE 5 /* mpool_free function called */ +#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */ /* * void mpool_log_func_t @@ -133,12 +133,12 @@ * old_byte_size -> Optionally specified old byte size. For * mpool_resize only. */ -typedef void (*mpool_log_func_t)(const void *mp_p, - const int func_id, - const unsigned long byte_size, - const unsigned long ele_n, - const void *old_addr, const void *new_addr, - const unsigned long old_byte_size); +typedef void (*mpool_log_func_t)(const void *mp_p, + const int func_id, + const unsigned long byte_size, + const unsigned long ele_n, + const void *old_addr, const void *new_addr, + const unsigned long old_byte_size); #ifdef MPOOL_MAIN @@ -147,7 +147,7 @@ typedef void (*mpool_log_func_t)(const void *mp_p, #else /* generic mpool type */ -typedef void mpool_t; +typedef void mpool_t; #endif @@ -181,9 +181,8 @@ typedef void mpool_t; * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -extern -mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, - void *start_addr, int *error_p); +KS_DECLARE(mpool_t *) mpool_open(const unsigned int flags, const unsigned int page_size, + void *start_addr, int *error_p); /* * int mpool_close @@ -203,8 +202,7 @@ mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, * * mp_p <-> Pointer to our memory pool. */ -extern -int mpool_close(mpool_t *mp_p); +KS_DECLARE(int) mpool_close(mpool_t *mp_p); /* * int mpool_clear @@ -223,8 +221,7 @@ int mpool_close(mpool_t *mp_p); * * mp_p <-> Pointer to our memory pool. */ -extern -int mpool_clear(mpool_t *mp_p); +KS_DECLARE(int) mpool_clear(mpool_t *mp_p); /* * void *mpool_alloc @@ -249,9 +246,8 @@ int mpool_clear(mpool_t *mp_p); * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -extern -void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, - int *error_p); +KS_DECLARE(void *) mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, + int *error_p); /* * void *mpool_calloc @@ -279,9 +275,8 @@ void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -extern -void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, - const unsigned long ele_size, int *error_p); +KS_DECLARE(void *)mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, + const unsigned long ele_size, int *error_p); /* * int mpool_free @@ -305,8 +300,8 @@ void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, * * size -> Size of the address being freed. */ -extern -int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size); + +KS_DECLARE(int) mpool_free(mpool_t *mp_p, void *addr, const unsigned long size); /* * void *mpool_resize @@ -339,11 +334,10 @@ int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size); * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -extern -void *mpool_resize(mpool_t *mp_p, void *old_addr, - const unsigned long old_byte_size, - const unsigned long new_byte_size, - int *error_p); +KS_DECLARE(void *) mpool_resize(mpool_t *mp_p, void *old_addr, + const unsigned long old_byte_size, + const unsigned long new_byte_size, + int *error_p); /* * int mpool_stats @@ -379,12 +373,11 @@ void *mpool_resize(mpool_t *mp_p, void *old_addr, * will be set to the total amount of space (including administrative * overhead) used by the pool. */ -extern -int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, - unsigned long *num_alloced_p, - unsigned long *user_alloced_p, - unsigned long *max_alloced_p, - unsigned long *tot_alloced_p); +KS_DECLARE(int) mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, + unsigned long *num_alloced_p, + unsigned long *user_alloced_p, + unsigned long *max_alloced_p, + unsigned long *tot_alloced_p); /* * int mpool_set_log_func @@ -407,8 +400,7 @@ int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, * log_func -> Log function (defined in mpool.h) which will be called * with each mpool transaction. */ -extern -int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func); +KS_DECLARE(int) mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func); /* * int mpool_set_max_pages @@ -435,8 +427,7 @@ int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func); * * max_pages -> Maximum number of pages used by the library. */ -extern -int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages); +KS_DECLARE(int) mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages); /* * const char *mpool_strerror @@ -455,9 +446,19 @@ int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages); * * error -> Error number that we are converting. */ -extern -const char *mpool_strerror(const int error); +KS_DECLARE(const char *) mpool_strerror(const int error); /*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ #endif /* ! __MPOOL_H__ */ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/include/mpool_loc.h b/libs/libks/src/include/mpool_loc.h index 3d33f5d927..a3fdbda3db 100644 --- a/libs/libks/src/include/mpool_loc.h +++ b/libs/libks/src/include/mpool_loc.h @@ -43,12 +43,12 @@ #define BIT_IS_SET(v,f) ((v) & (f)) #define BIT_TOGGLE(v,f) (v) ^= (f) -#define SET_POINTER(pnt, val) \ - do { \ - if ((pnt) != NULL) { \ - (*(pnt)) = (val); \ - } \ - } while(0) +#define SET_POINTER(pnt, val) \ + do { \ + if ((pnt) != NULL) { \ + (*(pnt)) = (val); \ + } \ + } while(0) #define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */ #define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */ @@ -56,39 +56,40 @@ #define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/ /* How many pages SIZE bytes resides in. We add in the block header. */ -#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \ - (mp_p)->mp_page_size - 1) / \ - (mp_p)->mp_page_size) +#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \ + (mp_p)->mp_page_size - 1) / \ + (mp_p)->mp_page_size) #define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size) #define MAX_BITS 30 /* we only can allocate 1gb chunks */ #define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \ - sizeof(mpool_block_t)) -#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \ - sizeof(mpool_block_t)) -#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \ - ((char *)(block_p) + \ - sizeof(mpool_block_t))) + sizeof(mpool_block_t)) +#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \ + sizeof(mpool_block_t)) +#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \ + ((char *)(block_p) + \ + sizeof(mpool_block_t))) typedef struct { - unsigned int mp_magic; /* magic number for struct */ - unsigned int mp_flags; /* flags for the struct */ - unsigned long mp_alloc_c; /* number of allocations */ - unsigned long mp_user_alloc; /* user bytes allocated */ - unsigned long mp_max_alloc; /* maximum user bytes allocated */ - unsigned int mp_page_c; /* number of pages allocated */ - unsigned int mp_max_pages; /* maximum number of pages to use */ - unsigned int mp_page_size; /* page-size of our system */ - int mp_fd; /* fd for /dev/zero if mmap-ing */ - off_t mp_top; /* top of our allocations in fd */ - mpool_log_func_t mp_log_func; /* log callback function */ - void *mp_addr; /* current address for mmaping */ - void *mp_min_p; /* min address in pool for checks */ - void *mp_bounds_p; /* max address in pool for checks */ - struct mpool_block_st *mp_first_p; /* first memory block we are using */ - struct mpool_block_st *mp_last_p; /* last memory block we are using */ - struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */ - unsigned int mp_magic2; /* upper magic for overwrite sanity */ + unsigned int mp_magic; /* magic number for struct */ + unsigned int mp_flags; /* flags for the struct */ + unsigned int mp_mmflags; /* flags for mmap */ + unsigned long mp_alloc_c; /* number of allocations */ + unsigned long mp_user_alloc; /* user bytes allocated */ + unsigned long mp_max_alloc; /* maximum user bytes allocated */ + unsigned int mp_page_c; /* number of pages allocated */ + unsigned int mp_max_pages; /* maximum number of pages to use */ + unsigned int mp_page_size; /* page-size of our system */ + int mp_fd; /* fd for /dev/zero if mmap-ing */ + off_t mp_top; /* top of our allocations in fd */ + mpool_log_func_t mp_log_func; /* log callback function */ + void *mp_addr; /* current address for mmaping */ + void *mp_min_p; /* min address in pool for checks */ + void *mp_bounds_p; /* max address in pool for checks */ + struct mpool_block_st *mp_first_p; /* first memory block we are using */ + struct mpool_block_st *mp_last_p; /* last memory block we are using */ + struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */ + unsigned int mp_magic2; /* upper magic for overwrite sanity */ } mpool_t; /* for debuggers to be able to interrogate the generic type in the .h file */ @@ -99,18 +100,29 @@ typedef mpool_t mpool_ext_t; * aligned. */ typedef struct mpool_block_st { - unsigned int mb_magic; /* magic number for block header */ - void *mb_bounds_p; /* block boundary location */ - struct mpool_block_st *mb_next_p; /* linked list next pointer */ - unsigned int mb_magic2; /* upper magic for overwrite sanity */ + unsigned int mb_magic; /* magic number for block header */ + void *mb_bounds_p; /* block boundary location */ + struct mpool_block_st *mb_next_p; /* linked list next pointer */ + unsigned int mb_magic2; /* upper magic for overwrite sanity */ } mpool_block_t; /* * Free list structure. */ typedef struct { - void *mf_next_p; /* pointer to the next free address */ - unsigned long mf_size; /* size of the free block */ + void *mf_next_p; /* pointer to the next free address */ + unsigned long mf_size; /* size of the free block */ } mpool_free_t; #endif /* ! __MPOOL_LOC_H__ */ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/include/simclist.h b/libs/libks/src/include/simclist.h index 2ce9d491ad..1b99ad9c43 100755 --- a/libs/libks/src/include/simclist.h +++ b/libs/libks/src/include/simclist.h @@ -40,7 +40,7 @@ extern "C" { #endif -/* Be friend of both C90 and C99 compilers */ + /* Be friend of both C90 and C99 compilers */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* "inline" and "restrict" are keywords */ #else @@ -49,928 +49,928 @@ extern "C" { #endif -/** - * Type representing list hashes. - * - * This is a signed integer value. - */ -typedef int32_t list_hash_t; + /** + * Type representing list hashes. + * + * This is a signed integer value. + */ + typedef int32_t list_hash_t; #ifndef SIMCLIST_NO_DUMPRESTORE -typedef struct { - uint16_t version; /* dump version */ - struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */ - uint32_t list_size; - uint32_t list_numels; - list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */ - uint32_t dumpsize; - int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */ -} list_dump_info_t; + typedef struct { + uint16_t version; /* dump version */ + struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */ + uint32_t list_size; + uint32_t list_numels; + list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */ + uint32_t dumpsize; + int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */ + } list_dump_info_t; #endif -/** - * a comparator of elements. - * - * A comparator of elements is a function that: - * -# receives two references to elements a and b - * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively - * - * It is responsability of the function to handle possible NULL values. - */ -typedef int (*element_comparator)(const void *a, const void *b); + /** + * a comparator of elements. + * + * A comparator of elements is a function that: + * -# receives two references to elements a and b + * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively + * + * It is responsability of the function to handle possible NULL values. + */ + typedef int (*element_comparator)(const void *a, const void *b); -/** - * a seeker of elements. - * - * An element seeker is a function that: - * -# receives a reference to an element el - * -# receives a reference to some indicator data - * -# returns non-0 if the element matches the indicator, 0 otherwise - * - * It is responsability of the function to handle possible NULL values in any - * argument. - */ -typedef int (*element_seeker)(const void *el, const void *indicator); + /** + * a seeker of elements. + * + * An element seeker is a function that: + * -# receives a reference to an element el + * -# receives a reference to some indicator data + * -# returns non-0 if the element matches the indicator, 0 otherwise + * + * It is responsability of the function to handle possible NULL values in any + * argument. + */ + typedef int (*element_seeker)(const void *el, const void *indicator); -/** - * an element lenght meter. - * - * An element meter is a function that: - * -# receives the reference to an element el - * -# returns its size in bytes - * - * It is responsability of the function to handle possible NULL values. - */ -typedef size_t (*element_meter)(const void *el); + /** + * an element lenght meter. + * + * An element meter is a function that: + * -# receives the reference to an element el + * -# returns its size in bytes + * + * It is responsability of the function to handle possible NULL values. + */ + typedef size_t (*element_meter)(const void *el); -/** - * a function computing the hash of elements. - * - * An hash computing function is a function that: - * -# receives the reference to an element el - * -# returns a hash value for el - * - * It is responsability of the function to handle possible NULL values. - */ -typedef list_hash_t (*element_hash_computer)(const void *el); + /** + * a function computing the hash of elements. + * + * An hash computing function is a function that: + * -# receives the reference to an element el + * -# returns a hash value for el + * + * It is responsability of the function to handle possible NULL values. + */ + typedef list_hash_t (*element_hash_computer)(const void *el); -/** - * a function for serializing an element. - * - * A serializer function is one that gets a reference to an element, - * and returns a reference to a buffer that contains its serialization - * along with the length of this buffer. - * It is responsability of the function to handle possible NULL values, - * returning a NULL buffer and a 0 buffer length. - * - * These functions have 3 goals: - * -# "freeze" and "flatten" the memory representation of the element - * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations - * -# possibly extract a compressed representation of the element - * - * @param el reference to the element data - * @param serialize_buffer reference to fill with the length of the buffer - * @return reference to the buffer with the serialized data - */ -typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len); + /** + * a function for serializing an element. + * + * A serializer function is one that gets a reference to an element, + * and returns a reference to a buffer that contains its serialization + * along with the length of this buffer. + * It is responsability of the function to handle possible NULL values, + * returning a NULL buffer and a 0 buffer length. + * + * These functions have 3 goals: + * -# "freeze" and "flatten" the memory representation of the element + * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations + * -# possibly extract a compressed representation of the element + * + * @param el reference to the element data + * @param serialize_buffer reference to fill with the length of the buffer + * @return reference to the buffer with the serialized data + */ + typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len); -/** - * a function for un-serializing an element. - * - * An unserializer function accomplishes the inverse operation of the - * serializer function. An unserializer function is one that gets a - * serialized representation of an element and turns it backe to the original - * element. The serialized representation is passed as a reference to a buffer - * with its data, and the function allocates and returns the buffer containing - * the original element, and it sets the length of this buffer into the - * integer passed by reference. - * - * @param data reference to the buffer with the serialized representation of the element - * @param data_len reference to the location where to store the length of the data in the buffer returned - * @return reference to a buffer with the original, unserialized representation of the element - */ -typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len); + /** + * a function for un-serializing an element. + * + * An unserializer function accomplishes the inverse operation of the + * serializer function. An unserializer function is one that gets a + * serialized representation of an element and turns it backe to the original + * element. The serialized representation is passed as a reference to a buffer + * with its data, and the function allocates and returns the buffer containing + * the original element, and it sets the length of this buffer into the + * integer passed by reference. + * + * @param data reference to the buffer with the serialized representation of the element + * @param data_len reference to the location where to store the length of the data in the buffer returned + * @return reference to a buffer with the original, unserialized representation of the element + */ + typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len); -/* [private-use] list entry -- olds actual user datum */ -struct list_entry_s { - void *data; + /* [private-use] list entry -- olds actual user datum */ + struct list_entry_s { + void *data; - /* doubly-linked list service references */ - struct list_entry_s *next; - struct list_entry_s *prev; -}; + /* doubly-linked list service references */ + struct list_entry_s *next; + struct list_entry_s *prev; + }; -/* [private-use] list attributes */ -struct list_attributes_s { - /* user-set routine for comparing list elements */ - element_comparator comparator; - /* user-set routing for seeking elements */ - element_seeker seeker; - /* user-set routine for determining the length of an element */ - element_meter meter; - int copy_data; - /* user-set routine for computing the hash of an element */ - element_hash_computer hasher; - /* user-set routine for serializing an element */ - element_serializer serializer; - /* user-set routine for unserializing an element */ - element_unserializer unserializer; -}; + /* [private-use] list attributes */ + struct list_attributes_s { + /* user-set routine for comparing list elements */ + element_comparator comparator; + /* user-set routing for seeking elements */ + element_seeker seeker; + /* user-set routine for determining the length of an element */ + element_meter meter; + int copy_data; + /* user-set routine for computing the hash of an element */ + element_hash_computer hasher; + /* user-set routine for serializing an element */ + element_serializer serializer; + /* user-set routine for unserializing an element */ + element_unserializer unserializer; + }; -/** list object */ -typedef struct { - struct list_entry_s *head_sentinel; - struct list_entry_s *tail_sentinel; - struct list_entry_s *mid; + /** list object */ + typedef struct { + struct list_entry_s *head_sentinel; + struct list_entry_s *tail_sentinel; + struct list_entry_s *mid; - unsigned int numels; + unsigned int numels; - /* array of spare elements */ - struct list_entry_s **spareels; - unsigned int spareelsnum; + /* array of spare elements */ + struct list_entry_s **spareels; + unsigned int spareelsnum; #ifdef SIMCLIST_WITH_THREADS - /* how many threads are currently running */ - unsigned int threadcount; + /* how many threads are currently running */ + unsigned int threadcount; #endif - /* service variables for list iteration */ - int iter_active; - unsigned int iter_pos; - struct list_entry_s *iter_curentry; + /* service variables for list iteration */ + int iter_active; + unsigned int iter_pos; + struct list_entry_s *iter_curentry; - /* list attributes */ - struct list_attributes_s attrs; -} list_t; + /* list attributes */ + struct list_attributes_s attrs; + } list_t; -/** - * initialize a list object for use. - * - * @param l must point to a user-provided memory location - * @return 0 for success. -1 for failure - */ -int list_init(list_t *restrict l); + /** + * initialize a list object for use. + * + * @param l must point to a user-provided memory location + * @return 0 for success. -1 for failure + */ + int list_init(list_t *restrict l); -/** - * completely remove the list from memory. - * - * This function is the inverse of list_init(). It is meant to be called when - * the list is no longer going to be used. Elements and possible memory taken - * for internal use are freed. - * - * @param l list to destroy - */ -void list_destroy(list_t *restrict l); + /** + * completely remove the list from memory. + * + * This function is the inverse of list_init(). It is meant to be called when + * the list is no longer going to be used. Elements and possible memory taken + * for internal use are freed. + * + * @param l list to destroy + */ + void list_destroy(list_t *restrict l); -/** - * set the comparator function for list elements. - * - * Comparator functions are used for searching and sorting. If NULL is passed - * as reference to the function, the comparator is disabled. - * - * @param l list to operate - * @param comparator_fun pointer to the actual comparator function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_comparator() - */ -int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); + /** + * set the comparator function for list elements. + * + * Comparator functions are used for searching and sorting. If NULL is passed + * as reference to the function, the comparator is disabled. + * + * @param l list to operate + * @param comparator_fun pointer to the actual comparator function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_comparator() + */ + int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); -/** - * set a seeker function for list elements. - * - * Seeker functions are used for finding elements. If NULL is passed as reference - * to the function, the seeker is disabled. - * - * @param l list to operate - * @param seeker_fun pointer to the actual seeker function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_seeker() - */ -int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); + /** + * set a seeker function for list elements. + * + * Seeker functions are used for finding elements. If NULL is passed as reference + * to the function, the seeker is disabled. + * + * @param l list to operate + * @param seeker_fun pointer to the actual seeker function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_seeker() + */ + int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); -/** - * require to free element data when list entry is removed (default: don't free). - * - * [ advanced preference ] - * - * By default, when an element is removed from the list, it disappears from - * the list by its actual data is not free()d. With this option, every - * deletion causes element data to be freed. - * - * It is responsability of this function to correctly handle NULL values, if - * NULL elements are inserted into the list. - * - * @param l list to operate - * @param metric_fun pointer to the actual metric function - * @param copy_data 0: do not free element data (default); non-0: do free - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_meter() - * @see list_meter_int8_t() - * @see list_meter_int16_t() - * @see list_meter_int32_t() - * @see list_meter_int64_t() - * @see list_meter_uint8_t() - * @see list_meter_uint16_t() - * @see list_meter_uint32_t() - * @see list_meter_uint64_t() - * @see list_meter_float() - * @see list_meter_double() - * @see list_meter_string() - */ -int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); + /** + * require to free element data when list entry is removed (default: don't free). + * + * [ advanced preference ] + * + * By default, when an element is removed from the list, it disappears from + * the list by its actual data is not free()d. With this option, every + * deletion causes element data to be freed. + * + * It is responsability of this function to correctly handle NULL values, if + * NULL elements are inserted into the list. + * + * @param l list to operate + * @param metric_fun pointer to the actual metric function + * @param copy_data 0: do not free element data (default); non-0: do free + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_meter() + * @see list_meter_int8_t() + * @see list_meter_int16_t() + * @see list_meter_int32_t() + * @see list_meter_int64_t() + * @see list_meter_uint8_t() + * @see list_meter_uint16_t() + * @see list_meter_uint32_t() + * @see list_meter_uint64_t() + * @see list_meter_float() + * @see list_meter_double() + * @see list_meter_string() + */ + int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); -/** - * set the element hash computing function for the list elements. - * - * [ advanced preference ] - * - * An hash can be requested depicting the list status at a given time. An hash - * only depends on the elements and their order. By default, the hash of an - * element is only computed on its reference. With this function, the user can - * set a custom function computing the hash of an element. If such function is - * provided, the list_hash() function automatically computes the list hash using - * the custom function instead of simply referring to element references. - * - * @param l list to operate - * @param hash_computer_fun pointer to the actual hash computing function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_hash_computer() - */ -int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); + /** + * set the element hash computing function for the list elements. + * + * [ advanced preference ] + * + * An hash can be requested depicting the list status at a given time. An hash + * only depends on the elements and their order. By default, the hash of an + * element is only computed on its reference. With this function, the user can + * set a custom function computing the hash of an element. If such function is + * provided, the list_hash() function automatically computes the list hash using + * the custom function instead of simply referring to element references. + * + * @param l list to operate + * @param hash_computer_fun pointer to the actual hash computing function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_hash_computer() + */ + int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); -/** - * set the element serializer function for the list elements. - * - * [ advanced preference ] - * - * Serialize functions are used for dumping the list to some persistent - * storage. The serializer function is called for each element; it is passed - * a reference to the element and a reference to a size_t object. It will - * provide (and return) the buffer with the serialization of the element and - * fill the size_t object with the length of this serialization data. - * - * @param l list to operate - * @param serializer_fun pointer to the actual serializer function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_serializer() - * @see list_dump_filedescriptor() - * @see list_restore_filedescriptor() - */ -int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); + /** + * set the element serializer function for the list elements. + * + * [ advanced preference ] + * + * Serialize functions are used for dumping the list to some persistent + * storage. The serializer function is called for each element; it is passed + * a reference to the element and a reference to a size_t object. It will + * provide (and return) the buffer with the serialization of the element and + * fill the size_t object with the length of this serialization data. + * + * @param l list to operate + * @param serializer_fun pointer to the actual serializer function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_serializer() + * @see list_dump_filedescriptor() + * @see list_restore_filedescriptor() + */ + int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); -/** - * set the element unserializer function for the list elements. - * - * [ advanced preference ] - * - * Unserialize functions are used for restoring the list from some persistent - * storage. The unserializer function is called for each element segment read - * from the storage; it is passed the segment and a reference to an integer. - * It shall allocate and return a buffer compiled with the resumed memory - * representation of the element, and set the integer value to the length of - * this buffer. - * - * @param l list to operate - * @param unserializer_fun pointer to the actual unserializer function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_unserializer() - * @see list_dump_filedescriptor() - * @see list_restore_filedescriptor() - */ -int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); + /** + * set the element unserializer function for the list elements. + * + * [ advanced preference ] + * + * Unserialize functions are used for restoring the list from some persistent + * storage. The unserializer function is called for each element segment read + * from the storage; it is passed the segment and a reference to an integer. + * It shall allocate and return a buffer compiled with the resumed memory + * representation of the element, and set the integer value to the length of + * this buffer. + * + * @param l list to operate + * @param unserializer_fun pointer to the actual unserializer function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_unserializer() + * @see list_dump_filedescriptor() + * @see list_restore_filedescriptor() + */ + int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); -/** - * append data at the end of the list. - * - * This function is useful for adding elements with a FIFO/queue policy. - * - * @param l list to operate - * @param data pointer to user data to append - * - * @return 1 for success. < 0 for failure - */ -int list_append(list_t *restrict l, const void *data); + /** + * append data at the end of the list. + * + * This function is useful for adding elements with a FIFO/queue policy. + * + * @param l list to operate + * @param data pointer to user data to append + * + * @return 1 for success. < 0 for failure + */ + int list_append(list_t *restrict l, const void *data); -/** - * insert data in the head of the list. - * - * This function is useful for adding elements with a LIFO/Stack policy. - * - * @param l list to operate - * @param data pointer to user data to append - * - * @return 1 for success. < 0 for failure - */ -int list_prepend(list_t *restrict l, const void *restrict data); + /** + * insert data in the head of the list. + * + * This function is useful for adding elements with a LIFO/Stack policy. + * + * @param l list to operate + * @param data pointer to user data to append + * + * @return 1 for success. < 0 for failure + */ + int list_prepend(list_t *restrict l, const void *restrict data); -/** - * extract the element in the top of the list. - * - * This function is for using a list with a FIFO/queue policy. - * - * @param l list to operate - * @return reference to user datum, or NULL on errors - */ -void *list_fetch(list_t *restrict l); + /** + * extract the element in the top of the list. + * + * This function is for using a list with a FIFO/queue policy. + * + * @param l list to operate + * @return reference to user datum, or NULL on errors + */ + void *list_fetch(list_t *restrict l); -/** - * retrieve an element at a given position. - * - * @param l list to operate - * @param pos [0,size-1] position index of the element wanted - * @return reference to user datum, or NULL on errors - */ -void *list_get_at(const list_t *restrict l, unsigned int pos); + /** + * retrieve an element at a given position. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element wanted + * @return reference to user datum, or NULL on errors + */ + void *list_get_at(const list_t *restrict l, unsigned int pos); -/** - * return the maximum element of the list. - * - * @warning Requires a comparator function to be set for the list. - * - * Returns the maximum element with respect to the comparator function output. - * - * @see list_attributes_comparator() - * - * @param l list to operate - * @return the reference to the element, or NULL - */ -void *list_get_max(const list_t *restrict l); + /** + * return the maximum element of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * Returns the maximum element with respect to the comparator function output. + * + * @see list_attributes_comparator() + * + * @param l list to operate + * @return the reference to the element, or NULL + */ + void *list_get_max(const list_t *restrict l); -/** - * return the minimum element of the list. - * - * @warning Requires a comparator function to be set for the list. - * - * Returns the minimum element with respect to the comparator function output. - * - * @see list_attributes_comparator() - * - * @param l list to operate - * @return the reference to the element, or NULL - */ -void *list_get_min(const list_t *restrict l); + /** + * return the minimum element of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * Returns the minimum element with respect to the comparator function output. + * + * @see list_attributes_comparator() + * + * @param l list to operate + * @return the reference to the element, or NULL + */ + void *list_get_min(const list_t *restrict l); -/** - * retrieve and remove from list an element at a given position. - * - * @param l list to operate - * @param pos [0,size-1] position index of the element wanted - * @return reference to user datum, or NULL on errors - */ -void *list_extract_at(list_t *restrict l, unsigned int pos); + /** + * retrieve and remove from list an element at a given position. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element wanted + * @return reference to user datum, or NULL on errors + */ + void *list_extract_at(list_t *restrict l, unsigned int pos); -/** - * insert an element at a given position. - * - * @param l list to operate - * @param data reference to data to be inserted - * @param pos [0,size-1] position index to insert the element at - * @return positive value on success. Negative on failure - */ -int list_insert_at(list_t *restrict l, const void *data, unsigned int pos); + /** + * insert an element at a given position. + * + * @param l list to operate + * @param data reference to data to be inserted + * @param pos [0,size-1] position index to insert the element at + * @return positive value on success. Negative on failure + */ + int list_insert_at(list_t *restrict l, const void *data, unsigned int pos); -/** - * expunge the first found given element from the list. - * - * Inspects the given list looking for the given element; if the element - * is found, it is removed. Only the first occurence is removed. - * If a comparator function was not set, elements are compared by reference. - * Otherwise, the comparator is used to match the element. - * - * @param l list to operate - * @param data reference of the element to search for - * @return 0 on success. Negative value on failure - * - * @see list_attributes_comparator() - * @see list_delete_at() - */ -int list_delete(list_t *restrict l, const void *data); + /** + * expunge the first found given element from the list. + * + * Inspects the given list looking for the given element; if the element + * is found, it is removed. Only the first occurence is removed. + * If a comparator function was not set, elements are compared by reference. + * Otherwise, the comparator is used to match the element. + * + * @param l list to operate + * @param data reference of the element to search for + * @return 0 on success. Negative value on failure + * + * @see list_attributes_comparator() + * @see list_delete_at() + */ + int list_delete(list_t *restrict l, const void *data); -/** - * expunge an element at a given position from the list. - * - * @param l list to operate - * @param pos [0,size-1] position index of the element to be deleted - * @return 0 on success. Negative value on failure - */ -int list_delete_at(list_t *restrict l, unsigned int pos); + /** + * expunge an element at a given position from the list. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element to be deleted + * @return 0 on success. Negative value on failure + */ + int list_delete_at(list_t *restrict l, unsigned int pos); -/** - * expunge an array of elements from the list, given their position range. - * - * @param l list to operate - * @param posstart [0,size-1] position index of the first element to be deleted - * @param posend [posstart,size-1] position of the last element to be deleted - * @return the number of elements successfully removed on success, <0 on error - */ -int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); + /** + * expunge an array of elements from the list, given their position range. + * + * @param l list to operate + * @param posstart [0,size-1] position index of the first element to be deleted + * @param posend [posstart,size-1] position of the last element to be deleted + * @return the number of elements successfully removed on success, <0 on error + */ + int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); -/** - * clear all the elements off of the list. - * - * The element datums will not be freed. - * - * @see list_delete_range() - * @see list_size() - * - * @param l list to operate - * @return the number of elements removed on success, <0 on error - */ -int list_clear(list_t *restrict l); + /** + * clear all the elements off of the list. + * + * The element datums will not be freed. + * + * @see list_delete_range() + * @see list_size() + * + * @param l list to operate + * @return the number of elements removed on success, <0 on error + */ + int list_clear(list_t *restrict l); -/** - * inspect the number of elements in the list. - * - * @param l list to operate - * @return number of elements currently held by the list - */ -unsigned int list_size(const list_t *restrict l); + /** + * inspect the number of elements in the list. + * + * @param l list to operate + * @return number of elements currently held by the list + */ + unsigned int list_size(const list_t *restrict l); -/** - * inspect whether the list is empty. - * - * @param l list to operate - * @return 0 iff the list is not empty - * - * @see list_size() - */ -int list_empty(const list_t *restrict l); + /** + * inspect whether the list is empty. + * + * @param l list to operate + * @return 0 iff the list is not empty + * + * @see list_size() + */ + int list_empty(const list_t *restrict l); -/** - * find the position of an element in a list. - * - * @warning Requires a comparator function to be set for the list. - * - * Inspects the given list looking for the given element; if the element - * is found, its position into the list is returned. - * Elements are inspected comparing references if a comparator has not been - * set. Otherwise, the comparator is used to find the element. - * - * @param l list to operate - * @param data reference of the element to search for - * @return position of element in the list, or <0 if not found - * - * @see list_attributes_comparator() - * @see list_get_at() - */ -int list_locate(const list_t *restrict l, const void *data); + /** + * find the position of an element in a list. + * + * @warning Requires a comparator function to be set for the list. + * + * Inspects the given list looking for the given element; if the element + * is found, its position into the list is returned. + * Elements are inspected comparing references if a comparator has not been + * set. Otherwise, the comparator is used to find the element. + * + * @param l list to operate + * @param data reference of the element to search for + * @return position of element in the list, or <0 if not found + * + * @see list_attributes_comparator() + * @see list_get_at() + */ + int list_locate(const list_t *restrict l, const void *data); -/** - * returns an element given an indicator. - * - * @warning Requires a seeker function to be set for the list. - * - * Inspect the given list looking with the seeker if an element matches - * an indicator. If such element is found, the reference to the element - * is returned. - * - * @param l list to operate - * @param indicator indicator data to pass to the seeker along with elements - * @return reference to the element accepted by the seeker, or NULL if none found - */ -void *list_seek(list_t *restrict l, const void *indicator); + /** + * returns an element given an indicator. + * + * @warning Requires a seeker function to be set for the list. + * + * Inspect the given list looking with the seeker if an element matches + * an indicator. If such element is found, the reference to the element + * is returned. + * + * @param l list to operate + * @param indicator indicator data to pass to the seeker along with elements + * @return reference to the element accepted by the seeker, or NULL if none found + */ + void *list_seek(list_t *restrict l, const void *indicator); -/** - * inspect whether some data is member of the list. - * - * @warning Requires a comparator function to be set for the list. - * - * By default, a per-reference comparison is accomplished. That is, - * the data is in list if any element of the list points to the same - * location of data. - * A "semantic" comparison is accomplished, otherwise, if a comparator - * function has been set previously, with list_attributes_comparator(); - * in which case, the given data reference is believed to be in list iff - * comparator_fun(elementdata, userdata) == 0 for any element in the list. - * - * @param l list to operate - * @param data reference to the data to search - * @return 0 iff the list does not contain data as an element - * - * @see list_attributes_comparator() - */ -int list_contains(const list_t *restrict l, const void *data); + /** + * inspect whether some data is member of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * By default, a per-reference comparison is accomplished. That is, + * the data is in list if any element of the list points to the same + * location of data. + * A "semantic" comparison is accomplished, otherwise, if a comparator + * function has been set previously, with list_attributes_comparator(); + * in which case, the given data reference is believed to be in list iff + * comparator_fun(elementdata, userdata) == 0 for any element in the list. + * + * @param l list to operate + * @param data reference to the data to search + * @return 0 iff the list does not contain data as an element + * + * @see list_attributes_comparator() + */ + int list_contains(const list_t *restrict l, const void *data); -/** - * concatenate two lists - * - * Concatenates one list with another, and stores the result into a - * user-provided list object, which must be different from both the - * lists to concatenate. Attributes from the original lists are not - * cloned. - * The destination list referred is threated as virgin room: if it - * is an existing list containing elements, memory leaks will happen. - * It is OK to specify the same list twice as source, for "doubling" - * it in the destination. - * - * @param l1 base list - * @param l2 list to append to the base - * @param dest reference to the destination list - * @return 0 for success, -1 for errors - */ -int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); + /** + * concatenate two lists + * + * Concatenates one list with another, and stores the result into a + * user-provided list object, which must be different from both the + * lists to concatenate. Attributes from the original lists are not + * cloned. + * The destination list referred is threated as virgin room: if it + * is an existing list containing elements, memory leaks will happen. + * It is OK to specify the same list twice as source, for "doubling" + * it in the destination. + * + * @param l1 base list + * @param l2 list to append to the base + * @param dest reference to the destination list + * @return 0 for success, -1 for errors + */ + int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); -/** - * sort list elements. - * - * @warning Requires a comparator function to be set for the list. - * - * Sorts the list in ascending or descending order as specified by the versus - * flag. The algorithm chooses autonomously what algorithm is best suited for - * sorting the list wrt its current status. - * - * @param l list to operate - * @param versus positive: order small to big; negative: order big to small - * @return 0 iff sorting was successful - * - * @see list_attributes_comparator() - */ -int list_sort(list_t *restrict l, int versus); + /** + * sort list elements. + * + * @warning Requires a comparator function to be set for the list. + * + * Sorts the list in ascending or descending order as specified by the versus + * flag. The algorithm chooses autonomously what algorithm is best suited for + * sorting the list wrt its current status. + * + * @param l list to operate + * @param versus positive: order small to big; negative: order big to small + * @return 0 iff sorting was successful + * + * @see list_attributes_comparator() + */ + int list_sort(list_t *restrict l, int versus); -/** - * start an iteration session. - * - * This function prepares the list to be iterated. - * - * @param l list to operate - * @return 0 if the list cannot be currently iterated. >0 otherwise - * - * @see list_iterator_stop() - */ -int list_iterator_start(list_t *restrict l); + /** + * start an iteration session. + * + * This function prepares the list to be iterated. + * + * @param l list to operate + * @return 0 if the list cannot be currently iterated. >0 otherwise + * + * @see list_iterator_stop() + */ + int list_iterator_start(list_t *restrict l); -/** - * return the next element in the iteration session. - * - * @param l list to operate - * @return element datum, or NULL on errors - */ -void *list_iterator_next(list_t *restrict l); + /** + * return the next element in the iteration session. + * + * @param l list to operate + * @return element datum, or NULL on errors + */ + void *list_iterator_next(list_t *restrict l); -/** - * inspect whether more elements are available in the iteration session. - * - * @param l list to operate - * @return 0 iff no more elements are available. - */ -int list_iterator_hasnext(const list_t *restrict l); + /** + * inspect whether more elements are available in the iteration session. + * + * @param l list to operate + * @return 0 iff no more elements are available. + */ + int list_iterator_hasnext(const list_t *restrict l); -/** - * end an iteration session. - * - * @param l list to operate - * @return 0 iff the iteration session cannot be stopped - */ -int list_iterator_stop(list_t *restrict l); + /** + * end an iteration session. + * + * @param l list to operate + * @return 0 iff the iteration session cannot be stopped + */ + int list_iterator_stop(list_t *restrict l); -/** - * return the hash of the current status of the list. - * - * @param l list to operate - * @param hash where the resulting hash is put - * - * @return 0 for success; <0 for failure - */ -int list_hash(const list_t *restrict l, list_hash_t *restrict hash); + /** + * return the hash of the current status of the list. + * + * @param l list to operate + * @param hash where the resulting hash is put + * + * @return 0 for success; <0 for failure + */ + int list_hash(const list_t *restrict l, list_hash_t *restrict hash); #ifndef SIMCLIST_NO_DUMPRESTORE -/** - * get meta informations on a list dump on filedescriptor. - * - * [ advanced function ] - * - * Extracts the meta information from a SimCList dump located in a file - * descriptor. The file descriptor must be open and positioned at the - * beginning of the SimCList dump block. - * - * @param fd file descriptor to get metadata from - * @param info reference to a dump metainformation structure to fill - * @return 0 for success; <0 for failure - * - * @see list_dump_filedescriptor() - */ -int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); + /** + * get meta informations on a list dump on filedescriptor. + * + * [ advanced function ] + * + * Extracts the meta information from a SimCList dump located in a file + * descriptor. The file descriptor must be open and positioned at the + * beginning of the SimCList dump block. + * + * @param fd file descriptor to get metadata from + * @param info reference to a dump metainformation structure to fill + * @return 0 for success; <0 for failure + * + * @see list_dump_filedescriptor() + */ + int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); -/** - * get meta informations on a list dump on file. - * - * [ advanced function ] - * - * Extracts the meta information from a SimCList dump located in a file. - * - * @param filename filename of the file to fetch from - * @param info reference to a dump metainformation structure to fill - * @return 0 for success; <0 for failure - * - * @see list_dump_filedescriptor() - */ -int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); + /** + * get meta informations on a list dump on file. + * + * [ advanced function ] + * + * Extracts the meta information from a SimCList dump located in a file. + * + * @param filename filename of the file to fetch from + * @param info reference to a dump metainformation structure to fill + * @return 0 for success; <0 for failure + * + * @see list_dump_filedescriptor() + */ + int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); -/** - * dump the list into an open, writable file descriptor. - * - * This function "dumps" the list to a persistent storage so it can be - * preserved across process terminations. - * When called, the file descriptor must be open for writing and positioned - * where the serialized data must begin. It writes its serialization of the - * list in a form which is portable across different architectures. Dump can - * be safely performed on stream-only (non seekable) descriptors. The file - * descriptor is not closed at the end of the operations. - * - * To use dump functions, either of these conditions must be satisfied: - * -# a metric function has been specified with list_attributes_copy() - * -# a serializer function has been specified with list_attributes_serializer() - * - * If a metric function has been specified, each element of the list is dumped - * as-is from memory, copying it from its pointer for its length down to the - * file descriptor. This might have impacts on portability of the dump to - * different architectures. - * - * If a serializer function has been specified, its result for each element is - * dumped to the file descriptor. - * - * - * @param l list to operate - * @param fd file descriptor to write to - * @param len location to store the resulting length of the dump (bytes), or NULL - * - * @return 0 if successful; -1 otherwise - * - * @see element_serializer() - * @see list_attributes_copy() - * @see list_attributes_serializer() - */ -int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); + /** + * dump the list into an open, writable file descriptor. + * + * This function "dumps" the list to a persistent storage so it can be + * preserved across process terminations. + * When called, the file descriptor must be open for writing and positioned + * where the serialized data must begin. It writes its serialization of the + * list in a form which is portable across different architectures. Dump can + * be safely performed on stream-only (non seekable) descriptors. The file + * descriptor is not closed at the end of the operations. + * + * To use dump functions, either of these conditions must be satisfied: + * -# a metric function has been specified with list_attributes_copy() + * -# a serializer function has been specified with list_attributes_serializer() + * + * If a metric function has been specified, each element of the list is dumped + * as-is from memory, copying it from its pointer for its length down to the + * file descriptor. This might have impacts on portability of the dump to + * different architectures. + * + * If a serializer function has been specified, its result for each element is + * dumped to the file descriptor. + * + * + * @param l list to operate + * @param fd file descriptor to write to + * @param len location to store the resulting length of the dump (bytes), or NULL + * + * @return 0 if successful; -1 otherwise + * + * @see element_serializer() + * @see list_attributes_copy() + * @see list_attributes_serializer() + */ + int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); -/** - * dump the list to a file name. - * - * This function creates a filename and dumps the current content of the list - * to it. If the file exists it is overwritten. The number of bytes written to - * the file can be returned in a specified argument. - * - * @param l list to operate - * @param filename filename to write to - * @param len location to store the resulting length of the dump (bytes), or NULL - * - * @return 0 if successful; -1 otherwise - * - * @see list_attributes_copy() - * @see element_serializer() - * @see list_attributes_serializer() - * @see list_dump_filedescriptor() - * @see list_restore_file() - * - * This function stores a representation of the list - */ -int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); + /** + * dump the list to a file name. + * + * This function creates a filename and dumps the current content of the list + * to it. If the file exists it is overwritten. The number of bytes written to + * the file can be returned in a specified argument. + * + * @param l list to operate + * @param filename filename to write to + * @param len location to store the resulting length of the dump (bytes), or NULL + * + * @return 0 if successful; -1 otherwise + * + * @see list_attributes_copy() + * @see element_serializer() + * @see list_attributes_serializer() + * @see list_dump_filedescriptor() + * @see list_restore_file() + * + * This function stores a representation of the list + */ + int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); -/** - * restore the list from an open, readable file descriptor to memory. - * - * This function is the "inverse" of list_dump_filedescriptor(). It restores - * the list content from a (open, read-ready) file descriptor to memory. An - * unserializer might be needed to restore elements from the persistent - * representation back into memory-consistent format. List attributes can not - * be restored and must be set manually. - * - * @see list_dump_filedescriptor() - * @see list_attributes_serializer() - * @see list_attributes_unserializer() - * - * @param l list to restore to - * @param fd file descriptor to read from. - * @param len location to store the length of the dump read (bytes), or NULL - * @return 0 if successful; -1 otherwise - */ -int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); + /** + * restore the list from an open, readable file descriptor to memory. + * + * This function is the "inverse" of list_dump_filedescriptor(). It restores + * the list content from a (open, read-ready) file descriptor to memory. An + * unserializer might be needed to restore elements from the persistent + * representation back into memory-consistent format. List attributes can not + * be restored and must be set manually. + * + * @see list_dump_filedescriptor() + * @see list_attributes_serializer() + * @see list_attributes_unserializer() + * + * @param l list to restore to + * @param fd file descriptor to read from. + * @param len location to store the length of the dump read (bytes), or NULL + * @return 0 if successful; -1 otherwise + */ + int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); -/** - * restore the list from a file name. - * - * This function restores the content of a list from a file into memory. It is - * the inverse of list_dump_file(). - * - * @see element_unserializer() - * @see list_attributes_unserializer() - * @see list_dump_file() - * @see list_restore_filedescriptor() - * - * @param l list to restore to - * @param filename filename to read data from - * @param len location to store the length of the dump read (bytes), or NULL - * @return 0 if successful; -1 otherwise - */ -int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); + /** + * restore the list from a file name. + * + * This function restores the content of a list from a file into memory. It is + * the inverse of list_dump_file(). + * + * @see element_unserializer() + * @see list_attributes_unserializer() + * @see list_dump_file() + * @see list_restore_filedescriptor() + * + * @param l list to restore to + * @param filename filename to read data from + * @param len location to store the length of the dump read (bytes), or NULL + * @return 0 if successful; -1 otherwise + */ + int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); #endif -/* ready-made comparators, meters and hash computers */ - /* comparator functions */ -/** - * ready-made comparator for int8_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_int8_t(const void *a, const void *b); + /* ready-made comparators, meters and hash computers */ + /* comparator functions */ + /** + * ready-made comparator for int8_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int8_t(const void *a, const void *b); -/** - * ready-made comparator for int16_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_int16_t(const void *a, const void *b); + /** + * ready-made comparator for int16_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int16_t(const void *a, const void *b); -/** - * ready-made comparator for int32_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_int32_t(const void *a, const void *b); + /** + * ready-made comparator for int32_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int32_t(const void *a, const void *b); -/** - * ready-made comparator for int64_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_int64_t(const void *a, const void *b); + /** + * ready-made comparator for int64_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int64_t(const void *a, const void *b); -/** - * ready-made comparator for uint8_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_uint8_t(const void *a, const void *b); + /** + * ready-made comparator for uint8_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint8_t(const void *a, const void *b); -/** - * ready-made comparator for uint16_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_uint16_t(const void *a, const void *b); + /** + * ready-made comparator for uint16_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint16_t(const void *a, const void *b); -/** - * ready-made comparator for uint32_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_uint32_t(const void *a, const void *b); + /** + * ready-made comparator for uint32_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint32_t(const void *a, const void *b); -/** - * ready-made comparator for uint64_t elements. - * @see list_attributes_comparator() - */ -int list_comparator_uint64_t(const void *a, const void *b); + /** + * ready-made comparator for uint64_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint64_t(const void *a, const void *b); -/** - * ready-made comparator for float elements. - * @see list_attributes_comparator() - */ -int list_comparator_float(const void *a, const void *b); + /** + * ready-made comparator for float elements. + * @see list_attributes_comparator() + */ + int list_comparator_float(const void *a, const void *b); -/** - * ready-made comparator for double elements. - * @see list_attributes_comparator() - */ -int list_comparator_double(const void *a, const void *b); + /** + * ready-made comparator for double elements. + * @see list_attributes_comparator() + */ + int list_comparator_double(const void *a, const void *b); -/** - * ready-made comparator for string elements. - * @see list_attributes_comparator() - */ -int list_comparator_string(const void *a, const void *b); + /** + * ready-made comparator for string elements. + * @see list_attributes_comparator() + */ + int list_comparator_string(const void *a, const void *b); - /* metric functions */ -/** - * ready-made metric function for int8_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_int8_t(const void *el); + /* metric functions */ + /** + * ready-made metric function for int8_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int8_t(const void *el); -/** - * ready-made metric function for int16_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_int16_t(const void *el); + /** + * ready-made metric function for int16_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int16_t(const void *el); -/** - * ready-made metric function for int32_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_int32_t(const void *el); + /** + * ready-made metric function for int32_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int32_t(const void *el); -/** - * ready-made metric function for int64_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_int64_t(const void *el); + /** + * ready-made metric function for int64_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int64_t(const void *el); -/** - * ready-made metric function for uint8_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_uint8_t(const void *el); + /** + * ready-made metric function for uint8_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint8_t(const void *el); -/** - * ready-made metric function for uint16_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_uint16_t(const void *el); + /** + * ready-made metric function for uint16_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint16_t(const void *el); -/** - * ready-made metric function for uint32_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_uint32_t(const void *el); + /** + * ready-made metric function for uint32_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint32_t(const void *el); -/** - * ready-made metric function for uint64_t elements. - * @see list_attributes_copy() - */ -size_t list_meter_uint64_t(const void *el); + /** + * ready-made metric function for uint64_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint64_t(const void *el); -/** - * ready-made metric function for float elements. - * @see list_attributes_copy() - */ -size_t list_meter_float(const void *el); + /** + * ready-made metric function for float elements. + * @see list_attributes_copy() + */ + size_t list_meter_float(const void *el); -/** - * ready-made metric function for double elements. - * @see list_attributes_copy() - */ -size_t list_meter_double(const void *el); + /** + * ready-made metric function for double elements. + * @see list_attributes_copy() + */ + size_t list_meter_double(const void *el); -/** - * ready-made metric function for string elements. - * @see list_attributes_copy() - */ -size_t list_meter_string(const void *el); + /** + * ready-made metric function for string elements. + * @see list_attributes_copy() + */ + size_t list_meter_string(const void *el); - /* hash functions */ -/** - * ready-made hash function for int8_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_int8_t(const void *el); + /* hash functions */ + /** + * ready-made hash function for int8_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int8_t(const void *el); -/** - * ready-made hash function for int16_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_int16_t(const void *el); + /** + * ready-made hash function for int16_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int16_t(const void *el); -/** - * ready-made hash function for int32_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_int32_t(const void *el); + /** + * ready-made hash function for int32_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int32_t(const void *el); -/** - * ready-made hash function for int64_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_int64_t(const void *el); + /** + * ready-made hash function for int64_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int64_t(const void *el); -/** - * ready-made hash function for uint8_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_uint8_t(const void *el); + /** + * ready-made hash function for uint8_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint8_t(const void *el); -/** - * ready-made hash function for uint16_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_uint16_t(const void *el); + /** + * ready-made hash function for uint16_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint16_t(const void *el); -/** - * ready-made hash function for uint32_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_uint32_t(const void *el); + /** + * ready-made hash function for uint32_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint32_t(const void *el); -/** - * ready-made hash function for uint64_t elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_uint64_t(const void *el); + /** + * ready-made hash function for uint64_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint64_t(const void *el); -/** - * ready-made hash function for float elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_float(const void *el); + /** + * ready-made hash function for float elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_float(const void *el); -/** - * ready-made hash function for double elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_double(const void *el); + /** + * ready-made hash function for double elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_double(const void *el); -/** - * ready-made hash function for string elements. - * @see list_attributes_hash_computer() - */ -list_hash_t list_hashcomputer_string(const void *el); + /** + * ready-made hash function for string elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_string(const void *el); #ifdef __cplusplus } @@ -978,3 +978,13 @@ list_hash_t list_hashcomputer_string(const void *el); #endif +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/include/table.h b/libs/libks/src/include/table.h index 687358683d..181cacb906 100644 --- a/libs/libks/src/include/table.h +++ b/libs/libks/src/include/table.h @@ -28,19 +28,19 @@ extern "C" { #endif /* __cplusplus */ -/* - * To build a "key" in any of the below routines, pass in a pointer to - * the key and its size [i.e. sizeof(int), etc]. With any of the - * "key" or "data" arguments, if their size is < 0, it will do an - * internal strlen of the item and add 1 for the \0. - * - * If you are using firstkey() and nextkey() functions, be careful if, - * after starting your firstkey loop, you use delete or insert, it - * will not crash but may produce interesting results. If you are - * deleting from firstkey to NULL it will work fine. - */ + /* + * To build a "key" in any of the below routines, pass in a pointer to + * the key and its size [i.e. sizeof(int), etc]. With any of the + * "key" or "data" arguments, if their size is < 0, it will do an + * internal strlen of the item and add 1 for the \0. + * + * If you are using firstkey() and nextkey() functions, be careful if, + * after starting your firstkey loop, you use delete or insert, it + * will not crash but may produce interesting results. If you are + * deleting from firstkey to NULL it will work fine. + */ -/* return types for table functions */ + /* return types for table functions */ #define TABLE_ERROR_NONE 1 /* no error from function */ #define TABLE_ERROR_PNT 2 /* bad table pointer */ #define TABLE_ERROR_ARG_NULL 3 /* buffer args were null */ @@ -62,146 +62,146 @@ extern "C" { #define TABLE_ERROR_COMPARE 19 /* problems with internal comparison */ #define TABLE_ERROR_FREE 20 /* memory free error */ -/* - * Table flags set with table_attr. - */ + /* + * Table flags set with table_attr. + */ -/* - * Automatically adjust the number of table buckets on the fly. - * Whenever the number of entries gets above some threshold, the - * number of buckets is realloced to a new size and each entry is - * re-hashed. Although this may take some time when it re-hashes, the - * table will perform better over time. - */ + /* + * Automatically adjust the number of table buckets on the fly. + * Whenever the number of entries gets above some threshold, the + * number of buckets is realloced to a new size and each entry is + * re-hashed. Although this may take some time when it re-hashes, the + * table will perform better over time. + */ #define TABLE_FLAG_AUTO_ADJUST (1<<0) -/* - * If the above auto-adjust flag is set, also adjust the number of - * table buckets down as we delete entries. - */ + /* + * If the above auto-adjust flag is set, also adjust the number of + * table buckets down as we delete entries. + */ #define TABLE_FLAG_ADJUST_DOWN (1<<1) -/* structure to walk through the fields in a linear order */ -typedef struct { - unsigned int tl_magic; /* magic structure to ensure correct init */ - unsigned int tl_bucket_c; /* where in the table buck array we are */ - unsigned int tl_entry_c; /* in the bucket, which entry we are on */ -} table_linear_t; + /* structure to walk through the fields in a linear order */ + typedef struct { + unsigned int tl_magic; /* magic structure to ensure correct init */ + unsigned int tl_bucket_c; /* where in the table buck array we are */ + unsigned int tl_entry_c; /* in the bucket, which entry we are on */ + } table_linear_t; -/* - * int (*table_compare_t) - * - * DESCRIPTION - * - * Comparison function which compares two key/data pairs for table - * order. - * - * RETURNS: - * - * -1, 0, or 1 if key1 is <, ==, or > than key2. - * - * ARGUMENTS: - * - * key1 - Pointer to the first key entry. - * - * key1_size - Pointer to the size of the first key entry. - * - * data1 - Pointer to the first data entry. - * - * data1_size - Pointer to the size of the first data entry. - * - * key2 - Pointer to the second key entry. - * - * key2_size - Pointer to the size of the second key entry. - * - * data2 - Pointer to the second data entry. - * - * data2_size - Pointer to the size of the second data entry. - */ -typedef int (*table_compare_t)(const void *key1, const int key1_size, - const void *data1, const int data1_size, - const void *key2, const int key2_size, - const void *data2, const int data2_size); + /* + * int (*table_compare_t) + * + * DESCRIPTION + * + * Comparison function which compares two key/data pairs for table + * order. + * + * RETURNS: + * + * -1, 0, or 1 if key1 is <, ==, or > than key2. + * + * ARGUMENTS: + * + * key1 - Pointer to the first key entry. + * + * key1_size - Pointer to the size of the first key entry. + * + * data1 - Pointer to the first data entry. + * + * data1_size - Pointer to the size of the first data entry. + * + * key2 - Pointer to the second key entry. + * + * key2_size - Pointer to the size of the second key entry. + * + * data2 - Pointer to the second data entry. + * + * data2_size - Pointer to the size of the second data entry. + */ + typedef int (*table_compare_t)(const void *key1, const int key1_size, + const void *data1, const int data1_size, + const void *key2, const int key2_size, + const void *data2, const int data2_size); -/* - * int (*table_mem_alloc_t) - * - * DESCRIPTION - * - * Function to override the table's allocation function. - * - * RETURNS: - * - * Success - Newly allocated pointer. - * - * Failure - NULL - * - * ARGUMENTS: - * - * pool_p <-> Pointer to our memory pool. If no pool is set then this - * will be NULL. - * - * size -> Number of bytes that needs to be allocated. - */ -typedef void *(*table_mem_alloc_t)(void *pool_p, const unsigned long size); + /* + * int (*table_mem_alloc_t) + * + * DESCRIPTION + * + * Function to override the table's allocation function. + * + * RETURNS: + * + * Success - Newly allocated pointer. + * + * Failure - NULL + * + * ARGUMENTS: + * + * pool_p <-> Pointer to our memory pool. If no pool is set then this + * will be NULL. + * + * size -> Number of bytes that needs to be allocated. + */ + typedef void *(*table_mem_alloc_t)(void *pool_p, const unsigned long size); -/* - * int (*table_mem_resize_t) - * - * DESCRIPTION - * - * Function to override the table's memory resize function. The - * difference between this and realloc is that this provides the - * previous allocation size. You can specify NULL for this function - * in which cause the library will allocate, copy, and free itself. - * - * RETURNS: - * - * Success - Newly allocated pointer. - * - * Failure - NULL - * - * ARGUMENTS: - * - * pool_p <-> Pointer to our memory pool. If no pool is set then this - * will be NULL. - * - * old_addr -> Previously allocated address. - * - * old_size -> Size of the old address. Since the system is - * lightweight, it does not store size information on the pointer. - * - * new_size -> New size of the allocation. - */ -typedef void *(*table_mem_resize_t)(void *pool_p, void *old_addr, - const unsigned long old_size, - const unsigned long new_size); + /* + * int (*table_mem_resize_t) + * + * DESCRIPTION + * + * Function to override the table's memory resize function. The + * difference between this and realloc is that this provides the + * previous allocation size. You can specify NULL for this function + * in which cause the library will allocate, copy, and free itself. + * + * RETURNS: + * + * Success - Newly allocated pointer. + * + * Failure - NULL + * + * ARGUMENTS: + * + * pool_p <-> Pointer to our memory pool. If no pool is set then this + * will be NULL. + * + * old_addr -> Previously allocated address. + * + * old_size -> Size of the old address. Since the system is + * lightweight, it does not store size information on the pointer. + * + * new_size -> New size of the allocation. + */ + typedef void *(*table_mem_resize_t)(void *pool_p, void *old_addr, + const unsigned long old_size, + const unsigned long new_size); -/* - * int (*table_mem_free_t) - * - * DESCRIPTION - * - * Function to override the table's free function. - * - * RETURNS: - * - * Success - 1 - * - * Failure - 0 - * - * ARGUMENTS: - * - * pool_p <-> Pointer to our memory pool. If no pool is set then this - * will be NULL. - * - * addr -> Address that we are freeing. - * - * min_size -> Minimum size of the address being freed or 0 if not - * known. This can also be the exact size if known. - */ -typedef int (*table_mem_free_t)(void *pool_p, void *addr, - const unsigned long min_size); + /* + * int (*table_mem_free_t) + * + * DESCRIPTION + * + * Function to override the table's free function. + * + * RETURNS: + * + * Success - 1 + * + * Failure - 0 + * + * ARGUMENTS: + * + * pool_p <-> Pointer to our memory pool. If no pool is set then this + * will be NULL. + * + * addr -> Address that we are freeing. + * + * min_size -> Minimum size of the address being freed or 0 if not + * known. This can also be the exact size if known. + */ + typedef int (*table_mem_free_t)(void *pool_p, void *addr, + const unsigned long min_size); #ifdef TABLE_MAIN @@ -209,1164 +209,1175 @@ typedef int (*table_mem_free_t)(void *pool_p, void *addr, #else -/* generic table type */ -typedef void table_t; + /* generic table type */ + typedef void table_t; -/* generic table entry type */ -typedef void table_entry_t; + /* generic table entry type */ + typedef void table_entry_t; #endif -/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ + /*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ -/* - * table_t *table_alloc - * - * DESCRIPTION: - * - * Allocate a new table structure. - * - * RETURNS: - * - * A pointer to the new table structure which must be passed to - * table_free to be deallocated. On error a NULL is returned. - * - * ARGUMENTS: - * - * bucket_n - Number of buckets for the hash table. Our current hash - * value works best with base two numbers. Set to 0 to take the - * library default of 1024. - * - * error_p - Pointer to an integer which, if not NULL, will contain a - * table error code. - */ -extern -table_t *table_alloc(const unsigned int bucket_n, int *error_p); + /* + * table_t *table_alloc + * + * DESCRIPTION: + * + * Allocate a new table structure. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_free to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * bucket_n - Number of buckets for the hash table. Our current hash + * value works best with base two numbers. Set to 0 to take the + * library default of 1024. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ + extern + table_t *table_alloc(const unsigned int bucket_n, int *error_p); -/* - * table_t *table_alloc_in_pool - * - * DESCRIPTION: - * - * Allocate a new table structure in a memory pool or using - * alternative allocation and free functions. - * - * RETURNS: - * - * A pointer to the new table structure which must be passed to - * table_free to be deallocated. On error a NULL is returned. - * - * ARGUMENTS: - * - * bucket_n - Number of buckets for the hash table. Our current hash - * value works best with base two numbers. Set to 0 to take the - * library default of 1024. - * - * mem_pool <-> Memory pool to associate with the table. Can be NULL. - * - * alloc_func -> Allocate function we are overriding malloc() with. - * - * resize_func -> Resize function we are overriding the standard - * memory resize/realloc with. This can be NULL in which cause the - * library will allocate, copy, and free itself. - * - * free_func -> Free function we are overriding free() with. - * - * error_p - Pointer to an integer which, if not NULL, will contain a - * table error code. - */ -extern -table_t *table_alloc_in_pool(const unsigned int bucket_n, - void *mem_pool, - table_mem_alloc_t alloc_func, - table_mem_resize_t resize_func, - table_mem_free_t free_func, int *error_p); + /* + * table_t *table_alloc_in_pool + * + * DESCRIPTION: + * + * Allocate a new table structure in a memory pool or using + * alternative allocation and free functions. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_free to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * bucket_n - Number of buckets for the hash table. Our current hash + * value works best with base two numbers. Set to 0 to take the + * library default of 1024. + * + * mem_pool <-> Memory pool to associate with the table. Can be NULL. + * + * alloc_func -> Allocate function we are overriding malloc() with. + * + * resize_func -> Resize function we are overriding the standard + * memory resize/realloc with. This can be NULL in which cause the + * library will allocate, copy, and free itself. + * + * free_func -> Free function we are overriding free() with. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ + extern + table_t *table_alloc_in_pool(const unsigned int bucket_n, + void *mem_pool, + table_mem_alloc_t alloc_func, + table_mem_resize_t resize_func, + table_mem_free_t free_func, int *error_p); -/* - * int table_attr - * - * DESCRIPTION: - * - * Set the attributes for the table. The available attributes are - * specified at the top of table.h. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Pointer to a table structure which we will be altering. - * - * attr - Attribute(s) that we will be applying to the table. - */ -extern -int table_attr(table_t *table_p, const int attr); + /* + * int table_attr + * + * DESCRIPTION: + * + * Set the attributes for the table. The available attributes are + * specified at the top of table.h. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to a table structure which we will be altering. + * + * attr - Attribute(s) that we will be applying to the table. + */ + extern + int table_attr(table_t *table_p, const int attr); -/* - * int table_set_data_alignment - * - * DESCRIPTION: - * - * Set the alignment for the data in the table. This is used when you - * want to store binary data types and refer to them directly out of - * the table storage. For instance if you are storing integers as - * data in the table and want to be able to retrieve the location of - * the interger and then increment it as (*loc_p)++. Otherwise you - * would have to memcpy it out to an integer, increment it, and memcpy - * it back. If you are storing character data, no alignment is - * necessary. - * - * For most data elements, sizeof(long) is recommended unless you use - * smaller data types exclusively. - * - * WARNING: If necessary, you must set the data alignment before any - * data gets put into the table. Otherwise a TABLE_ERROR_NOT_EMPTY - * error will be returned. - * - * NOTE: there is no way to set the key data alignment although it - * should automatically be long aligned. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Pointer to a table structure which we will be altering. - * - * alignment - Alignment requested for the data. Must be a power of - * 2. Set to 0 for none. - */ -extern -int table_set_data_alignment(table_t *table_p, const int alignment); + /* + * int table_set_data_alignment + * + * DESCRIPTION: + * + * Set the alignment for the data in the table. This is used when you + * want to store binary data types and refer to them directly out of + * the table storage. For instance if you are storing integers as + * data in the table and want to be able to retrieve the location of + * the interger and then increment it as (*loc_p)++. Otherwise you + * would have to memcpy it out to an integer, increment it, and memcpy + * it back. If you are storing character data, no alignment is + * necessary. + * + * For most data elements, sizeof(long) is recommended unless you use + * smaller data types exclusively. + * + * WARNING: If necessary, you must set the data alignment before any + * data gets put into the table. Otherwise a TABLE_ERROR_NOT_EMPTY + * error will be returned. + * + * NOTE: there is no way to set the key data alignment although it + * should automatically be long aligned. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to a table structure which we will be altering. + * + * alignment - Alignment requested for the data. Must be a power of + * 2. Set to 0 for none. + */ + extern + int table_set_data_alignment(table_t *table_p, const int alignment); -/* - * int table_clear - * - * DESCRIPTION: - * - * Clear out and free all elements in a table structure. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer that we will be clearing. - */ -extern -int table_clear(table_t *table_p); + /* + * int table_clear + * + * DESCRIPTION: + * + * Clear out and free all elements in a table structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer that we will be clearing. + */ + extern + int table_clear(table_t *table_p); -/* - * int table_free - * - * DESCRIPTION: - * - * Deallocates a table structure. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer that we will be freeing. - */ -extern -int table_free(table_t *table_p); + /* + * int table_free + * + * DESCRIPTION: + * + * Deallocates a table structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer that we will be freeing. + */ + extern + int table_free(table_t *table_p); -/* - * int table_insert_kd - * - * DESCRIPTION: - * - * Like table_insert except it passes back a pointer to the key and - * the data buffers after they have been inserted into the table - * structure. - * - * This routine adds a key/data pair both of which are made up of a - * buffer of bytes and an associated size. Both the key and the data - * will be copied into buffers allocated inside the table. If the key - * exists already, the associated data will be replaced if the - * overwrite flag is set, otherwise an error is returned. - * - * NOTE: be very careful changing the values since the table library - * provides the pointers to its memory. The key can _never_ be - * changed otherwise you will not find it again. The data can be - * changed but its length can never be altered unless you delete and - * re-insert it into the table. - * - * WARNING: The pointers to the key and data are not in any specific - * alignment. Accessing the key and/or data as an short, integer, or - * long pointer directly can cause problems. - * - * WARNING: Replacing a data cell (not inserting) will cause the table - * linked list to be temporarily invalid. Care must be taken with - * multiple threaded programs which are relying on the first/next - * linked list to be always valid. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer into which we will be inserting a - * new key/data pair. - * - * key_buf - Buffer of bytes of the key that we are inserting. If you - * are storing an (int) as the key (for example) then key_buf should - * be a (int *). - * - * key_size - Size of the key_buf buffer. If set to < 0 then the - * library will do a strlen of key_buf and add 1 for the '\0'. If you - * are storing an (int) as the key (for example) then key_size should - * be sizeof(int). - * - * data_buf - Buffer of bytes of the data that we are inserting. If - * it is NULL then the library will allocate space for the data in the - * table without copying in any information. If data_buf is NULL and - * data_size is 0 then the library will associate a NULL data pointer - * with the key. If you are storing a (long) as the data (for - * example) then data_buf should be a (long *). - * - * data_size - Size of the data_buf buffer. If set to < 0 then the - * library will do a strlen of data_buf and add 1 for the '\0'. If - * you are storing an (long) as the key (for example) then key_size - * should be sizeof(long). - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the key storage that was allocated in the table. If you are - * storing an (int) as the key (for example) then key_buf_p should be - * (int **) i.e. the address of a (int *). - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that was allocated in the table. If you are - * storing an (long) as the data (for example) then data_buf_p should - * be (long **) i.e. the address of a (long *). - * - * overwrite - Flag which, if set to 1, will allow the overwriting of - * the data in the table with the new data if the key already exists - * in the table. - */ -extern -int table_insert_kd(table_t *table_p, - const void *key_buf, const int key_size, - const void *data_buf, const int data_size, - void **key_buf_p, void **data_buf_p, - const char overwrite_b); + /* + * int table_insert_kd + * + * DESCRIPTION: + * + * Like table_insert except it passes back a pointer to the key and + * the data buffers after they have been inserted into the table + * structure. + * + * This routine adds a key/data pair both of which are made up of a + * buffer of bytes and an associated size. Both the key and the data + * will be copied into buffers allocated inside the table. If the key + * exists already, the associated data will be replaced if the + * overwrite flag is set, otherwise an error is returned. + * + * NOTE: be very careful changing the values since the table library + * provides the pointers to its memory. The key can _never_ be + * changed otherwise you will not find it again. The data can be + * changed but its length can never be altered unless you delete and + * re-insert it into the table. + * + * WARNING: The pointers to the key and data are not in any specific + * alignment. Accessing the key and/or data as an short, integer, or + * long pointer directly can cause problems. + * + * WARNING: Replacing a data cell (not inserting) will cause the table + * linked list to be temporarily invalid. Care must be taken with + * multiple threaded programs which are relying on the first/next + * linked list to be always valid. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be inserting a + * new key/data pair. + * + * key_buf - Buffer of bytes of the key that we are inserting. If you + * are storing an (int) as the key (for example) then key_buf should + * be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are storing an (int) as the key (for example) then key_size should + * be sizeof(int). + * + * data_buf - Buffer of bytes of the data that we are inserting. If + * it is NULL then the library will allocate space for the data in the + * table without copying in any information. If data_buf is NULL and + * data_size is 0 then the library will associate a NULL data pointer + * with the key. If you are storing a (long) as the data (for + * example) then data_buf should be a (long *). + * + * data_size - Size of the data_buf buffer. If set to < 0 then the + * library will do a strlen of data_buf and add 1 for the '\0'. If + * you are storing an (long) as the key (for example) then key_size + * should be sizeof(long). + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the key storage that was allocated in the table. If you are + * storing an (int) as the key (for example) then key_buf_p should be + * (int **) i.e. the address of a (int *). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table. If you are + * storing an (long) as the data (for example) then data_buf_p should + * be (long **) i.e. the address of a (long *). + * + * overwrite - Flag which, if set to 1, will allow the overwriting of + * the data in the table with the new data if the key already exists + * in the table. + */ + extern + int table_insert_kd(table_t *table_p, + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **key_buf_p, void **data_buf_p, + const char overwrite_b); -/* - * int table_insert - * - * DESCRIPTION: - * - * Exactly the same as table_insert_kd except it does not pass back a - * pointer to the key after they have been inserted into the table - * structure. This is still here for backwards compatibility. - * - * See table_insert_kd for more information. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer into which we will be inserting a - * new key/data pair. - * - * key_buf - Buffer of bytes of the key that we are inserting. If you - * are storing an (int) as the key (for example) then key_buf should - * be a (int *). - * - * key_size - Size of the key_buf buffer. If set to < 0 then the - * library will do a strlen of key_buf and add 1 for the '\0'. If you - * are storing an (int) as the key (for example) then key_size should - * be sizeof(int). - * - * data_buf - Buffer of bytes of the data that we are inserting. If - * it is NULL then the library will allocate space for the data in the - * table without copying in any information. If data_buf is NULL and - * data_size is 0 then the library will associate a NULL data pointer - * with the key. If you are storing a (long) as the data (for - * example) then data_buf should be a (long *). - * - * data_size - Size of the data_buf buffer. If set to < 0 then the - * library will do a strlen of data_buf and add 1 for the '\0'. If - * you are storing an (long) as the key (for example) then key_size - * should be sizeof(long). - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that was allocated in the table. If you are - * storing an (long) as the data (for example) then data_buf_p should - * be (long **) i.e. the address of a (long *). - * - * overwrite - Flag which, if set to 1, will allow the overwriting of - * the data in the table with the new data if the key already exists - * in the table. - */ -extern -int table_insert(table_t *table_p, - const void *key_buf, const int key_size, - const void *data_buf, const int data_size, - void **data_buf_p, const char overwrite_b); + /* + * int table_insert + * + * DESCRIPTION: + * + * Exactly the same as table_insert_kd except it does not pass back a + * pointer to the key after they have been inserted into the table + * structure. This is still here for backwards compatibility. + * + * See table_insert_kd for more information. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be inserting a + * new key/data pair. + * + * key_buf - Buffer of bytes of the key that we are inserting. If you + * are storing an (int) as the key (for example) then key_buf should + * be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are storing an (int) as the key (for example) then key_size should + * be sizeof(int). + * + * data_buf - Buffer of bytes of the data that we are inserting. If + * it is NULL then the library will allocate space for the data in the + * table without copying in any information. If data_buf is NULL and + * data_size is 0 then the library will associate a NULL data pointer + * with the key. If you are storing a (long) as the data (for + * example) then data_buf should be a (long *). + * + * data_size - Size of the data_buf buffer. If set to < 0 then the + * library will do a strlen of data_buf and add 1 for the '\0'. If + * you are storing an (long) as the key (for example) then key_size + * should be sizeof(long). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table. If you are + * storing an (long) as the data (for example) then data_buf_p should + * be (long **) i.e. the address of a (long *). + * + * overwrite - Flag which, if set to 1, will allow the overwriting of + * the data in the table with the new data if the key already exists + * in the table. + */ + extern + int table_insert(table_t *table_p, + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **data_buf_p, const char overwrite_b); -/* - * int table_retrieve - * - * DESCRIPTION: - * - * This routine looks up a key made up of a buffer of bytes and an - * associated size in the table. If found then it returns the - * associated data information. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer into which we will be searching - * for the key. - * - * key_buf - Buffer of bytes of the key that we are searching for. If - * you are looking for an (int) as the key (for example) then key_buf - * should be a (int *). - * - * key_size - Size of the key_buf buffer. If set to < 0 then the - * library will do a strlen of key_buf and add 1 for the '\0'. If you - * are looking for an (int) as the key (for example) then key_size - * should be sizeof(int). - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that was allocated in the table and that is - * associated with the key. If a (long) was stored as the data (for - * example) then data_buf_p should be (long **) i.e. the address of a - * (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data stored in the table that is associated with - * the key. - */ -extern -int table_retrieve(table_t *table_p, - const void *key_buf, const int key_size, - void **data_buf_p, int *data_size_p); + /* + * int table_retrieve + * + * DESCRIPTION: + * + * This routine looks up a key made up of a buffer of bytes and an + * associated size in the table. If found then it returns the + * associated data information. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer into which we will be searching + * for the key. + * + * key_buf - Buffer of bytes of the key that we are searching for. If + * you are looking for an (int) as the key (for example) then key_buf + * should be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are looking for an (int) as the key (for example) then key_size + * should be sizeof(int). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that is + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data stored in the table that is associated with + * the key. + */ + extern + int table_retrieve(table_t *table_p, + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p); -/* - * int table_delete - * - * DESCRIPTION: - * - * This routine looks up a key made up of a buffer of bytes and an - * associated size in the table. If found then it will be removed - * from the table. The associated data can be passed back to the user - * if requested. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * NOTE: this could be an allocation error if the library is to return - * the data to the user. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we will be deleteing - * the key. - * - * key_buf - Buffer of bytes of the key that we are searching for to - * delete. If you are deleting an (int) key (for example) then - * key_buf should be a (int *). - * - * key_size - Size of the key_buf buffer. If set to < 0 then the - * library will do a strlen of key_buf and add 1 for the '\0'. If you - * are deleting an (int) key (for example) then key_size should be - * sizeof(int). - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that was allocated in the table and that was - * associated with the key. If a (long) was stored as the data (for - * example) then data_buf_p should be (long **) i.e. the address of a - * (long *). If a pointer is passed in, the caller is responsible for - * freeing it after use. If data_buf_p is NULL then the library will - * free up the data allocation itself. - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that was stored in the table and that was - * associated with the key. - */ -extern -int table_delete(table_t *table_p, - const void *key_buf, const int key_size, - void **data_buf_p, int *data_size_p); + /* + * int table_delete + * + * DESCRIPTION: + * + * This routine looks up a key made up of a buffer of bytes and an + * associated size in the table. If found then it will be removed + * from the table. The associated data can be passed back to the user + * if requested. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * NOTE: this could be an allocation error if the library is to return + * the data to the user. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we will be deleteing + * the key. + * + * key_buf - Buffer of bytes of the key that we are searching for to + * delete. If you are deleting an (int) key (for example) then + * key_buf should be a (int *). + * + * key_size - Size of the key_buf buffer. If set to < 0 then the + * library will do a strlen of key_buf and add 1 for the '\0'. If you + * are deleting an (int) key (for example) then key_size should be + * sizeof(int). + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that was + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). If a pointer is passed in, the caller is responsible for + * freeing it after use. If data_buf_p is NULL then the library will + * free up the data allocation itself. + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that was stored in the table and that was + * associated with the key. + */ + extern + int table_delete(table_t *table_p, + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p); -/* - * int table_delete_first - * - * DESCRIPTION: - * - * This is like the table_delete routines except it deletes the first - * key/data pair in the table instead of an entry corresponding to a - * particular key. The associated key and data information can be - * passed back to the user if requested. This routines is handy to - * clear out a table. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * NOTE: this could be an allocation error if the library is to return - * the data to the user. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we will be deleteing - * the first key. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the first key that was allocated in the table. - * If an (int) was stored as the first key (for example) then - * key_buf_p should be (int **) i.e. the address of a (int *). If a - * pointer is passed in, the caller is responsible for freeing it - * after use. If key_buf_p is NULL then the library will free up the - * key allocation itself. - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that was stored in the table and that was - * associated with the key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that was allocated in the table and that was - * associated with the key. If a (long) was stored as the data (for - * example) then data_buf_p should be (long **) i.e. the address of a - * (long *). If a pointer is passed in, the caller is responsible for - * freeing it after use. If data_buf_p is NULL then the library will - * free up the data allocation itself. - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that was stored in the table and that was - * associated with the key. - */ -extern -int table_delete_first(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_delete_first + * + * DESCRIPTION: + * + * This is like the table_delete routines except it deletes the first + * key/data pair in the table instead of an entry corresponding to a + * particular key. The associated key and data information can be + * passed back to the user if requested. This routines is handy to + * clear out a table. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * NOTE: this could be an allocation error if the library is to return + * the data to the user. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we will be deleteing + * the first key. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that was allocated in the table. + * If an (int) was stored as the first key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). If a + * pointer is passed in, the caller is responsible for freeing it + * after use. If key_buf_p is NULL then the library will free up the + * key allocation itself. + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that was stored in the table and that was + * associated with the key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that was allocated in the table and that was + * associated with the key. If a (long) was stored as the data (for + * example) then data_buf_p should be (long **) i.e. the address of a + * (long *). If a pointer is passed in, the caller is responsible for + * freeing it after use. If data_buf_p is NULL then the library will + * free up the data allocation itself. + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that was stored in the table and that was + * associated with the key. + */ + extern + int table_delete_first(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * int table_info - * - * DESCRIPTION: - * - * Get some information about a table_p structure. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting - * information. - * - * num_buckets_p - Pointer to an integer which, if not NULL, will - * contain the number of buckets in the table. - * - * num_entries_p - Pointer to an integer which, if not NULL, will - * contain the number of entries stored in the table. - */ -extern -int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p); + /* + * int table_info + * + * DESCRIPTION: + * + * Get some information about a table_p structure. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting + * information. + * + * num_buckets_p - Pointer to an integer which, if not NULL, will + * contain the number of buckets in the table. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries stored in the table. + */ + extern + int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p); -/* - * int table_adjust - * - * DESCRIPTION: - * - * Set the number of buckets in a table to a certain value. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer of which we are adjusting. - * - * bucket_n - Number buckets to adjust the table to. Set to 0 to - * adjust the table to its number of entries. - */ -extern -int table_adjust(table_t *table_p, const int bucket_n); + /* + * int table_adjust + * + * DESCRIPTION: + * + * Set the number of buckets in a table to a certain value. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer of which we are adjusting. + * + * bucket_n - Number buckets to adjust the table to. Set to 0 to + * adjust the table to its number of entries. + */ + extern + int table_adjust(table_t *table_p, const int bucket_n); -/* - * int table_type_size - * - * DESCRIPTION: - * - * Return the size of the internal table type. - * - * RETURNS: - * - * The size of the table_t type. - * - * ARGUMENTS: - * - * None. - */ -extern -int table_type_size(void); + /* + * int table_type_size + * + * DESCRIPTION: + * + * Return the size of the internal table type. + * + * RETURNS: + * + * The size of the table_t type. + * + * ARGUMENTS: + * + * None. + */ + extern + int table_type_size(void); -/* - * int table_first - * - * DESCRIPTION: - * - * Find first element in a table and pass back information about the - * key/data pair. If any of the key/data pointers are NULL then they - * are ignored. - * - * NOTE: This function is not reentrant. More than one thread cannot - * be doing a first and next on the same table at the same time. Use - * the table_first_r version below for this. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * first element. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the first key that is allocated in the table. If - * an (int) is stored as the first key (for example) then key_buf_p - * should be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table and that is - * associated with the first key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that is allocated in the table and that is - * associated with the first key. If a (long) is stored as the data - * (for example) then data_buf_p should be (long **) i.e. the address - * of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table and that is - * associated with the first key. - */ -extern -int table_first(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_first + * + * DESCRIPTION: + * + * Find first element in a table and pass back information about the + * key/data pair. If any of the key/data pointers are NULL then they + * are ignored. + * + * NOTE: This function is not reentrant. More than one thread cannot + * be doing a first and next on the same table at the same time. Use + * the table_first_r version below for this. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * first element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that is allocated in the table. If + * an (int) is stored as the first key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the first key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the first key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the first key. + */ + extern + int table_first(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * int table_next - * - * DESCRIPTION: - * - * Find the next element in a table and pass back information about - * the key/data pair. If any of the key/data pointers are NULL then - * they are ignored. - * - * NOTE: This function is not reentrant. More than one thread cannot - * be doing a first and next on the same table at the same time. Use - * the table_next_r version below for this. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * next element. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the next key that is allocated in the table. If - * an (int) is stored as the next key (for example) then key_buf_p - * should be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table and that is - * associated with the next key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that is allocated in the table and that is - * associated with the next key. If a (long) is stored as the data - * (for example) then data_buf_p should be (long **) i.e. the address - * of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table and that is - * associated with the next key. - */ -extern -int table_next(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_next + * + * DESCRIPTION: + * + * Find the next element in a table and pass back information about + * the key/data pair. If any of the key/data pointers are NULL then + * they are ignored. + * + * NOTE: This function is not reentrant. More than one thread cannot + * be doing a first and next on the same table at the same time. Use + * the table_next_r version below for this. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * next element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the next key that is allocated in the table. If + * an (int) is stored as the next key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the next key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the next key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the next key. + */ + extern + int table_next(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * int table_this - * - * DESCRIPTION: - * - * Find the current element in a table and pass back information about - * the key/data pair. If any of the key/data pointers are NULL then - * they are ignored. - * - * NOTE: This function is not reentrant. Use the table_current_r - * version below. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * current element. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the current key that is allocated in the table. - * If an (int) is stored as the current key (for example) then - * key_buf_p should be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table and that is - * associated with the current key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that is allocated in the table and that is - * associated with the current key. If a (long) is stored as the data - * (for example) then data_buf_p should be (long **) i.e. the address - * of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table and that is - * associated with the current key. - */ -extern -int table_this(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_this + * + * DESCRIPTION: + * + * Find the current element in a table and pass back information about + * the key/data pair. If any of the key/data pointers are NULL then + * they are ignored. + * + * NOTE: This function is not reentrant. Use the table_current_r + * version below. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * current element. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the current key that is allocated in the table. + * If an (int) is stored as the current key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the current key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the current key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the current key. + */ + extern + int table_this(table_t *table_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * int table_first_r - * - * DESCRIPTION: - * - * Reetrant version of the table_first routine above. Find first - * element in a table and pass back information about the key/data - * pair. If any of the key/data pointers are NULL then they are - * ignored. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * first element. - * - * linear_p - Pointer to a table linear structure which is initialized - * here. The same pointer should then be passed to table_next_r - * below. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the first key that is allocated in the table. If - * an (int) is stored as the first key (for example) then key_buf_p - * should be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table and that is - * associated with the first key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that is allocated in the table and that is - * associated with the first key. If a (long) is stored as the data - * (for example) then data_buf_p should be (long **) i.e. the address - * of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table and that is - * associated with the first key. - */ -extern -int table_first_r(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_first_r + * + * DESCRIPTION: + * + * Reetrant version of the table_first routine above. Find first + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * first element. + * + * linear_p - Pointer to a table linear structure which is initialized + * here. The same pointer should then be passed to table_next_r + * below. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the first key that is allocated in the table. If + * an (int) is stored as the first key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the first key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the first key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the first key. + */ + extern + int table_first_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * int table_next_r - * - * DESCRIPTION: - * - * Reetrant version of the table_next routine above. Find next - * element in a table and pass back information about the key/data - * pair. If any of the key/data pointers are NULL then they are - * ignored. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * next element. - * - * linear_p - Pointer to a table linear structure which is incremented - * here. The same pointer must have been passed to table_first_r - * first so that it can be initialized. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the next key that is allocated in the table. If - * an (int) is stored as the next key (for example) then key_buf_p - * should be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL will be set - * to the size of the key that is stored in the table and that is - * associated with the next key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that is allocated in the table and that is - * associated with the next key. If a (long) is stored as the data - * (for example) then data_buf_p should be (long **) i.e. the address - * of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table and that is - * associated with the next key. - */ -extern -int table_next_r(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_next_r + * + * DESCRIPTION: + * + * Reetrant version of the table_next routine above. Find next + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * next element. + * + * linear_p - Pointer to a table linear structure which is incremented + * here. The same pointer must have been passed to table_first_r + * first so that it can be initialized. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the next key that is allocated in the table. If + * an (int) is stored as the next key (for example) then key_buf_p + * should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL will be set + * to the size of the key that is stored in the table and that is + * associated with the next key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the next key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the next key. + */ + extern + int table_next_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * int table_this_r - * - * DESCRIPTION: - * - * Reetrant version of the table_this routine above. Find current - * element in a table and pass back information about the key/data - * pair. If any of the key/data pointers are NULL then they are - * ignored. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * current element. - * - * linear_p - Pointer to a table linear structure which is accessed - * here. The same pointer must have been passed to table_first_r - * first so that it can be initialized. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of the current key that is allocated in the table. - * If an (int) is stored as the current key (for example) then - * key_buf_p should be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table and that is - * associated with the current key. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage that is allocated in the table and that is - * associated with the current key. If a (long) is stored as the data - * (for example) then data_buf_p should be (long **) i.e. the address - * of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table and that is - * associated with the current key. - */ -extern -int table_this_r(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_this_r + * + * DESCRIPTION: + * + * Reetrant version of the table_this routine above. Find current + * element in a table and pass back information about the key/data + * pair. If any of the key/data pointers are NULL then they are + * ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * current element. + * + * linear_p - Pointer to a table linear structure which is accessed + * here. The same pointer must have been passed to table_first_r + * first so that it can be initialized. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of the current key that is allocated in the table. + * If an (int) is stored as the current key (for example) then + * key_buf_p should be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table and that is + * associated with the current key. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage that is allocated in the table and that is + * associated with the current key. If a (long) is stored as the data + * (for example) then data_buf_p should be (long **) i.e. the address + * of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table and that is + * associated with the current key. + */ + extern + int table_this_r(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * table_t *table_mmap - * - * DESCRIPTION: - * - * Mmap a table from a file that had been written to disk earlier via - * table_write. - * - * RETURNS: - * - * A pointer to the new table structure which must be passed to - * table_munmap to be deallocated. On error a NULL is returned. - * - * ARGUMENTS: - * - * path - Table file to mmap in. - * - * error_p - Pointer to an integer which, if not NULL, will contain a - * table error code. - */ -extern -table_t *table_mmap(const char *path, int *error_p); + /* + * table_t *table_mmap + * + * DESCRIPTION: + * + * Mmap a table from a file that had been written to disk earlier via + * table_write. + * + * RETURNS: + * + * A pointer to the new table structure which must be passed to + * table_munmap to be deallocated. On error a NULL is returned. + * + * ARGUMENTS: + * + * path - Table file to mmap in. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ + extern + table_t *table_mmap(const char *path, int *error_p); -/* - * int table_munmap - * - * DESCRIPTION: - * - * Unmmap a table that was previously mmapped using table_mmap. - * - * RETURNS: - * - * Returns table error codes. - * - * ARGUMENTS: - * - * table_p - Mmaped table pointer to unmap. - */ -extern -int table_munmap(table_t *table_p); + /* + * int table_munmap + * + * DESCRIPTION: + * + * Unmmap a table that was previously mmapped using table_mmap. + * + * RETURNS: + * + * Returns table error codes. + * + * ARGUMENTS: + * + * table_p - Mmaped table pointer to unmap. + */ + extern + int table_munmap(table_t *table_p); -/* - * int table_read - * - * DESCRIPTION: - * - * Read in a table from a file that had been written to disk earlier - * via table_write. - * - * RETURNS: - * - * Success - Pointer to the new table structure which must be passed - * to table_free to be deallocated. - * - * Failure - NULL - * - * ARGUMENTS: - * - * path - Table file to read in. - * - * error_p - Pointer to an integer which, if not NULL, will contain a - * table error code. - */ -extern -table_t *table_read(const char *path, int *error_p); + /* + * int table_read + * + * DESCRIPTION: + * + * Read in a table from a file that had been written to disk earlier + * via table_write. + * + * RETURNS: + * + * Success - Pointer to the new table structure which must be passed + * to table_free to be deallocated. + * + * Failure - NULL + * + * ARGUMENTS: + * + * path - Table file to read in. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ + extern + table_t *table_read(const char *path, int *error_p); -/* - * int table_write - * - * DESCRIPTION: - * - * Write a table from memory to file. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Pointer to the table that we are writing to the file. - * - * path - Table file to write out to. - * - * mode - Mode of the file. This argument is passed on to open when - * the file is created. - */ -extern -int table_write(const table_t *table_p, const char *path, const int mode); + /* + * int table_write + * + * DESCRIPTION: + * + * Write a table from memory to file. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are writing to the file. + * + * path - Table file to write out to. + * + * mode - Mode of the file. This argument is passed on to open when + * the file is created. + */ + extern + int table_write(const table_t *table_p, const char *path, const int mode); -/* - * table_entry_t *table_order - * - * DESCRIPTION: - * - * Order a table by building an array of table entry pointers and then - * sorting this array using the qsort function. To retrieve the - * sorted entries, you can then use the table_entry routine to access - * each entry in order. - * - * NOTE: This routine is thread safe and makes use of an internal - * status qsort function. - * - * RETURNS: - * - * Success - An allocated list of table-linear structures which must - * be freed by table_order_free later. - * - * Failure - NULL - * - * ARGUMENTS: - * - * table_p - Pointer to the table that we are ordering. - * - * compare - Comparison function defined by the user. Its definition - * is at the top of the table.h file. If this is NULL then it will - * order the table my memcmp-ing the keys. - * - * num_entries_p - Pointer to an integer which, if not NULL, will - * contain the number of entries in the returned entry pointer array. - * - * error_p - Pointer to an integer which, if not NULL, will contain a - * table error code. - */ -extern -table_entry_t **table_order(table_t *table_p, table_compare_t compare, - int *num_entries_p, int *error_p); + /* + * table_entry_t *table_order + * + * DESCRIPTION: + * + * Order a table by building an array of table entry pointers and then + * sorting this array using the qsort function. To retrieve the + * sorted entries, you can then use the table_entry routine to access + * each entry in order. + * + * NOTE: This routine is thread safe and makes use of an internal + * status qsort function. + * + * RETURNS: + * + * Success - An allocated list of table-linear structures which must + * be freed by table_order_free later. + * + * Failure - NULL + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are ordering. + * + * compare - Comparison function defined by the user. Its definition + * is at the top of the table.h file. If this is NULL then it will + * order the table my memcmp-ing the keys. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries in the returned entry pointer array. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ + extern + table_entry_t **table_order(table_t *table_p, table_compare_t compare, + int *num_entries_p, int *error_p); -/* - * int table_order_free - * - * DESCRIPTION: - * - * Free the pointer returned by the table_order or table_order_pos - * routines. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Pointer to the table. - * - * table_entries - Allocated list of entry pointers returned by - * table_order. - * - * entry_n - Number of entries in the array as passed back by - * table_order or table_order_pos in num_entries_p. - */ -extern -int table_order_free(table_t *table_p, table_entry_t **table_entries, - const int entry_n); + /* + * int table_order_free + * + * DESCRIPTION: + * + * Free the pointer returned by the table_order or table_order_pos + * routines. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table. + * + * table_entries - Allocated list of entry pointers returned by + * table_order. + * + * entry_n - Number of entries in the array as passed back by + * table_order or table_order_pos in num_entries_p. + */ + extern + int table_order_free(table_t *table_p, table_entry_t **table_entries, + const int entry_n); -/* - * int table_entry - * - * DESCRIPTION: - * - * Get information about an element. The element is one from the - * array returned by the table_order function. If any of the key/data - * pointers are NULL then they are ignored. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * element. - * - * entry_p - Pointer to a table entry from the array returned by the - * table_order function. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of this entry that is allocated in the table. If an - * (int) is stored as this entry (for example) then key_buf_p should - * be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage of this entry that is allocated in the table. - * If a (long) is stored as this entry data (for example) then - * data_buf_p should be (long **) i.e. the address of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table. - */ -extern -int table_entry(table_t *table_p, table_entry_t *entry_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_entry + * + * DESCRIPTION: + * + * Get information about an element. The element is one from the + * array returned by the table_order function. If any of the key/data + * pointers are NULL then they are ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * element. + * + * entry_p - Pointer to a table entry from the array returned by the + * table_order function. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of this entry that is allocated in the table. If an + * (int) is stored as this entry (for example) then key_buf_p should + * be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage of this entry that is allocated in the table. + * If a (long) is stored as this entry data (for example) then + * data_buf_p should be (long **) i.e. the address of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table. + */ + extern + int table_entry(table_t *table_p, table_entry_t *entry_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * table_linear_t *table_order_pos - * - * DESCRIPTION: - * - * Order a table by building an array of table linear structures and - * then sorting this array using the qsort function. To retrieve the - * sorted entries, you can then use the table_entry_pos routine to - * access each entry in order. - * - * NOTE: This routine is thread safe and makes use of an internal - * status qsort function. - * - * RETURNS: - * - * Success - An allocated list of table-linear structures which must - * be freed by table_order_pos_free later. - * - * Failure - NULL - * - * ARGUMENTS: - * - * table_p - Pointer to the table that we are ordering. - * - * compare - Comparison function defined by the user. Its definition - * is at the top of the table.h file. If this is NULL then it will - * order the table my memcmp-ing the keys. - * - * num_entries_p - Pointer to an integer which, if not NULL, will - * contain the number of entries in the returned entry pointer array. - * - * error_p - Pointer to an integer which, if not NULL, will contain a - * table error code. - */ -extern -table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare, - int *num_entries_p, int *error_p); + /* + * table_linear_t *table_order_pos + * + * DESCRIPTION: + * + * Order a table by building an array of table linear structures and + * then sorting this array using the qsort function. To retrieve the + * sorted entries, you can then use the table_entry_pos routine to + * access each entry in order. + * + * NOTE: This routine is thread safe and makes use of an internal + * status qsort function. + * + * RETURNS: + * + * Success - An allocated list of table-linear structures which must + * be freed by table_order_pos_free later. + * + * Failure - NULL + * + * ARGUMENTS: + * + * table_p - Pointer to the table that we are ordering. + * + * compare - Comparison function defined by the user. Its definition + * is at the top of the table.h file. If this is NULL then it will + * order the table my memcmp-ing the keys. + * + * num_entries_p - Pointer to an integer which, if not NULL, will + * contain the number of entries in the returned entry pointer array. + * + * error_p - Pointer to an integer which, if not NULL, will contain a + * table error code. + */ + extern + table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare, + int *num_entries_p, int *error_p); -/* - * int table_order_pos_free - * - * DESCRIPTION: - * - * Free the pointer returned by the table_order or table_order_pos - * routines. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Pointer to the table. - * - * table_entries - Allocated list of entry pointers returned by - * table_order_pos. - * - * entry_n - Number of entries in the array as passed back by - * table_order or table_order_pos in num_entries_p. - */ -extern -int table_order_pos_free(table_t *table_p, table_linear_t *table_entries, - const int entry_n); + /* + * int table_order_pos_free + * + * DESCRIPTION: + * + * Free the pointer returned by the table_order or table_order_pos + * routines. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Pointer to the table. + * + * table_entries - Allocated list of entry pointers returned by + * table_order_pos. + * + * entry_n - Number of entries in the array as passed back by + * table_order or table_order_pos in num_entries_p. + */ + extern + int table_order_pos_free(table_t *table_p, table_linear_t *table_entries, + const int entry_n); -/* - * int table_entry_pos - * - * DESCRIPTION: - * - * Get information about an element. The element is one from the - * array returned by the table_order function. If any of the key/data - * pointers are NULL then they are ignored. - * - * RETURNS: - * - * Success - TABLE_ERROR_NONE - * - * Failure - Table error code. - * - * ARGUMENTS: - * - * table_p - Table structure pointer from which we are getting the - * element. - * - * linear_p - Pointer to a table linear structure from the array - * returned by the table_order function. - * - * key_buf_p - Pointer which, if not NULL, will be set to the address - * of the storage of this entry that is allocated in the table. If an - * (int) is stored as this entry (for example) then key_buf_p should - * be (int **) i.e. the address of a (int *). - * - * key_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the key that is stored in the table. - * - * data_buf_p - Pointer which, if not NULL, will be set to the address - * of the data storage of this entry that is allocated in the table. - * If a (long) is stored as this entry data (for example) then - * data_buf_p should be (long **) i.e. the address of a (long *). - * - * data_size_p - Pointer to an integer which, if not NULL, will be set - * to the size of the data that is stored in the table. - */ -extern -int table_entry_pos(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p); + /* + * int table_entry_pos + * + * DESCRIPTION: + * + * Get information about an element. The element is one from the + * array returned by the table_order function. If any of the key/data + * pointers are NULL then they are ignored. + * + * RETURNS: + * + * Success - TABLE_ERROR_NONE + * + * Failure - Table error code. + * + * ARGUMENTS: + * + * table_p - Table structure pointer from which we are getting the + * element. + * + * linear_p - Pointer to a table linear structure from the array + * returned by the table_order function. + * + * key_buf_p - Pointer which, if not NULL, will be set to the address + * of the storage of this entry that is allocated in the table. If an + * (int) is stored as this entry (for example) then key_buf_p should + * be (int **) i.e. the address of a (int *). + * + * key_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the key that is stored in the table. + * + * data_buf_p - Pointer which, if not NULL, will be set to the address + * of the data storage of this entry that is allocated in the table. + * If a (long) is stored as this entry data (for example) then + * data_buf_p should be (long **) i.e. the address of a (long *). + * + * data_size_p - Pointer to an integer which, if not NULL, will be set + * to the size of the data that is stored in the table. + */ + extern + int table_entry_pos(table_t *table_p, table_linear_t *linear_p, + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p); -/* - * const char *table_strerror - * - * DESCRIPTION: - * - * Return the corresponding string for the error number. - * - * RETURNS: - * - * Success - String equivalient of the error. - * - * Failure - String "invalid error code" - * - * ARGUMENTS: - * - * error - Error number that we are converting. - */ -extern -const char *table_strerror(const int error); + /* + * const char *table_strerror + * + * DESCRIPTION: + * + * Return the corresponding string for the error number. + * + * RETURNS: + * + * Success - String equivalient of the error. + * + * Failure - String "invalid error code" + * + * ARGUMENTS: + * + * error - Error number that we are converting. + */ + extern + const char *table_strerror(const int error); -/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ + /*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* ! __TABLE_H__ */ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/include/table_loc.h b/libs/libks/src/include/table_loc.h index 02514c8211..95149db971 100644 --- a/libs/libks/src/include/table_loc.h +++ b/libs/libks/src/include/table_loc.h @@ -83,25 +83,25 @@ * were about 2^68 hashes to choose from. I only tested about a * billion of those. */ -#define HASH_MIX(a, b, c) \ - do { \ - a -= b; a -= c; a ^= (c >> 13); \ - b -= c; b -= a; b ^= (a << 8); \ - c -= a; c -= b; c ^= (b >> 13); \ - a -= b; a -= c; a ^= (c >> 12); \ - b -= c; b -= a; b ^= (a << 16); \ - c -= a; c -= b; c ^= (b >> 5); \ - a -= b; a -= c; a ^= (c >> 3); \ - b -= c; b -= a; b ^= (a << 10); \ - c -= a; c -= b; c ^= (b >> 15); \ - } while(0) +#define HASH_MIX(a, b, c) \ + do { \ + a -= b; a -= c; a ^= (c >> 13); \ + b -= c; b -= a; b ^= (a << 8); \ + c -= a; c -= b; c ^= (b >> 13); \ + a -= b; a -= c; a ^= (c >> 12); \ + b -= c; b -= a; b ^= (a << 16); \ + c -= a; c -= b; c ^= (b >> 5); \ + a -= b; a -= c; a ^= (c >> 3); \ + b -= c; b -= a; b ^= (a << 10); \ + c -= a; c -= b; c ^= (b >> 15); \ + } while(0) -#define SET_POINTER(pnt, val) \ - do { \ - if ((pnt) != NULL) { \ - (*(pnt)) = (val); \ - } \ - } while(0) +#define SET_POINTER(pnt, val) \ + do { \ + if ((pnt) != NULL) { \ + (*(pnt)) = (val); \ + } \ + } while(0) /* * The following macros take care of the mmap case. When we are @@ -117,9 +117,9 @@ #else -#define TABLE_POINTER(tab_p, type, pnt) \ - ((tab_p)->ta_mmap == NULL || (pnt) == NULL ? (pnt) : \ - (type)((char *)((tab_p)->ta_mmap) + (long)(pnt))) +#define TABLE_POINTER(tab_p, type, pnt) \ + ((tab_p)->ta_mmap == NULL || (pnt) == NULL ? (pnt) : \ + (type)((char *)((tab_p)->ta_mmap) + (long)(pnt))) #endif @@ -127,8 +127,8 @@ * Macros to get at the key and the data pointers */ #define ENTRY_KEY_BUF(entry_p) ((entry_p)->te_key_buf) -#define ENTRY_DATA_BUF(tab_p, entry_p) \ - (ENTRY_KEY_BUF(entry_p) + (entry_p)->te_key_size) +#define ENTRY_DATA_BUF(tab_p, entry_p) \ + (ENTRY_KEY_BUF(entry_p) + (entry_p)->te_key_size) /* * Table structures... @@ -142,10 +142,10 @@ * faster. */ typedef struct table_shell_st { - unsigned int te_key_size; /* size of data */ - unsigned int te_data_size; /* size of data */ - struct table_shell_st *te_next_p; /* pointer to next in the list */ - /* NOTE: this does not have the te_key_buf field here */ + unsigned int te_key_size; /* size of data */ + unsigned int te_data_size; /* size of data */ + struct table_shell_st *te_next_p; /* pointer to next in the list */ + /* NOTE: this does not have the te_key_buf field here */ } table_shell_t; /* @@ -157,10 +157,10 @@ typedef struct table_shell_st { * changed to match. */ typedef struct table_entry_st { - unsigned int te_key_size; /* size of data */ - unsigned int te_data_size; /* size of data */ - struct table_entry_st *te_next_p; /* pointer to next in the list */ - unsigned char te_key_buf[1]; /* 1st byte of key buf */ + unsigned int te_key_size; /* size of data */ + unsigned int te_data_size; /* size of data */ + struct table_entry_st *te_next_p; /* pointer to next in the list */ + unsigned char te_key_buf[1]; /* 1st byte of key buf */ } table_entry_t; /* external structure for debuggers be able to see void */ @@ -168,20 +168,20 @@ typedef table_entry_t table_entry_ext_t; /* main table structure */ typedef struct table_st { - unsigned int ta_magic; /* magic number */ - unsigned int ta_flags; /* table's flags defined in table.h */ - unsigned int ta_bucket_n; /* num of buckets, should be 2^X */ - unsigned int ta_entry_n; /* num of entries in all buckets */ - unsigned int ta_data_align; /* data alignment value */ - table_entry_t **ta_buckets; /* array of linked lists */ - table_linear_t ta_linear; /* linear tracking */ - struct table_st *ta_mmap; /* mmaped table */ - unsigned long ta_file_size; /* size of on-disk space */ + unsigned int ta_magic; /* magic number */ + unsigned int ta_flags; /* table's flags defined in table.h */ + unsigned int ta_bucket_n; /* num of buckets, should be 2^X */ + unsigned int ta_entry_n; /* num of entries in all buckets */ + unsigned int ta_data_align; /* data alignment value */ + table_entry_t **ta_buckets; /* array of linked lists */ + table_linear_t ta_linear; /* linear tracking */ + struct table_st *ta_mmap; /* mmaped table */ + unsigned long ta_file_size; /* size of on-disk space */ - void *ta_mem_pool; /* pointer to some memory pool */ - table_mem_alloc_t ta_alloc_func; /* memory allocation function */ - table_mem_resize_t ta_resize_func; /* memory resize function */ - table_mem_free_t ta_free_func; /* memory free function */ + void *ta_mem_pool; /* pointer to some memory pool */ + table_mem_alloc_t ta_alloc_func; /* memory allocation function */ + table_mem_resize_t ta_resize_func; /* memory resize function */ + table_mem_free_t ta_free_func; /* memory free function */ } table_t; /* external table structure for debuggers */ @@ -189,41 +189,53 @@ typedef table_t table_ext_t; /* local comparison functions */ typedef int (*compare_t)(const void *element1_p, const void *element2_p, - table_compare_t user_compare, - const table_t *table_p, int *err_bp); + table_compare_t user_compare, + const table_t *table_p, int *err_bp); /* * to map error to string */ typedef struct { - int es_error; /* error number */ - char *es_string; /* assocaited string */ + int es_error; /* error number */ + char *es_string; /* assocaited string */ } error_str_t; static error_str_t errors[] = { - { TABLE_ERROR_NONE, "no error" }, - { TABLE_ERROR_PNT, "invalid table pointer" }, - { TABLE_ERROR_ARG_NULL, "buffer argument is null" }, - { TABLE_ERROR_SIZE, "incorrect size argument" }, - { TABLE_ERROR_OVERWRITE, "key exists and no overwrite" }, - { TABLE_ERROR_NOT_FOUND, "key does not exist" }, - { TABLE_ERROR_ALLOC, "error allocating memory" }, - { TABLE_ERROR_LINEAR, "linear access not in progress" }, - { TABLE_ERROR_OPEN, "could not open file" }, - { TABLE_ERROR_SEEK, "could not seek to position in file" }, - { TABLE_ERROR_READ, "could not read from file" }, - { TABLE_ERROR_WRITE, "could not write to file" }, - { TABLE_ERROR_MMAP_NONE, "no mmap support compiled in library" }, - { TABLE_ERROR_MMAP, "could not mmap the file" }, - { TABLE_ERROR_MMAP_OP, "operation not valid on mmap files" }, - { TABLE_ERROR_EMPTY, "table is empty" }, - { TABLE_ERROR_NOT_EMPTY, "table contains data" }, - { TABLE_ERROR_ALIGNMENT, "invalid alignment value" }, - { TABLE_ERROR_COMPARE, "problems with internal comparison" }, - { TABLE_ERROR_FREE, "memory free error" }, - { 0 } + { TABLE_ERROR_NONE, "no error" }, + { TABLE_ERROR_PNT, "invalid table pointer" }, + { TABLE_ERROR_ARG_NULL, "buffer argument is null" }, + { TABLE_ERROR_SIZE, "incorrect size argument" }, + { TABLE_ERROR_OVERWRITE, "key exists and no overwrite" }, + { TABLE_ERROR_NOT_FOUND, "key does not exist" }, + { TABLE_ERROR_ALLOC, "error allocating memory" }, + { TABLE_ERROR_LINEAR, "linear access not in progress" }, + { TABLE_ERROR_OPEN, "could not open file" }, + { TABLE_ERROR_SEEK, "could not seek to position in file" }, + { TABLE_ERROR_READ, "could not read from file" }, + { TABLE_ERROR_WRITE, "could not write to file" }, + { TABLE_ERROR_MMAP_NONE, "no mmap support compiled in library" }, + { TABLE_ERROR_MMAP, "could not mmap the file" }, + { TABLE_ERROR_MMAP_OP, "operation not valid on mmap files" }, + { TABLE_ERROR_EMPTY, "table is empty" }, + { TABLE_ERROR_NOT_EMPTY, "table contains data" }, + { TABLE_ERROR_ALIGNMENT, "invalid alignment value" }, + { TABLE_ERROR_COMPARE, "problems with internal comparison" }, + { TABLE_ERROR_FREE, "memory free error" }, + { 0 } }; #define INVALID_ERROR "invalid error code" #endif /* ! __TABLE_LOC_H__ */ + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ + diff --git a/libs/libks/src/ks.c b/libs/libks/src/ks.c index ebaaa143a2..2747bd43e9 100644 --- a/libs/libks/src/ks.c +++ b/libs/libks/src/ks.c @@ -59,6 +59,7 @@ /* These warnings need to be ignored warning in sdk header */ #include #include +#pragma comment(lib, "Ws2_32.lib") #ifndef errno #define errno WSAGetLastError() #endif diff --git a/libs/libks/src/ks_json.c b/libs/libks/src/ks_json.c index ffa965a609..63529e7b5b 100644 --- a/libs/libks/src/ks_json.c +++ b/libs/libks/src/ks_json.c @@ -204,7 +204,7 @@ static const char *parse_string(cJSON *item,const char *str) break; default: *ptr2++=*ptr; break; } - ptr++; + if (*ptr) ptr++; } } *ptr2=0; diff --git a/libs/libks/src/mpool.c b/libs/libks/src/mpool.c index 72c5b6b108..31c7a166aa 100644 --- a/libs/libks/src/mpool.c +++ b/libs/libks/src/mpool.c @@ -37,7 +37,17 @@ #include #include #include +#ifdef _MSC_VER +#include +#ifndef open +#define open _open +#endif +#ifndef close +#define close _close +#endif +#else #include +#endif #include #ifdef DMALLOC @@ -56,14 +66,26 @@ static char *rcs_id = "$Id: mpool.c,v 1.5 2006/05/31 20:28:31 gray Exp $"; #endif /* version */ -static char *version = "mpool library version 2.1.0"; +static char *version = "mpool library version 2.1.0"; /* local variables */ -static int enabled_b = 0; /* lib initialized? */ -static unsigned int min_bit_free_next = 0; /* min size of next pnt */ -static unsigned int min_bit_free_size = 0; /* min size of next + size */ -static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */ +static int enabled_b = 0; /* lib initialized? */ +static unsigned int min_bit_free_next = 0; /* min size of next pnt */ +static unsigned int min_bit_free_size = 0; /* min size of next + size */ +static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */ +#ifdef _MSC_VER +#include +long getpagesize(void) { + static long g_pagesize = 0; + if (!g_pagesize) { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + g_pagesize = system_info.dwPageSize; + } + return g_pagesize; +} +#endif /****************************** local utilities ******************************/ /* @@ -81,38 +103,38 @@ static unsigned long bit_array[MAX_BITS + 1]; /* size -> bit */ * * None. */ -static void startup(void) +static void startup(void) { - int bit_c; - unsigned long size = 1; + int bit_c; + unsigned long size = 1; - if (enabled_b) { - return; - } - - /* allocate our free bit array list */ - for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { - bit_array[bit_c] = size; - - /* - * Note our minimum number of bits that can store a pointer. This - * is smallest address that we can have a linked list for. - */ - if (min_bit_free_next == 0 && size >= sizeof(void *)) { - min_bit_free_next = bit_c; + if (enabled_b) { + return; } - /* - * Note our minimum number of bits that can store a pointer and - * the size of the block. - */ - if (min_bit_free_size == 0 && size >= sizeof(mpool_free_t)) { - min_bit_free_size = bit_c; - } - - size *= 2; - } - enabled_b = 1; + /* allocate our free bit array list */ + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + bit_array[bit_c] = size; + + /* + * Note our minimum number of bits that can store a pointer. This + * is smallest address that we can have a linked list for. + */ + if (min_bit_free_next == 0 && size >= sizeof(void *)) { + min_bit_free_next = bit_c; + } + /* + * Note our minimum number of bits that can store a pointer and + * the size of the block. + */ + if (min_bit_free_size == 0 && size >= sizeof(mpool_free_t)) { + min_bit_free_size = bit_c; + } + + size *= 2; + } + + enabled_b = 1; } /* @@ -130,17 +152,17 @@ static void startup(void) * * size -> Size of memory of which to calculate the number of bits. */ -static int size_to_bits(const unsigned long size) +static int size_to_bits(const unsigned long size) { - int bit_c = 0; + int bit_c = 0; - for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { - if (size <= bit_array[bit_c]) { - break; + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + if (size <= bit_array[bit_c]) { + break; + } } - } - return bit_c; + return bit_c; } /* @@ -158,21 +180,21 @@ static int size_to_bits(const unsigned long size) * * size -> Size of memory of which to calculate the number of bits. */ -static int size_to_free_bits(const unsigned long size) +static int size_to_free_bits(const unsigned long size) { - int bit_c = 0; + int bit_c = 0; - if (size == 0) { - return 0; - } - - for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { - if (size < bit_array[bit_c]) { - break; + if (size == 0) { + return 0; } - } - return bit_c - 1; + for (bit_c = 0; bit_c <= MAX_BITS; bit_c++) { + if (size < bit_array[bit_c]) { + break; + } + } + + return bit_c - 1; } /* @@ -190,14 +212,14 @@ static int size_to_free_bits(const unsigned long size) * * bit_n -> Number of bits */ -static unsigned long bits_to_size(const int bit_n) +static unsigned long bits_to_size(const int bit_n) { - if (bit_n > MAX_BITS) { - return bit_array[MAX_BITS]; - } - else { - return bit_array[bit_n]; - } + if (bit_n > MAX_BITS) { + return bit_array[MAX_BITS]; + } + else { + return bit_array[bit_n]; + } } /* @@ -222,78 +244,58 @@ static unsigned long bits_to_size(const int bit_n) * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, - int *error_p) +static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, + int *error_p) { - void *mem, *fill_mem; - unsigned long size, fill; - int state; + void *mem; + unsigned long size; + int state; - /* are we over our max-pages? */ - if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) { - SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES); - return NULL; - } + /* are we over our max-pages? */ + if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) { + SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES); + return NULL; + } - size = SIZE_OF_PAGES(mp_p, page_n); + size = SIZE_OF_PAGES(mp_p, page_n); #ifdef DEBUG - (void)printf("allocating %u pages or %lu bytes\n", page_n, size); + (void)printf("allocating %u pages or %lu bytes\n", page_n, size); #endif - - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { - mem = sbrk(size); - if (mem == (void *)-1) { - SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); - return NULL; - } - fill = (unsigned long)mem % mp_p->mp_page_size; - - if (fill > 0) { - fill = mp_p->mp_page_size - fill; - fill_mem = sbrk(fill); - if (fill_mem == (void *)-1) { - SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); - return NULL; - } - if ((char *)fill_mem != (char *)mem + size) { - SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG); - return NULL; - } - mem = (char *)mem + fill; - } - } - else { + + state = MAP_PRIVATE; -#ifdef MAP_FILE + +#if defined(MAP_FILE) state |= MAP_FILE; #endif -#ifdef MAP_VARIABLE + +#if defined(MAP_VARIABLE) state |= MAP_VARIABLE; #endif /* mmap from /dev/zero */ - mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state, - mp_p->mp_fd, mp_p->mp_top); + mem = mmap(mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state | mp_p->mp_mmflags, + mp_p->mp_fd, mp_p->mp_top); if (mem == (void *)MAP_FAILED) { - if (errno == ENOMEM) { - SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); - } - else { - SET_POINTER(error_p, MPOOL_ERROR_MMAP); - } - return NULL; + if (errno == ENOMEM) { + SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); + } else { + SET_POINTER(error_p, MPOOL_ERROR_MMAP); + } + return NULL; } + mp_p->mp_top += size; + if (mp_p->mp_addr != NULL) { - mp_p->mp_addr = (char *)mp_p->mp_addr + size; + mp_p->mp_addr = (char *)mp_p->mp_addr + size; } - } - mp_p->mp_page_c += page_n; + mp_p->mp_page_c += page_n; - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return mem; + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return mem; } /* @@ -317,14 +319,11 @@ static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, * * sbrk_b -> Set to one if the pages were allocated with sbrk else mmap. */ -static int free_pages(void *pages, const unsigned long size, - const int sbrk_b) +static int free_pages(void *pages, const unsigned long size) + { - if (! sbrk_b) { - (void)munmap((caddr_t)pages, size); - } - - return MPOOL_ERROR_NONE; + (void)munmap(pages, size); + return MPOOL_ERROR_NONE; } /* @@ -346,19 +345,19 @@ static int free_pages(void *pages, const unsigned long size, * * size -> Size of the block. */ -static int check_magic(const void *addr, const unsigned long size) +static int check_magic(const void *addr, const unsigned long size) { - const unsigned char *mem_p; + const unsigned char *mem_p; - /* set our starting point */ - mem_p = (unsigned char *)addr + size; + /* set our starting point */ + mem_p = (unsigned char *)addr + size; - if (*mem_p == FENCE_MAGIC0 && *(mem_p + 1) == FENCE_MAGIC1) { - return MPOOL_ERROR_NONE; - } - else { - return MPOOL_ERROR_PNT_OVER; - } + if (*mem_p == FENCE_MAGIC0 && *(mem_p + 1) == FENCE_MAGIC1) { + return MPOOL_ERROR_NONE; + } + else { + return MPOOL_ERROR_PNT_OVER; + } } /* @@ -376,10 +375,10 @@ static int check_magic(const void *addr, const unsigned long size) * * addr -> Address where to write the magic. */ -static void write_magic(const void *addr) +static void write_magic(const void *addr) { - *(unsigned char *)addr = FENCE_MAGIC0; - *((unsigned char *)addr + 1) = FENCE_MAGIC1; + *(unsigned char *)addr = FENCE_MAGIC0; + *((unsigned char *)addr + 1) = FENCE_MAGIC1; } /* @@ -404,76 +403,76 @@ static void write_magic(const void *addr) * * size -> Size of the address space. */ -static int free_pointer(mpool_t *mp_p, void *addr, - const unsigned long size) +static int free_pointer(mpool_t *mp_p, void *addr, + const unsigned long size) { - unsigned int bit_n; - unsigned long real_size; - mpool_free_t free_pnt; + unsigned int bit_n; + unsigned long real_size; + mpool_free_t free_pnt; #ifdef DEBUG - (void)printf("freeing a block at %lx of %lu bytes\n", (long)addr, size); + (void)printf("freeing a block at %lx of %lu bytes\n", (long)addr, size); #endif - if (size == 0) { - return MPOOL_ERROR_NONE; - } - - /* - * if the user size is larger then can fit in an entire block then - * we change the size - */ - if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { - real_size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, size)) - - sizeof(mpool_block_t); - } - else { - real_size = size; - } - - /* - * We use a specific free bits calculation here because if we are - * freeing 10 bytes then we will be putting it into the 8-byte free - * list and not the 16 byte list. size_to_bits(10) will return 4 - * instead of 3. - */ - bit_n = size_to_free_bits(real_size); - - /* - * Minimal error checking. We could go all the way through the - * list however this might be prohibitive. - */ - if (mp_p->mp_free[bit_n] == addr) { - return MPOOL_ERROR_IS_FREE; - } - - /* add the freed pointer to the free list */ - if (bit_n < min_bit_free_next) { - /* - * Yes we know this will lose 99% of the allocations but what else - * can we do? No space for a next pointer. - */ - if (mp_p->mp_free[bit_n] == NULL) { - mp_p->mp_free[bit_n] = addr; + if (size == 0) { + return MPOOL_ERROR_NONE; } - } - else if (bit_n < min_bit_free_size) { - /* we copy, not assign, to maintain the free list */ - memcpy(addr, mp_p->mp_free + bit_n, sizeof(void *)); - mp_p->mp_free[bit_n] = addr; - } - else { - - /* setup our free list structure */ - free_pnt.mf_next_p = mp_p->mp_free[bit_n]; - free_pnt.mf_size = real_size; - - /* we copy the structure in since we don't know about alignment */ - memcpy(addr, &free_pnt, sizeof(free_pnt)); - mp_p->mp_free[bit_n] = addr; - } - return MPOOL_ERROR_NONE; + /* + * if the user size is larger then can fit in an entire block then + * we change the size + */ + if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { + real_size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, size)) - + sizeof(mpool_block_t); + } + else { + real_size = size; + } + + /* + * We use a specific free bits calculation here because if we are + * freeing 10 bytes then we will be putting it into the 8-byte free + * list and not the 16 byte list. size_to_bits(10) will return 4 + * instead of 3. + */ + bit_n = size_to_free_bits(real_size); + + /* + * Minimal error checking. We could go all the way through the + * list however this might be prohibitive. + */ + if (mp_p->mp_free[bit_n] == addr) { + return MPOOL_ERROR_IS_FREE; + } + + /* add the freed pointer to the free list */ + if (bit_n < min_bit_free_next) { + /* + * Yes we know this will lose 99% of the allocations but what else + * can we do? No space for a next pointer. + */ + if (mp_p->mp_free[bit_n] == NULL) { + mp_p->mp_free[bit_n] = addr; + } + } + else if (bit_n < min_bit_free_size) { + /* we copy, not assign, to maintain the free list */ + memcpy(addr, mp_p->mp_free + bit_n, sizeof(void *)); + mp_p->mp_free[bit_n] = addr; + } + else { + + /* setup our free list structure */ + free_pnt.mf_next_p = mp_p->mp_free[bit_n]; + free_pnt.mf_size = real_size; + + /* we copy the structure in since we don't know about alignment */ + memcpy(addr, &free_pnt, sizeof(free_pnt)); + mp_p->mp_free[bit_n] = addr; + } + + return MPOOL_ERROR_NONE; } /* @@ -498,60 +497,60 @@ static int free_pointer(mpool_t *mp_p, void *addr, * * size -> Size of the space that we are taking from address. */ -static int split_block(mpool_t *mp_p, void *free_addr, - const unsigned long size) +static int split_block(mpool_t *mp_p, void *free_addr, + const unsigned long size) { - mpool_block_t *block_p, *new_block_p; - int ret, page_n; - void *end_p; + mpool_block_t *block_p, *new_block_p; + int ret, page_n; + void *end_p; - /* - * 1st we find the block pointer from our free addr. At this point - * the pointer must be the 1st one in the block if it is spans - * multiple blocks. - */ - block_p = (mpool_block_t *)((char *)free_addr - sizeof(mpool_block_t)); - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - page_n = PAGES_IN_SIZE(mp_p, size); - - /* we are creating a new block structure for the 2nd ... */ - new_block_p = (mpool_block_t *)((char *)block_p + - SIZE_OF_PAGES(mp_p, page_n)); - new_block_p->mb_magic = BLOCK_MAGIC; - /* New bounds is 1st block bounds. The 1st block's is reset below. */ - new_block_p->mb_bounds_p = block_p->mb_bounds_p; - /* Continue the linked list. The 1st block will point to us below. */ - new_block_p->mb_next_p = block_p->mb_next_p; - new_block_p->mb_magic2 = BLOCK_MAGIC; - - /* bounds for the 1st block are reset to the 1st page only */ - block_p->mb_bounds_p = (char *)new_block_p; - /* the next block pointer for the 1st block is now the new one */ - block_p->mb_next_p = new_block_p; - - /* only free the space in the 1st block if it is only 1 block in size */ - if (page_n == 1) { - /* now free the rest of the 1st block block */ - end_p = (char *)free_addr + size; - ret = free_pointer(mp_p, end_p, - (char *)block_p->mb_bounds_p - (char *)end_p); - if (ret != MPOOL_ERROR_NONE) { - return ret; + /* + * 1st we find the block pointer from our free addr. At this point + * the pointer must be the 1st one in the block if it is spans + * multiple blocks. + */ + block_p = (mpool_block_t *)((char *)free_addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + return MPOOL_ERROR_POOL_OVER; } - } - /* now free the rest of the block */ - ret = free_pointer(mp_p, FIRST_ADDR_IN_BLOCK(new_block_p), - MEMORY_IN_BLOCK(new_block_p)); - if (ret != MPOOL_ERROR_NONE) { - return ret; - } + page_n = PAGES_IN_SIZE(mp_p, size); - return MPOOL_ERROR_NONE; + /* we are creating a new block structure for the 2nd ... */ + new_block_p = (mpool_block_t *)((char *)block_p + + SIZE_OF_PAGES(mp_p, page_n)); + new_block_p->mb_magic = BLOCK_MAGIC; + /* New bounds is 1st block bounds. The 1st block's is reset below. */ + new_block_p->mb_bounds_p = block_p->mb_bounds_p; + /* Continue the linked list. The 1st block will point to us below. */ + new_block_p->mb_next_p = block_p->mb_next_p; + new_block_p->mb_magic2 = BLOCK_MAGIC; + + /* bounds for the 1st block are reset to the 1st page only */ + block_p->mb_bounds_p = (char *)new_block_p; + /* the next block pointer for the 1st block is now the new one */ + block_p->mb_next_p = new_block_p; + + /* only free the space in the 1st block if it is only 1 block in size */ + if (page_n == 1) { + /* now free the rest of the 1st block block */ + end_p = (char *)free_addr + size; + ret = free_pointer(mp_p, end_p, + (char *)block_p->mb_bounds_p - (char *)end_p); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + } + + /* now free the rest of the block */ + ret = free_pointer(mp_p, FIRST_ADDR_IN_BLOCK(new_block_p), + MEMORY_IN_BLOCK(new_block_p)); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + + return MPOOL_ERROR_NONE; } /* @@ -576,146 +575,146 @@ static int split_block(mpool_t *mp_p, void *free_addr, * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -static void *get_space(mpool_t *mp_p, const unsigned long byte_size, - int *error_p) +static void *get_space(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) { - mpool_block_t *block_p; - mpool_free_t free_pnt; - int ret; - unsigned long size; - unsigned int bit_c, page_n, left; - void *free_addr = NULL, *free_end; + mpool_block_t *block_p; + mpool_free_t free_pnt; + int ret; + unsigned long size; + unsigned int bit_c, page_n, left; + void *free_addr = NULL, *free_end; - size = byte_size; - while ((size & (sizeof(void *) - 1)) > 0) { - size++; - } - - /* - * First we check the free lists looking for something with enough - * pages. Maybe we should only look X bits higher in the list. - * - * XXX: this is where we'd do the best fit. We'd look for the - * closest match. We then could put the rest of the allocation that - * we did not use in a lower free list. Have a define which states - * how deep in the free list to go to find the closest match. - */ - for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) { - if (mp_p->mp_free[bit_c] != NULL) { - free_addr = mp_p->mp_free[bit_c]; - break; + size = byte_size; + while ((size & (sizeof(void *) - 1)) > 0) { + size++; } - } - /* - * If we haven't allocated any blocks or if the last block doesn't - * have enough memory then we need a new block. - */ - if (bit_c > MAX_BITS) { - - /* we need to allocate more space */ - - page_n = PAGES_IN_SIZE(mp_p, size); - - /* now we try and get the pages we need/want */ - block_p = alloc_pages(mp_p, page_n, error_p); - if (block_p == NULL) { - /* error_p set in alloc_pages */ - return NULL; - } - - /* init the block header */ - block_p->mb_magic = BLOCK_MAGIC; - block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n); - block_p->mb_next_p = mp_p->mp_first_p; - block_p->mb_magic2 = BLOCK_MAGIC; - /* - * We insert it into the front of the queue. We could add it to - * the end but there is not much use. + * First we check the free lists looking for something with enough + * pages. Maybe we should only look X bits higher in the list. + * + * XXX: this is where we'd do the best fit. We'd look for the + * closest match. We then could put the rest of the allocation that + * we did not use in a lower free list. Have a define which states + * how deep in the free list to go to find the closest match. */ - mp_p->mp_first_p = block_p; - if (mp_p->mp_last_p == NULL) { - mp_p->mp_last_p = block_p; + for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) { + if (mp_p->mp_free[bit_c] != NULL) { + free_addr = mp_p->mp_free[bit_c]; + break; + } } + + /* + * If we haven't allocated any blocks or if the last block doesn't + * have enough memory then we need a new block. + */ + if (bit_c > MAX_BITS) { - free_addr = FIRST_ADDR_IN_BLOCK(block_p); + /* we need to allocate more space */ + + page_n = PAGES_IN_SIZE(mp_p, size); + + /* now we try and get the pages we need/want */ + block_p = alloc_pages(mp_p, page_n, error_p); + if (block_p == NULL) { + /* error_p set in alloc_pages */ + return NULL; + } + + /* init the block header */ + block_p->mb_magic = BLOCK_MAGIC; + block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n); + block_p->mb_next_p = mp_p->mp_first_p; + block_p->mb_magic2 = BLOCK_MAGIC; + + /* + * We insert it into the front of the queue. We could add it to + * the end but there is not much use. + */ + mp_p->mp_first_p = block_p; + if (mp_p->mp_last_p == NULL) { + mp_p->mp_last_p = block_p; + } + + free_addr = FIRST_ADDR_IN_BLOCK(block_p); #ifdef DEBUG - (void)printf("had to allocate space for %lx of %lu bytes\n", - (long)free_addr, size); + (void)printf("had to allocate space for %lx of %lu bytes\n", + (long)free_addr, size); #endif - free_end = (char *)free_addr + size; - left = (char *)block_p->mb_bounds_p - (char *)free_end; - } - else { - - if (bit_c < min_bit_free_next) { - mp_p->mp_free[bit_c] = NULL; - /* calculate the number of left over bytes */ - left = bits_to_size(bit_c) - size; - } - else if (bit_c < min_bit_free_next) { - /* grab the next pointer from the freed address into our list */ - memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *)); - /* calculate the number of left over bytes */ - left = bits_to_size(bit_c) - size; + free_end = (char *)free_addr + size; + left = (char *)block_p->mb_bounds_p - (char *)free_end; } else { - /* grab the free structure from the address */ - memcpy(&free_pnt, free_addr, sizeof(free_pnt)); - mp_p->mp_free[bit_c] = free_pnt.mf_next_p; + + if (bit_c < min_bit_free_next) { + mp_p->mp_free[bit_c] = NULL; + /* calculate the number of left over bytes */ + left = bits_to_size(bit_c) - size; + } + else if (bit_c < min_bit_free_next) { + /* grab the next pointer from the freed address into our list */ + memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *)); + /* calculate the number of left over bytes */ + left = bits_to_size(bit_c) - size; + } + else { + /* grab the free structure from the address */ + memcpy(&free_pnt, free_addr, sizeof(free_pnt)); + mp_p->mp_free[bit_c] = free_pnt.mf_next_p; - /* are we are splitting up a multiblock chunk into fewer blocks? */ - if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) { - ret = split_block(mp_p, free_addr, size); - if (ret != MPOOL_ERROR_NONE) { - SET_POINTER(error_p, ret); - return NULL; - } - /* left over memory was taken care of in split_block */ - left = 0; - } - else { - /* calculate the number of left over bytes */ - left = free_pnt.mf_size - size; - } - } + /* are we are splitting up a multiblock chunk into fewer blocks? */ + if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) { + ret = split_block(mp_p, free_addr, size); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + /* left over memory was taken care of in split_block */ + left = 0; + } + else { + /* calculate the number of left over bytes */ + left = free_pnt.mf_size - size; + } + } #ifdef DEBUG - (void)printf("found a free block at %lx of %lu bytes\n", - (long)free_addr, left + size); + (void)printf("found a free block at %lx of %lu bytes\n", + (long)free_addr, left + size); #endif - free_end = (char *)free_addr + size; - } - - /* - * If we have memory left over then we free it so someone else can - * use it. We do not free the space if we just allocated a - * multi-block chunk because we need to have every allocation easily - * find the start of the block. Every user address % page-size - * should take us to the start of the block. - */ - if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) { - /* free the rest of the block */ - ret = free_pointer(mp_p, free_end, left); - if (ret != MPOOL_ERROR_NONE) { - SET_POINTER(error_p, ret); - return NULL; + free_end = (char *)free_addr + size; } - } - /* update our bounds */ - if (free_addr > mp_p->mp_bounds_p) { - mp_p->mp_bounds_p = free_addr; - } - else if (free_addr < mp_p->mp_min_p) { - mp_p->mp_min_p = free_addr; - } + /* + * If we have memory left over then we free it so someone else can + * use it. We do not free the space if we just allocated a + * multi-block chunk because we need to have every allocation easily + * find the start of the block. Every user address % page-size + * should take us to the start of the block. + */ + if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) { + /* free the rest of the block */ + ret = free_pointer(mp_p, free_end, left); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + } - return free_addr; + /* update our bounds */ + if (free_addr > mp_p->mp_bounds_p) { + mp_p->mp_bounds_p = free_addr; + } + else if (free_addr < mp_p->mp_min_p) { + mp_p->mp_min_p = free_addr; + } + + return free_addr; } /* @@ -741,47 +740,47 @@ static void *get_space(mpool_t *mp_p, const unsigned long byte_size, * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, - int *error_p) +static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) { - unsigned long size, fence; - void *addr; + unsigned long size, fence; + void *addr; - /* make sure we have enough bytes */ - if (byte_size < MIN_ALLOCATION) { - size = MIN_ALLOCATION; - } - else { - size = byte_size; - } + /* make sure we have enough bytes */ + if (byte_size < MIN_ALLOCATION) { + size = MIN_ALLOCATION; + } + else { + size = byte_size; + } - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - fence = 0; - } - else { - fence = FENCE_SIZE; - } + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else { + fence = FENCE_SIZE; + } - /* get our free space + the space for the fence post */ - addr = get_space(mp_p, size + fence, error_p); - if (addr == NULL) { - /* error_p set in get_space */ - return NULL; - } + /* get our free space + the space for the fence post */ + addr = get_space(mp_p, size + fence, error_p); + if (addr == NULL) { + /* error_p set in get_space */ + return NULL; + } - if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - write_magic((char *)addr + size); - } + if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + write_magic((char *)addr + size); + } - /* maintain our stats */ - mp_p->mp_alloc_c++; - mp_p->mp_user_alloc += size; - if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) { - mp_p->mp_max_alloc = mp_p->mp_user_alloc; - } + /* maintain our stats */ + mp_p->mp_alloc_c++; + mp_p->mp_user_alloc += size; + if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) { + mp_p->mp_max_alloc = mp_p->mp_user_alloc; + } - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return addr; + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; } /* @@ -806,56 +805,56 @@ static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, * * size -> Size of the address being freed. */ -static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) +static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) { - unsigned long old_size, fence; - int ret; - mpool_block_t *block_p; + unsigned long old_size, fence; + int ret; + mpool_block_t *block_p; - /* - * If the size is larger than a block then the allocation must be at - * the front of the block. - */ - if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { - block_p = (mpool_block_t *)((char *)addr - sizeof(mpool_block_t)); - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - return MPOOL_ERROR_POOL_OVER; + /* + * If the size is larger than a block then the allocation must be at + * the front of the block. + */ + if (size > MAX_BLOCK_USER_MEMORY(mp_p)) { + block_p = (mpool_block_t *)((char *)addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } } - } - /* make sure we have enough bytes */ - if (size < MIN_ALLOCATION) { - old_size = MIN_ALLOCATION; - } - else { - old_size = size; - } - - /* if we are packing the pool smaller */ - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - fence = 0; - } - else { - /* find the user's magic numbers if they were written */ - ret = check_magic(addr, old_size); - if (ret != MPOOL_ERROR_NONE) { - return ret; + /* make sure we have enough bytes */ + if (size < MIN_ALLOCATION) { + old_size = MIN_ALLOCATION; + } + else { + old_size = size; } - fence = FENCE_SIZE; - } - /* now we free the pointer */ - ret = free_pointer(mp_p, addr, old_size + fence); - if (ret != MPOOL_ERROR_NONE) { - return ret; - } - mp_p->mp_user_alloc -= old_size; + /* if we are packing the pool smaller */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else { + /* find the user's magic numbers if they were written */ + ret = check_magic(addr, old_size); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + fence = FENCE_SIZE; + } - /* adjust our stats */ - mp_p->mp_alloc_c--; + /* now we free the pointer */ + ret = free_pointer(mp_p, addr, old_size + fence); + if (ret != MPOOL_ERROR_NONE) { + return ret; + } + mp_p->mp_user_alloc -= old_size; - return MPOOL_ERROR_NONE; + /* adjust our stats */ + mp_p->mp_alloc_c--; + + return MPOOL_ERROR_NONE; } /***************************** exported routines *****************************/ @@ -883,153 +882,153 @@ static int free_mem(mpool_t *mp_p, void *addr, const unsigned long size) * multiple of the getpagesize() value. Set to 0 for the default. * * start_addr -> Starting address to try and allocate memory pools. - * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, - void *start_addr, int *error_p) +KS_DECLARE(mpool_t *) mpool_open(const unsigned int flags, const unsigned int page_size, + void *start_addr, int *error_p) { - mpool_block_t *block_p; - int page_n, ret; - mpool_t mp, *mp_p; - void *free_addr; + mpool_block_t *block_p; + int page_n, ret; + mpool_t mp, *mp_p; + void *free_addr; - if (! enabled_b) { - startup(); - } - - /* zero our temp struct */ - memset(&mp, 0, sizeof(mp)); - - mp.mp_magic = MPOOL_MAGIC; - mp.mp_flags = flags; - mp.mp_alloc_c = 0; - mp.mp_user_alloc = 0; - mp.mp_max_alloc = 0; - mp.mp_page_c = 0; - /* mp.mp_page_size set below */ - /* mp.mp_blocks_bit_n set below */ - /* mp.mp_fd set below */ - /* mp.mp_top set below */ - /* mp.mp_addr set below */ - mp.mp_log_func = NULL; - mp.mp_min_p = NULL; - mp.mp_bounds_p = NULL; - mp.mp_first_p = NULL; - mp.mp_last_p = NULL; - mp.mp_magic2 = MPOOL_MAGIC; - - /* get and sanity check our page size */ - if (page_size > 0) { - mp.mp_page_size = page_size; - if (mp.mp_page_size % getpagesize() != 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; + if (! enabled_b) { + startup(); } - } - else { - mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT; - if (mp.mp_page_size % 1024 != 0) { - SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE); - return NULL; - } - } - if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) { - mp.mp_fd = -1; - mp.mp_addr = NULL; - mp.mp_top = 0; - } - else { - /* open dev-zero for our mmaping */ - mp.mp_fd = open("/dev/zero", O_RDWR, 0); - if (mp.mp_fd < 0) { - SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO); - return NULL; + /* zero our temp struct */ + memset(&mp, 0, sizeof(mp)); + + mp.mp_magic = MPOOL_MAGIC; + mp.mp_flags = flags; + mp.mp_alloc_c = 0; + mp.mp_user_alloc = 0; + mp.mp_max_alloc = 0; + mp.mp_page_c = 0; + /* mp.mp_page_size set below */ + /* mp.mp_blocks_bit_n set below */ + /* mp.mp_fd set below */ + /* mp.mp_top set below */ + /* mp.mp_addr set below */ + mp.mp_log_func = NULL; + mp.mp_min_p = NULL; + mp.mp_bounds_p = NULL; + mp.mp_first_p = NULL; + mp.mp_last_p = NULL; + mp.mp_magic2 = MPOOL_MAGIC; + + /* get and sanity check our page size */ + if (page_size > 0) { + mp.mp_page_size = page_size; + if (mp.mp_page_size % getpagesize() != 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + } + else { + mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT; + if (mp.mp_page_size % 1024 != 0) { + SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE); + return NULL; + } + } + + mp.mp_mmflags = 0; + + if (BIT_IS_SET(flags, MPOOL_FLAG_ANONYMOUS)) { + mp.mp_fd = -1; + mp.mp_mmflags |= MAP_ANON; + } else { + /* open dev-zero for our mmaping */ + mp.mp_fd = open("/dev/zero", O_RDWR, 0); + if (mp.mp_fd < 0) { + SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO); + return NULL; + } } mp.mp_addr = start_addr; /* we start at the front of the file */ mp.mp_top = 0; - } + - /* - * Find out how many pages we need for our mpool structure. - * - * NOTE: this adds possibly unneeded space for mpool_block_t which - * may not be in this block. - */ - page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t)); - - /* now allocate us space for the actual struct */ - mp_p = alloc_pages(&mp, page_n, error_p); - if (mp_p == NULL) { - if (mp.mp_fd >= 0) { - (void)close(mp.mp_fd); - mp.mp_fd = -1; - } - return NULL; - } - - /* - * NOTE: we do not normally free the rest of the block here because - * we want to lesson the chance of an allocation overwriting the - * main structure. - */ - if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) { - - /* we add a block header to the front of the block */ - block_p = (mpool_block_t *)mp_p; - - /* init the block header */ - block_p->mb_magic = BLOCK_MAGIC; - block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n); - block_p->mb_next_p = NULL; - block_p->mb_magic2 = BLOCK_MAGIC; - - /* the mpool pointer is then the 2nd thing in the block */ - mp_p = FIRST_ADDR_IN_BLOCK(block_p); - free_addr = (char *)mp_p + sizeof(mpool_t); - - /* free the rest of the block */ - ret = free_pointer(&mp, free_addr, - (char *)block_p->mb_bounds_p - (char *)free_addr); - if (ret != MPOOL_ERROR_NONE) { - if (mp.mp_fd >= 0) { - (void)close(mp.mp_fd); - mp.mp_fd = -1; - } - /* NOTE: after this line mp_p will be invalid */ - (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n), - BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)); - SET_POINTER(error_p, ret); - return NULL; - } - /* - * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool - * header is not on the block linked list. + * Find out how many pages we need for our mpool structure. + * + * NOTE: this adds possibly unneeded space for mpool_block_t which + * may not be in this block. */ - - /* now copy our tmp structure into our new memory area */ - memcpy(mp_p, &mp, sizeof(mpool_t)); - - /* we setup min/max to our current address which is as good as any */ - mp_p->mp_min_p = block_p; - mp_p->mp_bounds_p = block_p->mb_bounds_p; - } - else { - /* now copy our tmp structure into our new memory area */ - memcpy(mp_p, &mp, sizeof(mpool_t)); - - /* we setup min/max to our current address which is as good as any */ - mp_p->mp_min_p = mp_p; - mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n); - } + page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t)); - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return mp_p; + /* now allocate us space for the actual struct */ + mp_p = alloc_pages(&mp, page_n, error_p); + if (mp_p == NULL) { + if (mp.mp_fd >= 0) { + (void)close(mp.mp_fd); + mp.mp_fd = -1; + } + return NULL; + } + + /* + * NOTE: we do not normally free the rest of the block here because + * we want to lesson the chance of an allocation overwriting the + * main structure. + */ + if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) { + + /* we add a block header to the front of the block */ + block_p = (mpool_block_t *)mp_p; + + /* init the block header */ + block_p->mb_magic = BLOCK_MAGIC; + block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n); + block_p->mb_next_p = NULL; + block_p->mb_magic2 = BLOCK_MAGIC; + + /* the mpool pointer is then the 2nd thing in the block */ + mp_p = FIRST_ADDR_IN_BLOCK(block_p); + free_addr = (char *)mp_p + sizeof(mpool_t); + + /* free the rest of the block */ + ret = free_pointer(&mp, free_addr, + (char *)block_p->mb_bounds_p - (char *)free_addr); + if (ret != MPOOL_ERROR_NONE) { + if (mp.mp_fd >= 0) { + (void)close(mp.mp_fd); + mp.mp_fd = -1; + } + /* NOTE: after this line mp_p will be invalid */ + (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n)); + + SET_POINTER(error_p, ret); + return NULL; + } + + /* + * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool + * header is not on the block linked list. + */ + + /* now copy our tmp structure into our new memory area */ + memcpy(mp_p, &mp, sizeof(mpool_t)); + + /* we setup min/max to our current address which is as good as any */ + mp_p->mp_min_p = block_p; + mp_p->mp_bounds_p = block_p->mb_bounds_p; + } + else { + /* now copy our tmp structure into our new memory area */ + memcpy(mp_p, &mp, sizeof(mpool_t)); + + /* we setup min/max to our current address which is as good as any */ + mp_p->mp_min_p = mp_p; + mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n); + } + + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return mp_p; } /* @@ -1050,77 +1049,74 @@ mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, * * mp_p <-> Pointer to our memory pool. */ -int mpool_close(mpool_t *mp_p) +KS_DECLARE(int) mpool_close(mpool_t *mp_p) { - mpool_block_t *block_p, *next_p; - void *addr; - unsigned long size; - int ret, final = MPOOL_ERROR_NONE; + mpool_block_t *block_p, *next_p; + void *addr; + unsigned long size; + int ret, final = MPOOL_ERROR_NONE; - /* special case, just return no-error */ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLOSE, 0, 0, NULL, NULL, 0); - } - - /* - * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool - * header is not on the linked list. - */ - - /* free/invalidate the blocks */ - for (block_p = mp_p->mp_first_p; block_p != NULL; block_p = next_p) { - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - final = MPOOL_ERROR_POOL_OVER; - break; + /* special case, just return no-error */ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; } - block_p->mb_magic = 0; - block_p->mb_magic2 = 0; - /* record the next pointer because it might be invalidated below */ - next_p = block_p->mb_next_p; - ret = free_pages(block_p, (char *)block_p->mb_bounds_p - (char *)block_p, - BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)); - if (ret != MPOOL_ERROR_NONE) { - final = ret; + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; } - } - /* close /dev/zero if necessary */ - if (mp_p->mp_fd >= 0) { - (void)close(mp_p->mp_fd); - mp_p->mp_fd = -1; - } + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLOSE, 0, 0, NULL, NULL, 0); + } - /* invalidate the mpool before we ditch it */ - mp_p->mp_magic = 0; - mp_p->mp_magic2 = 0; + /* + * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool + * header is not on the linked list. + */ + + /* free/invalidate the blocks */ + for (block_p = mp_p->mp_first_p; block_p != NULL; block_p = next_p) { + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + final = MPOOL_ERROR_POOL_OVER; + break; + } + block_p->mb_magic = 0; + block_p->mb_magic2 = 0; + /* record the next pointer because it might be invalidated below */ + next_p = block_p->mb_next_p; + ret = free_pages(block_p, (char *)block_p->mb_bounds_p - (char *)block_p); + + if (ret != MPOOL_ERROR_NONE) { + final = ret; + } + } + + /* close /dev/zero if necessary */ + if (mp_p->mp_fd >= 0) { + (void)close(mp_p->mp_fd); + mp_p->mp_fd = -1; + } + + /* invalidate the mpool before we ditch it */ + mp_p->mp_magic = 0; + mp_p->mp_magic2 = 0; - /* last we munmap the mpool pointer itself */ - if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { - /* if we are heavy packing then we need to free the 1st block later */ if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { - addr = (char *)mp_p - sizeof(mpool_block_t); + addr = (char *)mp_p - sizeof(mpool_block_t); } else { - addr = mp_p; + addr = mp_p; } size = SIZE_OF_PAGES(mp_p, PAGES_IN_SIZE(mp_p, sizeof(mpool_t))); + + (void)munmap(addr, size); - (void)munmap((caddr_t)addr, size); - } - return final; + return final; } /* @@ -1140,52 +1136,52 @@ int mpool_close(mpool_t *mp_p) * * mp_p <-> Pointer to our memory pool. */ -int mpool_clear(mpool_t *mp_p) +KS_DECLARE(int) mpool_clear(mpool_t *mp_p) { - mpool_block_t *block_p; - int final = MPOOL_ERROR_NONE, bit_n, ret; - void *first_p; + mpool_block_t *block_p; + int final = MPOOL_ERROR_NONE, bit_n, ret; + void *first_p; - /* special case, just return no-error */ - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLEAR, 0, 0, NULL, NULL, 0); - } - - /* reset all of our free lists */ - for (bit_n = 0; bit_n <= MAX_BITS; bit_n++) { - mp_p->mp_free[bit_n] = NULL; - } - - /* free the blocks */ - for (block_p = mp_p->mp_first_p; - block_p != NULL; - block_p = block_p->mb_next_p) { - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - final = MPOOL_ERROR_POOL_OVER; - break; + /* special case, just return no-error */ + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; } - - first_p = FIRST_ADDR_IN_BLOCK(block_p); - - /* free the memory */ - ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p)); - if (ret != MPOOL_ERROR_NONE) { - final = ret; + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; } - } - return final; + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CLEAR, 0, 0, NULL, NULL, 0); + } + + /* reset all of our free lists */ + for (bit_n = 0; bit_n <= MAX_BITS; bit_n++) { + mp_p->mp_free[bit_n] = NULL; + } + + /* free the blocks */ + for (block_p = mp_p->mp_first_p; + block_p != NULL; + block_p = block_p->mb_next_p) { + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + final = MPOOL_ERROR_POOL_OVER; + break; + } + + first_p = FIRST_ADDR_IN_BLOCK(block_p); + + /* free the memory */ + ret = free_pointer(mp_p, first_p, MEMORY_IN_BLOCK(block_p)); + if (ret != MPOOL_ERROR_NONE) { + final = ret; + } + } + + return final; } /* @@ -1211,45 +1207,45 @@ int mpool_clear(mpool_t *mp_p) * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, - int *error_p) +KS_DECLARE(void *) mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, + int *error_p) { - void *addr; + void *addr; - if (mp_p == NULL) { - /* special case -- do a normal malloc */ - addr = (void *)malloc(byte_size); - if (addr == NULL) { - SET_POINTER(error_p, MPOOL_ERROR_ALLOC); - return NULL; + if (mp_p == NULL) { + /* special case -- do a normal malloc */ + addr = (void *)malloc(byte_size); + if (addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ALLOC); + return NULL; + } + else { + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; + } } - else { - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return addr; + + if (mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; } - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_PNT); - return NULL; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } + if (byte_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } - if (byte_size == 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } + addr = alloc_mem(mp_p, byte_size, error_p); - addr = alloc_mem(mp_p, byte_size, error_p); + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, addr, NULL, 0); + } - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_ALLOC, byte_size, 0, addr, NULL, 0); - } - - return addr; + return addr; } /* @@ -1278,51 +1274,51 @@ void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size, * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, - const unsigned long ele_size, int *error_p) +KS_DECLARE(void *) mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, + const unsigned long ele_size, int *error_p) { - void *addr; - unsigned long byte_size; + void *addr; + unsigned long byte_size; - if (mp_p == NULL) { - /* special case -- do a normal calloc */ - addr = (void *)calloc(ele_n, ele_size); - if (addr == NULL) { - SET_POINTER(error_p, MPOOL_ERROR_ALLOC); - return NULL; - } - else { - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return addr; - } + if (mp_p == NULL) { + /* special case -- do a normal calloc */ + addr = (void *)calloc(ele_n, ele_size); + if (addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ALLOC); + return NULL; + } + else { + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return addr; + } - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_PNT); - return NULL; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } - if (ele_n == 0 || ele_size == 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } + if (ele_n == 0 || ele_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } - byte_size = ele_n * ele_size; - addr = alloc_mem(mp_p, byte_size, error_p); - if (addr != NULL) { - memset(addr, 0, byte_size); - } + byte_size = ele_n * ele_size; + addr = alloc_mem(mp_p, byte_size, error_p); + if (addr != NULL) { + memset(addr, 0, byte_size); + } - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, addr, NULL, 0); - } + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_CALLOC, ele_size, ele_n, addr, NULL, 0); + } - /* NOTE: error_p set above */ - return addr; + /* NOTE: error_p set above */ + return addr; } /* @@ -1347,32 +1343,32 @@ void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n, * * size -> Size of the address being freed. */ -int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size) +KS_DECLARE(int) mpool_free(mpool_t *mp_p, void *addr, const unsigned long size) { - if (mp_p == NULL) { - /* special case -- do a normal free */ - free(addr); - return MPOOL_ERROR_NONE; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } + if (mp_p == NULL) { + /* special case -- do a normal free */ + free(addr); + return MPOOL_ERROR_NONE; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, size, 0, NULL, addr, 0); - } + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_FREE, size, 0, NULL, addr, 0); + } - if (addr == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (size == 0) { - return MPOOL_ERROR_ARG_INVALID; - } + if (addr == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (size == 0) { + return MPOOL_ERROR_ARG_INVALID; + } - return free_mem(mp_p, addr, size); + return free_mem(mp_p, addr, size); } /* @@ -1406,127 +1402,127 @@ int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size) * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ -void *mpool_resize(mpool_t *mp_p, void *old_addr, - const unsigned long old_byte_size, - const unsigned long new_byte_size, - int *error_p) +KS_DECLARE(void *) mpool_resize(mpool_t *mp_p, void *old_addr, + const unsigned long old_byte_size, + const unsigned long new_byte_size, + int *error_p) { - unsigned long copy_size, new_size, old_size, fence; - void *new_addr; - mpool_block_t *block_p; - int ret; + unsigned long copy_size, new_size, old_size, fence; + void *new_addr; + mpool_block_t *block_p; + int ret; - if (mp_p == NULL) { - /* special case -- do a normal realloc */ - new_addr = (void *)realloc(old_addr, new_byte_size); - if (new_addr == NULL) { - SET_POINTER(error_p, MPOOL_ERROR_ALLOC); - return NULL; - } + if (mp_p == NULL) { + /* special case -- do a normal realloc */ + new_addr = (void *)realloc(old_addr, new_byte_size); + if (new_addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ALLOC); + return NULL; + } + else { + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return new_addr; + } + } + + if (mp_p->mp_magic != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_PNT); + return NULL; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + + if (old_addr == NULL) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL); + return NULL; + } + if (old_byte_size == 0) { + SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); + return NULL; + } + + /* + * If the size is larger than a block then the allocation must be at + * the front of the block. + */ + if (old_byte_size > MAX_BLOCK_USER_MEMORY(mp_p)) { + block_p = (mpool_block_t *)((char *)old_addr - sizeof(mpool_block_t)); + if (block_p->mb_magic != BLOCK_MAGIC + || block_p->mb_magic2 != BLOCK_MAGIC) { + SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); + return NULL; + } + } + + /* make sure we have enough bytes */ + if (old_byte_size < MIN_ALLOCATION) { + old_size = MIN_ALLOCATION; + } else { - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return new_addr; + old_size = old_byte_size; } - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_PNT); - return NULL; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; - } - - if (old_addr == NULL) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_NULL); - return NULL; - } - if (old_byte_size == 0) { - SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); - return NULL; - } - - /* - * If the size is larger than a block then the allocation must be at - * the front of the block. - */ - if (old_byte_size > MAX_BLOCK_USER_MEMORY(mp_p)) { - block_p = (mpool_block_t *)((char *)old_addr - sizeof(mpool_block_t)); - if (block_p->mb_magic != BLOCK_MAGIC - || block_p->mb_magic2 != BLOCK_MAGIC) { - SET_POINTER(error_p, MPOOL_ERROR_POOL_OVER); - return NULL; + /* verify that the size matches exactly if we can */ + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { + fence = 0; + } + else if (old_size > 0) { + ret = check_magic(old_addr, old_size); + if (ret != MPOOL_ERROR_NONE) { + SET_POINTER(error_p, ret); + return NULL; + } + fence = FENCE_SIZE; } - } - /* make sure we have enough bytes */ - if (old_byte_size < MIN_ALLOCATION) { - old_size = MIN_ALLOCATION; - } - else { - old_size = old_byte_size; - } + /* make sure we have enough bytes */ + if (new_byte_size < MIN_ALLOCATION) { + new_size = MIN_ALLOCATION; + } + else { + new_size = new_byte_size; + } - /* verify that the size matches exactly if we can */ - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { - fence = 0; - } - else if (old_size > 0) { - ret = check_magic(old_addr, old_size); + /* + * NOTE: we could here see if the size is the same or less and then + * use the current memory and free the space above. This is harder + * than it sounds if we are changing the block size of the + * allocation. + */ + + /* we need to get another address */ + new_addr = alloc_mem(mp_p, new_byte_size, error_p); + if (new_addr == NULL) { + /* error_p set in mpool_alloc */ + return NULL; + } + + if (new_byte_size > old_byte_size) { + copy_size = old_byte_size; + } + else { + copy_size = new_byte_size; + } + memcpy(new_addr, old_addr, copy_size); + + /* free the old address */ + ret = free_mem(mp_p, old_addr, old_byte_size); if (ret != MPOOL_ERROR_NONE) { - SET_POINTER(error_p, ret); - return NULL; + /* if the old free failed, try and free the new address */ + (void)free_mem(mp_p, new_addr, new_byte_size); + SET_POINTER(error_p, ret); + return NULL; } - fence = FENCE_SIZE; - } - /* make sure we have enough bytes */ - if (new_byte_size < MIN_ALLOCATION) { - new_size = MIN_ALLOCATION; - } - else { - new_size = new_byte_size; - } + if (mp_p->mp_log_func != NULL) { + mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size, + 0, new_addr, old_addr, old_byte_size); + } - /* - * NOTE: we could here see if the size is the same or less and then - * use the current memory and free the space above. This is harder - * than it sounds if we are changing the block size of the - * allocation. - */ - - /* we need to get another address */ - new_addr = alloc_mem(mp_p, new_byte_size, error_p); - if (new_addr == NULL) { - /* error_p set in mpool_alloc */ - return NULL; - } - - if (new_byte_size > old_byte_size) { - copy_size = old_byte_size; - } - else { - copy_size = new_byte_size; - } - memcpy(new_addr, old_addr, copy_size); - - /* free the old address */ - ret = free_mem(mp_p, old_addr, old_byte_size); - if (ret != MPOOL_ERROR_NONE) { - /* if the old free failed, try and free the new address */ - (void)free_mem(mp_p, new_addr, new_byte_size); - SET_POINTER(error_p, ret); - return NULL; - } - - if (mp_p->mp_log_func != NULL) { - mp_p->mp_log_func(mp_p, MPOOL_FUNC_RESIZE, new_byte_size, - 0, new_addr, old_addr, old_byte_size); - } - - SET_POINTER(error_p, MPOOL_ERROR_NONE); - return new_addr; + SET_POINTER(error_p, MPOOL_ERROR_NONE); + return new_addr; } /* @@ -1563,29 +1559,29 @@ void *mpool_resize(mpool_t *mp_p, void *old_addr, * will be set to the total amount of space (including administrative * overhead) used by the pool. */ -int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, - unsigned long *num_alloced_p, - unsigned long *user_alloced_p, - unsigned long *max_alloced_p, - unsigned long *tot_alloced_p) +KS_DECLARE(int) mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, + unsigned long *num_alloced_p, + unsigned long *user_alloced_p, + unsigned long *max_alloced_p, + unsigned long *tot_alloced_p) { - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } - SET_POINTER(page_size_p, mp_p->mp_page_size); - SET_POINTER(num_alloced_p, mp_p->mp_alloc_c); - SET_POINTER(user_alloced_p, mp_p->mp_user_alloc); - SET_POINTER(max_alloced_p, mp_p->mp_max_alloc); - SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c)); + SET_POINTER(page_size_p, mp_p->mp_page_size); + SET_POINTER(num_alloced_p, mp_p->mp_alloc_c); + SET_POINTER(user_alloced_p, mp_p->mp_user_alloc); + SET_POINTER(max_alloced_p, mp_p->mp_max_alloc); + SET_POINTER(tot_alloced_p, SIZE_OF_PAGES(mp_p, mp_p->mp_page_c)); - return MPOOL_ERROR_NONE; + return MPOOL_ERROR_NONE; } /* @@ -1609,21 +1605,21 @@ int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p, * log_func -> Log function (defined in mpool.h) which will be called * with each mpool transaction. */ -int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func) +KS_DECLARE(int) mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func) { - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } - mp_p->mp_log_func = log_func; + mp_p->mp_log_func = log_func; - return MPOOL_ERROR_NONE; + return MPOOL_ERROR_NONE; } /* @@ -1651,30 +1647,30 @@ int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func) * * max_pages -> Maximum number of pages used by the library. */ -int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages) +KS_DECLARE(int) mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages) { - if (mp_p == NULL) { - return MPOOL_ERROR_ARG_NULL; - } - if (mp_p->mp_magic != MPOOL_MAGIC) { - return MPOOL_ERROR_PNT; - } - if (mp_p->mp_magic2 != MPOOL_MAGIC) { - return MPOOL_ERROR_POOL_OVER; - } + if (mp_p == NULL) { + return MPOOL_ERROR_ARG_NULL; + } + if (mp_p->mp_magic != MPOOL_MAGIC) { + return MPOOL_ERROR_PNT; + } + if (mp_p->mp_magic2 != MPOOL_MAGIC) { + return MPOOL_ERROR_POOL_OVER; + } - if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { - mp_p->mp_max_pages = max_pages; - } - else { - /* - * If we are not heavy-packing the pool then we don't count the - * 1st page allocated which holds the mpool header structure. - */ - mp_p->mp_max_pages = max_pages + 1; - } + if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_HEAVY_PACKING)) { + mp_p->mp_max_pages = max_pages; + } + else { + /* + * If we are not heavy-packing the pool then we don't count the + * 1st page allocated which holds the mpool header structure. + */ + mp_p->mp_max_pages = max_pages + 1; + } - return MPOOL_ERROR_NONE; + return MPOOL_ERROR_NONE; } /* @@ -1694,75 +1690,84 @@ int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages) * * error -> Error number that we are converting. */ -const char *mpool_strerror(const int error) +KS_DECLARE(const char *) mpool_strerror(const int error) { - switch (error) { - case MPOOL_ERROR_NONE: - return "no error"; - break; - case MPOOL_ERROR_ARG_NULL: - return "function argument is null"; - break; - case MPOOL_ERROR_ARG_INVALID: - return "function argument is invalid"; - break; - case MPOOL_ERROR_PNT: - return "invalid mpool pointer"; - break; - case MPOOL_ERROR_POOL_OVER: - return "mpool structure was overwritten"; - break; - case MPOOL_ERROR_PAGE_SIZE: - return "could not get system page-size"; - break; - case MPOOL_ERROR_OPEN_ZERO: - return "could not open /dev/zero"; - break; - case MPOOL_ERROR_NO_MEM: - return "no memory available"; - break; - case MPOOL_ERROR_MMAP: - return "problems with mmap"; - break; - case MPOOL_ERROR_SIZE: - return "error processing requested size"; - break; - case MPOOL_ERROR_TOO_BIG: - return "allocation exceeds pool max size"; - break; - case MPOOL_ERROR_MEM: - return "invalid memory address"; - break; - case MPOOL_ERROR_MEM_OVER: - return "memory lower bounds overwritten"; - break; - case MPOOL_ERROR_NOT_FOUND: - return "memory block not found in pool"; - break; - case MPOOL_ERROR_IS_FREE: - return "memory address has already been freed"; - break; - case MPOOL_ERROR_BLOCK_STAT: - return "invalid internal block status"; - break; - case MPOOL_ERROR_FREE_ADDR: - return "invalid internal free address"; - break; - case MPOOL_ERROR_SBRK_CONTIG: - return "sbrk did not return contiguous memory"; - break; - case MPOOL_ERROR_NO_PAGES: - return "no available pages left in pool"; - break; - case MPOOL_ERROR_ALLOC: - return "system alloc function failed"; - break; - case MPOOL_ERROR_PNT_OVER: - return "user pointer admin space overwritten"; - break; - default: - break; - } + switch (error) { + case MPOOL_ERROR_NONE: + return "no error"; + break; + case MPOOL_ERROR_ARG_NULL: + return "function argument is null"; + break; + case MPOOL_ERROR_ARG_INVALID: + return "function argument is invalid"; + break; + case MPOOL_ERROR_PNT: + return "invalid mpool pointer"; + break; + case MPOOL_ERROR_POOL_OVER: + return "mpool structure was overwritten"; + break; + case MPOOL_ERROR_PAGE_SIZE: + return "could not get system page-size"; + break; + case MPOOL_ERROR_OPEN_ZERO: + return "could not open /dev/zero"; + break; + case MPOOL_ERROR_NO_MEM: + return "no memory available"; + break; + case MPOOL_ERROR_MMAP: + return "problems with mmap"; + break; + case MPOOL_ERROR_SIZE: + return "error processing requested size"; + break; + case MPOOL_ERROR_TOO_BIG: + return "allocation exceeds pool max size"; + break; + case MPOOL_ERROR_MEM: + return "invalid memory address"; + break; + case MPOOL_ERROR_MEM_OVER: + return "memory lower bounds overwritten"; + break; + case MPOOL_ERROR_NOT_FOUND: + return "memory block not found in pool"; + break; + case MPOOL_ERROR_IS_FREE: + return "memory address has already been freed"; + break; + case MPOOL_ERROR_BLOCK_STAT: + return "invalid internal block status"; + break; + case MPOOL_ERROR_FREE_ADDR: + return "invalid internal free address"; + break; + case MPOOL_ERROR_NO_PAGES: + return "no available pages left in pool"; + break; + case MPOOL_ERROR_ALLOC: + return "system alloc function failed"; + break; + case MPOOL_ERROR_PNT_OVER: + return "user pointer admin space overwritten"; + break; + default: + break; + } - return "invalid error code"; + return "invalid error code"; } + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/simclist.c b/libs/libks/src/simclist.c index c8d36f5ff4..8333ab86d9 100755 --- a/libs/libks/src/simclist.c +++ b/libs/libks/src/simclist.c @@ -26,12 +26,14 @@ #include /* for setting errno */ #include #ifndef _WIN32 - /* not in Windows! */ +/* not in Windows! */ # include # include +#else +#include #endif #ifndef SIMCLIST_NO_DUMPRESTORE - /* includes for dump/restore */ +/* includes for dump/restore */ # include # include /* for READ_ERRCHECK() and write() */ # include /* for open() etc */ @@ -55,6 +57,9 @@ #if defined(_MSC_VER) || defined(__MINGW32__) /* provide gettimeofday() missing in Windows */ +#ifdef _MSC_VER +#pragma comment(lib, "Winmm.lib") +#endif int gettimeofday(struct timeval *tp, void *tzp) { DWORD t; @@ -88,31 +93,31 @@ typedef INT64 int64_t; /* define some commodity macros for Dump/Restore functionality */ #ifndef SIMCLIST_NO_DUMPRESTORE /* write() decorated with error checking logic */ -#define WRITE_ERRCHECK(fd, msgbuf, msglen) do { \ - if (write(fd, msgbuf, msglen) < 0) return -1; \ - } while (0); +#define WRITE_ERRCHECK(fd, msgbuf, msglen) do { \ + if (write(fd, msgbuf, msglen) < 0) return -1; \ + } while (0); /* READ_ERRCHECK() decorated with error checking logic */ -#define READ_ERRCHECK(fd, msgbuf, msglen) do { \ - if (read(fd, msgbuf, msglen) != msglen) { \ - /*errno = EPROTO;*/ \ - return -1; \ - } \ - } while (0); +#define READ_ERRCHECK(fd, msgbuf, msglen) do { \ + if (read(fd, msgbuf, msglen) != msglen) { \ + /*errno = EPROTO;*/ \ + return -1; \ + } \ + } while (0); /* convert 64bit integers from host to network format */ -#define hton64(x) (\ - htons(1) == 1 ? \ - (uint64_t)x /* big endian */ \ - : /* little endian */ \ - ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ - (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ - (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ - (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ - (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ - (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ - (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ - (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) \ - ) +#define hton64(x) ( \ + htons(1) == 1 ? \ + (uint64_t)x /* big endian */ \ + : /* little endian */ \ + ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ + (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) \ + ) /* convert 64bit integers from network to host format */ #define ntoh64(x) (hton64(x)) @@ -206,12 +211,12 @@ static int list_attrOk(const list_t *restrict l); /* do not inline, this is recursive */ static void list_sort_quicksort(list_t *restrict l, int versus, - unsigned int first, struct list_entry_s *fel, - unsigned int last, struct list_entry_s *lel); + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel); static inline void list_sort_selectionsort(list_t *restrict l, int versus, - unsigned int first, struct list_entry_s *fel, - unsigned int last, struct list_entry_s *lel); + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel); static void *list_get_minmax(const list_t *restrict l, int versus); @@ -792,8 +797,8 @@ static void *list_sort_quicksort_threadwrapper(void *wrapped_params) { #endif static inline void list_sort_selectionsort(list_t *restrict l, int versus, - unsigned int first, struct list_entry_s *fel, - unsigned int last, struct list_entry_s *lel) { + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel) { struct list_entry_s *cursor, *toswap, *firstunsorted; void *tmpdata; @@ -813,8 +818,8 @@ static inline void list_sort_selectionsort(list_t *restrict l, int versus, } static void list_sort_quicksort(list_t *restrict l, int versus, - unsigned int first, struct list_entry_s *fel, - unsigned int last, struct list_entry_s *lel) { + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel) { unsigned int pivotid; unsigned int i; register struct list_entry_s *pivot; @@ -1094,15 +1099,15 @@ int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict /**** DUMP FORMAT **** - [ ver timestamp | totlen numels elemlen hash | DATA ] + [ ver timestamp | totlen numels elemlen hash | DATA ] - where DATA can be: - @ for constant-size list (element size is constant; elemlen > 0) - [ elem elem ... elem ] - @ for other lists (element size dictated by element_meter each time; elemlen <= 0) - [ size elem size elem ... size elem ] + where DATA can be: + @ for constant-size list (element size is constant; elemlen > 0) + [ elem elem ... elem ] + @ for other lists (element size dictated by element_meter each time; elemlen <= 0) + [ size elem size elem ... size elem ] - all integers are encoded in NETWORK BYTE FORMAT + all integers are encoded in NETWORK BYTE FORMAT *****/ @@ -1327,10 +1332,10 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len /* possibly verify the list consistency */ /* wrt hash */ /* don't do that - if (header.listhash != 0 && header.listhash != list_hash(l)) { - errno = ECANCELED; - return -1; - } + if (header.listhash != 0 && header.listhash != list_hash(l)) { + errno = ECANCELED; + return -1; + } */ /* wrt header */ @@ -1487,14 +1492,14 @@ static int list_repOk(const list_t *restrict l) { struct list_entry_s *s; ok = (l != NULL) && ( - /* head/tail checks */ - (l->head_sentinel != NULL && l->tail_sentinel != NULL) && - (l->head_sentinel != l->tail_sentinel) && (l->head_sentinel->prev == NULL && l->tail_sentinel->next == NULL) && - /* empty list */ - (l->numels > 0 || (l->mid == NULL && l->head_sentinel->next == l->tail_sentinel && l->tail_sentinel->prev == l->head_sentinel)) && - /* spare elements checks */ - l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS - ); + /* head/tail checks */ + (l->head_sentinel != NULL && l->tail_sentinel != NULL) && + (l->head_sentinel != l->tail_sentinel) && (l->head_sentinel->prev == NULL && l->tail_sentinel->next == NULL) && + /* empty list */ + (l->numels > 0 || (l->mid == NULL && l->head_sentinel->next == l->tail_sentinel && l->tail_sentinel->prev == l->head_sentinel)) && + /* spare elements checks */ + l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS + ); if (!ok) return 0; @@ -1523,3 +1528,13 @@ static int list_attrOk(const list_t *restrict l) { #endif +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/table.c b/libs/libks/src/table.c index 4e28556eb9..d948dc5885 100644 --- a/libs/libks/src/table.c +++ b/libs/libks/src/table.c @@ -34,7 +34,7 @@ #include #include -#ifdef unix +#if defined(unix) || defined(__APPLE__) #include @@ -43,8 +43,12 @@ #include #include #define NO_MMAP +#ifndef open #define open _open - +#endif +#ifndef fdopen +#define fdopen _fdopen +#endif #endif #ifndef NO_MMAP @@ -68,7 +72,7 @@ #endif static char *rcs_id = - "$Id: table.c,v 1.19 2000/03/09 03:30:41 gray Exp $"; + "$Id: table.c,v 1.19 2000/03/09 03:30:41 gray Exp $"; /* * Version id for the library. You also need to add an entry to the @@ -100,24 +104,24 @@ static char *version_id = "$TableVersion: 4.3.0 March 8, 2000 $"; * and then find the corresponding entry. */ static table_entry_t *first_entry(const table_t *table_p, - table_linear_t *linear_p) + table_linear_t *linear_p) { - table_entry_t *entry_p; - unsigned int bucket_c = 0; + table_entry_t *entry_p; + unsigned int bucket_c = 0; - /* look for the first non-empty bucket */ - for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) { - entry_p = table_p->ta_buckets[bucket_c]; - if (entry_p != NULL) { - if (linear_p != NULL) { - linear_p->tl_bucket_c = bucket_c; - linear_p->tl_entry_c = 0; - } - return TABLE_POINTER(table_p, table_entry_t *, entry_p); - } - } + /* look for the first non-empty bucket */ + for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) { + entry_p = table_p->ta_buckets[bucket_c]; + if (entry_p != NULL) { + if (linear_p != NULL) { + linear_p->tl_bucket_c = bucket_c; + linear_p->tl_entry_c = 0; + } + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } + } - return NULL; + return NULL; } /* @@ -145,59 +149,59 @@ static table_entry_t *first_entry(const table_t *table_p, * will contain a table error code. */ static table_entry_t *next_entry(const table_t *table_p, - table_linear_t *linear_p, int *error_p) + table_linear_t *linear_p, int *error_p) { - table_entry_t *entry_p; - int entry_c; + table_entry_t *entry_p; + int entry_c; - /* can't next if we haven't first-ed */ - if (linear_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_LINEAR); - return NULL; - } + /* can't next if we haven't first-ed */ + if (linear_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_LINEAR); + return NULL; + } - if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { - /* - * NOTE: this might happen if we delete an item which shortens the - * table bucket numbers. - */ - SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); - return NULL; - } + if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } - linear_p->tl_entry_c++; + linear_p->tl_entry_c++; - /* find the entry which is the nth in the list */ - entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; - /* NOTE: we swap the order here to be more efficient */ - for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) { - /* did we reach the end of the list? */ - if (entry_p == NULL) { - break; - } - entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; - } + /* find the entry which is the nth in the list */ + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + /* NOTE: we swap the order here to be more efficient */ + for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) { + /* did we reach the end of the list? */ + if (entry_p == NULL) { + break; + } + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; + } - /* did we find an entry in the current bucket? */ - if (entry_p != NULL) { - SET_POINTER(error_p, TABLE_ERROR_NONE); - return TABLE_POINTER(table_p, table_entry_t *, entry_p); - } + /* did we find an entry in the current bucket? */ + if (entry_p != NULL) { + SET_POINTER(error_p, TABLE_ERROR_NONE); + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } - /* find the first entry in the next non-empty bucket */ + /* find the first entry in the next non-empty bucket */ - linear_p->tl_entry_c = 0; - for (linear_p->tl_bucket_c++; linear_p->tl_bucket_c < table_p->ta_bucket_n; - linear_p->tl_bucket_c++) { - entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; - if (entry_p != NULL) { - SET_POINTER(error_p, TABLE_ERROR_NONE); - return TABLE_POINTER(table_p, table_entry_t *, entry_p); - } - } + linear_p->tl_entry_c = 0; + for (linear_p->tl_bucket_c++; linear_p->tl_bucket_c < table_p->ta_bucket_n; + linear_p->tl_bucket_c++) { + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + if (entry_p != NULL) { + SET_POINTER(error_p, TABLE_ERROR_NONE); + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } + } - SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); - return NULL; + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; } /* @@ -225,48 +229,48 @@ static table_entry_t *next_entry(const table_t *table_p, * will contain a table error code. */ static table_entry_t *this_entry(const table_t *table_p, - const table_linear_t *linear_p, - int *error_p) + const table_linear_t *linear_p, + int *error_p) { - table_entry_t *entry_p; - int entry_c; + table_entry_t *entry_p; + int entry_c; - /* can't next if we haven't first-ed */ - if (linear_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_LINEAR); - return NULL; - } + /* can't next if we haven't first-ed */ + if (linear_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_LINEAR); + return NULL; + } - if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { - /* - * NOTE: this might happen if we delete an item which shortens the - * table bucket numbers. - */ - SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); - return NULL; - } + if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } - /* find the entry which is the nth in the list */ - entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + /* find the entry which is the nth in the list */ + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; - /* NOTE: we swap the order here to be more efficient */ - for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) { - /* did we reach the end of the list? */ - if (entry_p == NULL) { - break; - } - entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; - } + /* NOTE: we swap the order here to be more efficient */ + for (entry_c = linear_p->tl_entry_c; entry_c > 0; entry_c--) { + /* did we reach the end of the list? */ + if (entry_p == NULL) { + break; + } + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; + } - /* did we find an entry in the current bucket? */ - if (entry_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); - return NULL; - } - else { - SET_POINTER(error_p, TABLE_ERROR_NONE); - return TABLE_POINTER(table_p, table_entry_t *, entry_p); - } + /* did we find an entry in the current bucket? */ + if (entry_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } + else { + SET_POINTER(error_p, TABLE_ERROR_NONE); + return TABLE_POINTER(table_p, table_entry_t *, entry_p); + } } /* @@ -307,67 +311,67 @@ static table_entry_t *this_entry(const table_t *table_p, * for (i=0, h=0; i= 12; len -= 12) { - a += (key_p[0] - + ((unsigned int)key_p[1] << 8) - + ((unsigned int)key_p[2] << 16) - + ((unsigned int)key_p[3] << 24)); - b += (key_p[4] - + ((unsigned int)key_p[5] << 8) - + ((unsigned int)key_p[6] << 16) - + ((unsigned int)key_p[7] << 24)); - c += (key_p[8] - + ((unsigned int)key_p[9] << 8) - + ((unsigned int)key_p[10] << 16) - + ((unsigned int)key_p[11] << 24)); - HASH_MIX(a,b,c); - key_p += 12; - } + /* handle most of the key */ + for (len = length; len >= 12; len -= 12) { + a += (key_p[0] + + ((unsigned int)key_p[1] << 8) + + ((unsigned int)key_p[2] << 16) + + ((unsigned int)key_p[3] << 24)); + b += (key_p[4] + + ((unsigned int)key_p[5] << 8) + + ((unsigned int)key_p[6] << 16) + + ((unsigned int)key_p[7] << 24)); + c += (key_p[8] + + ((unsigned int)key_p[9] << 8) + + ((unsigned int)key_p[10] << 16) + + ((unsigned int)key_p[11] << 24)); + HASH_MIX(a,b,c); + key_p += 12; + } - c += length; + c += length; - /* all the case statements fall through to the next */ - switch(len) { - case 11: - c += ((unsigned int)key_p[10] << 24); - case 10: - c += ((unsigned int)key_p[9] << 16); - case 9: - c += ((unsigned int)key_p[8] << 8); - /* the first byte of c is reserved for the length */ - case 8: - b += ((unsigned int)key_p[7] << 24); - case 7: - b += ((unsigned int)key_p[6] << 16); - case 6: - b += ((unsigned int)key_p[5] << 8); - case 5: - b += key_p[4]; - case 4: - a += ((unsigned int)key_p[3] << 24); - case 3: - a += ((unsigned int)key_p[2] << 16); - case 2: - a += ((unsigned int)key_p[1] << 8); - case 1: - a += key_p[0]; - /* case 0: nothing left to add */ - } - HASH_MIX(a, b, c); + /* all the case statements fall through to the next */ + switch(len) { + case 11: + c += ((unsigned int)key_p[10] << 24); + case 10: + c += ((unsigned int)key_p[9] << 16); + case 9: + c += ((unsigned int)key_p[8] << 8); + /* the first byte of c is reserved for the length */ + case 8: + b += ((unsigned int)key_p[7] << 24); + case 7: + b += ((unsigned int)key_p[6] << 16); + case 6: + b += ((unsigned int)key_p[5] << 8); + case 5: + b += key_p[4]; + case 4: + a += ((unsigned int)key_p[3] << 24); + case 3: + a += ((unsigned int)key_p[2] << 16); + case 2: + a += ((unsigned int)key_p[1] << 8); + case 1: + a += key_p[0]; + /* case 0: nothing left to add */ + } + HASH_MIX(a, b, c); - return c; + return c; } /* @@ -392,28 +396,28 @@ static unsigned int hash(const unsigned char *key, * data - Size of the entry data. */ static int entry_size(const table_t *table_p, const unsigned int key_size, - const unsigned int data_size) + const unsigned int data_size) { - int size, left; + int size, left; - /* initial size -- key is already aligned if right after struct */ - size = sizeof(struct table_shell_st) + key_size; + /* initial size -- key is already aligned if right after struct */ + size = sizeof(struct table_shell_st) + key_size; - /* if there is no alignment then it is easy */ - if (table_p->ta_data_align == 0) { - return size + data_size; - } + /* if there is no alignment then it is easy */ + if (table_p->ta_data_align == 0) { + return size + data_size; + } - /* add in our alignement */ - left = size & (table_p->ta_data_align - 1); - if (left > 0) { - size += table_p->ta_data_align - left; - } + /* add in our alignement */ + left = size & (table_p->ta_data_align - 1); + if (left > 0) { + size += table_p->ta_data_align - left; + } - /* we add the data size here after the alignment */ - size += data_size; + /* we add the data size here after the alignment */ + size += data_size; - return size; + return size; } /* @@ -437,23 +441,23 @@ static int entry_size(const table_t *table_p, const unsigned int key_size, * entry_p - Entry whose data pointer we are determining. */ static unsigned char *entry_data_buf(const table_t *table_p, - const table_entry_t *entry_p) + const table_entry_t *entry_p) { - const unsigned char *buf_p; - unsigned int size, pad; + const unsigned char *buf_p; + unsigned int size, pad; - buf_p = entry_p->te_key_buf + entry_p->te_key_size; + buf_p = entry_p->te_key_buf + entry_p->te_key_size; - /* we need the size of the space before the data */ - size = sizeof(struct table_shell_st) + entry_p->te_key_size; + /* we need the size of the space before the data */ + size = sizeof(struct table_shell_st) + entry_p->te_key_size; - /* add in our alignment */ - pad = size & (table_p->ta_data_align - 1); - if (pad > 0) { - pad = table_p->ta_data_align - pad; - } + /* add in our alignment */ + pad = size & (table_p->ta_data_align - 1); + if (pad > 0) { + pad = table_p->ta_data_align - pad; + } - return (unsigned char *)buf_p + pad; + return (unsigned char *)buf_p + pad; } /******************************* sort routines *******************************/ @@ -484,26 +488,26 @@ static unsigned char *entry_data_buf(const table_t *table_p, * has occurred. It cannot be NULL. */ static int local_compare(const void *p1, const void *p2, - table_compare_t compare, const table_t *table_p, - int *err_bp) + table_compare_t compare, const table_t *table_p, + int *err_bp) { - const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; - int cmp; - unsigned int size; + const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; + int cmp; + unsigned int size; - /* compare as many bytes as we can */ - size = (*ent1_p)->te_key_size; - if ((*ent2_p)->te_key_size < size) { - size = (*ent2_p)->te_key_size; - } - cmp = memcmp(ENTRY_KEY_BUF(*ent1_p), ENTRY_KEY_BUF(*ent2_p), size); - /* if common-size equal, then if next more bytes, it is larger */ - if (cmp == 0) { - cmp = (*ent1_p)->te_key_size - (*ent2_p)->te_key_size; - } + /* compare as many bytes as we can */ + size = (*ent1_p)->te_key_size; + if ((*ent2_p)->te_key_size < size) { + size = (*ent2_p)->te_key_size; + } + cmp = memcmp(ENTRY_KEY_BUF(*ent1_p), ENTRY_KEY_BUF(*ent2_p), size); + /* if common-size equal, then if next more bytes, it is larger */ + if (cmp == 0) { + cmp = (*ent1_p)->te_key_size - (*ent2_p)->te_key_size; + } - *err_bp = 0; - return cmp; + *err_bp = 0; + return cmp; } /* @@ -532,35 +536,35 @@ static int local_compare(const void *p1, const void *p2, * has occurred. It cannot be NULL. */ static int local_compare_pos(const void *p1, const void *p2, - table_compare_t compare, - const table_t *table_p, int *err_bp) + table_compare_t compare, + const table_t *table_p, int *err_bp) { - const table_linear_t *lin1_p = p1, *lin2_p = p2; - const table_entry_t *ent1_p, *ent2_p; - int cmp, ret; - unsigned int size; + const table_linear_t *lin1_p = p1, *lin2_p = p2; + const table_entry_t *ent1_p, *ent2_p; + int cmp, ret; + unsigned int size; - /* get entry pointers */ - ent1_p = this_entry(table_p, lin1_p, &ret); - ent2_p = this_entry(table_p, lin2_p, &ret); - if (ent1_p == NULL || ent2_p == NULL) { - *err_bp = 1; - return 0; - } + /* get entry pointers */ + ent1_p = this_entry(table_p, lin1_p, &ret); + ent2_p = this_entry(table_p, lin2_p, &ret); + if (ent1_p == NULL || ent2_p == NULL) { + *err_bp = 1; + return 0; + } - /* compare as many bytes as we can */ - size = ent1_p->te_key_size; - if (ent2_p->te_key_size < size) { - size = ent2_p->te_key_size; - } - cmp = memcmp(ENTRY_KEY_BUF(ent1_p), ENTRY_KEY_BUF(ent2_p), size); - /* if common-size equal, then if next more bytes, it is larger */ - if (cmp == 0) { - cmp = ent1_p->te_key_size - ent2_p->te_key_size; - } + /* compare as many bytes as we can */ + size = ent1_p->te_key_size; + if (ent2_p->te_key_size < size) { + size = ent2_p->te_key_size; + } + cmp = memcmp(ENTRY_KEY_BUF(ent1_p), ENTRY_KEY_BUF(ent2_p), size); + /* if common-size equal, then if next more bytes, it is larger */ + if (cmp == 0) { + cmp = ent1_p->te_key_size - ent2_p->te_key_size; + } - *err_bp = 0; - return cmp; + *err_bp = 0; + return cmp; } /* @@ -589,18 +593,18 @@ static int local_compare_pos(const void *p1, const void *p2, * has occurred. It cannot be NULL. */ static int external_compare(const void *p1, const void *p2, - table_compare_t user_compare, - const table_t *table_p, int *err_bp) + table_compare_t user_compare, + const table_t *table_p, int *err_bp) { - const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; - /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */ - *err_bp = 0; - return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size, - ENTRY_DATA_BUF(table_p, *ent1_p), - (*ent1_p)->te_data_size, - ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size, - ENTRY_DATA_BUF(table_p, *ent2_p), - (*ent2_p)->te_data_size); + const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; + /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size, + ENTRY_DATA_BUF(table_p, *ent1_p), + (*ent1_p)->te_data_size, + ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size, + ENTRY_DATA_BUF(table_p, *ent2_p), + (*ent2_p)->te_data_size); } /* @@ -627,29 +631,29 @@ static int external_compare(const void *p1, const void *p2, * * err_bp - Pointer to an integer which will be set with 1 if an error * has occurred. It cannot be NULL. -*/ + */ static int external_compare_pos(const void *p1, const void *p2, - table_compare_t user_compare, - const table_t *table_p, int *err_bp) + table_compare_t user_compare, + const table_t *table_p, int *err_bp) { - const table_linear_t *lin1_p = p1, *lin2_p = p2; - const table_entry_t *ent1_p, *ent2_p; - int ret; + const table_linear_t *lin1_p = p1, *lin2_p = p2; + const table_entry_t *ent1_p, *ent2_p; + int ret; - /* get entry pointers */ - ent1_p = this_entry(table_p, lin1_p, &ret); - ent2_p = this_entry(table_p, lin2_p, &ret); - if (ent1_p == NULL || ent2_p == NULL) { - *err_bp = 1; - return 0; - } + /* get entry pointers */ + ent1_p = this_entry(table_p, lin1_p, &ret); + ent2_p = this_entry(table_p, lin2_p, &ret); + if (ent1_p == NULL || ent2_p == NULL) { + *err_bp = 1; + return 0; + } - /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */ - *err_bp = 0; - return user_compare(ENTRY_KEY_BUF(ent1_p), (ent1_p)->te_key_size, - ENTRY_DATA_BUF(table_p, ent1_p), ent1_p->te_data_size, - ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size, - ENTRY_DATA_BUF(table_p, ent2_p), ent2_p->te_data_size); + /* since we know we are not aligned we can use the EXTRY_DATA_BUF macro */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(ent1_p), (ent1_p)->te_key_size, + ENTRY_DATA_BUF(table_p, ent1_p), ent1_p->te_data_size, + ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size, + ENTRY_DATA_BUF(table_p, ent2_p), ent2_p->te_data_size); } /* @@ -678,18 +682,18 @@ static int external_compare_pos(const void *p1, const void *p2, * has occurred. It cannot be NULL. */ static int external_compare_align(const void *p1, const void *p2, - table_compare_t user_compare, - const table_t *table_p, int *err_bp) + table_compare_t user_compare, + const table_t *table_p, int *err_bp) { - const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; - /* since we are aligned we have to use the entry_data_buf function */ - *err_bp = 0; - return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size, - entry_data_buf(table_p, *ent1_p), - (*ent1_p)->te_data_size, - ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size, - entry_data_buf(table_p, *ent2_p), - (*ent2_p)->te_data_size); + const table_entry_t * const *ent1_p = p1, * const *ent2_p = p2; + /* since we are aligned we have to use the entry_data_buf function */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(*ent1_p), (*ent1_p)->te_key_size, + entry_data_buf(table_p, *ent1_p), + (*ent1_p)->te_data_size, + ENTRY_KEY_BUF(*ent2_p), (*ent2_p)->te_key_size, + entry_data_buf(table_p, *ent2_p), + (*ent2_p)->te_data_size); } /* @@ -718,27 +722,27 @@ static int external_compare_align(const void *p1, const void *p2, * has occurred. It cannot be NULL. */ static int external_compare_align_pos(const void *p1, const void *p2, - table_compare_t user_compare, - const table_t *table_p, int *err_bp) + table_compare_t user_compare, + const table_t *table_p, int *err_bp) { - const table_linear_t *lin1_p = p1, *lin2_p = p2; - const table_entry_t *ent1_p, *ent2_p; - int ret; + const table_linear_t *lin1_p = p1, *lin2_p = p2; + const table_entry_t *ent1_p, *ent2_p; + int ret; - /* get entry pointers */ - ent1_p = this_entry(table_p, lin1_p, &ret); - ent2_p = this_entry(table_p, lin2_p, &ret); - if (ent1_p == NULL || ent2_p == NULL) { - *err_bp = 1; - return 0; - } + /* get entry pointers */ + ent1_p = this_entry(table_p, lin1_p, &ret); + ent2_p = this_entry(table_p, lin2_p, &ret); + if (ent1_p == NULL || ent2_p == NULL) { + *err_bp = 1; + return 0; + } - /* since we are aligned we have to use the entry_data_buf function */ - *err_bp = 0; - return user_compare(ENTRY_KEY_BUF(ent1_p), ent1_p->te_key_size, - entry_data_buf(table_p, ent1_p), ent1_p->te_data_size, - ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size, - entry_data_buf(table_p, ent2_p), ent2_p->te_data_size); + /* since we are aligned we have to use the entry_data_buf function */ + *err_bp = 0; + return user_compare(ENTRY_KEY_BUF(ent1_p), ent1_p->te_key_size, + entry_data_buf(table_p, ent1_p), ent1_p->te_data_size, + ENTRY_KEY_BUF(ent2_p), ent2_p->te_key_size, + entry_data_buf(table_p, ent2_p), ent2_p->te_data_size); } /* @@ -761,17 +765,17 @@ static int external_compare_align_pos(const void *p1, const void *p2, * ele_size -> Size of the two items. */ static void swap_bytes(unsigned char *item1_p, unsigned char *item2_p, - int ele_size) + int ele_size) { - unsigned char char_temp; + unsigned char char_temp; - for (; ele_size > 0; ele_size--) { - char_temp = *item1_p; - *item1_p = *item2_p; - *item2_p = char_temp; - item1_p++; - item2_p++; - } + for (; ele_size > 0; ele_size--) { + char_temp = *item1_p; + *item1_p = *item2_p; + *item2_p = char_temp; + item1_p++; + item2_p++; + } } /* @@ -806,44 +810,44 @@ static void swap_bytes(unsigned char *item1_p, unsigned char *item2_p, * table_p -> Associated table being sorted. */ static int insert_sort(unsigned char *first_p, unsigned char *last_p, - unsigned char *holder_p, - const unsigned int ele_size, compare_t compare, - table_compare_t user_compare, table_t *table_p) + unsigned char *holder_p, + const unsigned int ele_size, compare_t compare, + table_compare_t user_compare, table_t *table_p) { - unsigned char *inner_p, *outer_p; - int ret, err_b; + unsigned char *inner_p, *outer_p; + int ret, err_b; - for (outer_p = first_p + ele_size; outer_p <= last_p; ) { + for (outer_p = first_p + ele_size; outer_p <= last_p; ) { - /* look for the place to insert the entry */ - for (inner_p = outer_p - ele_size; - inner_p >= first_p; - inner_p -= ele_size) { - ret = compare(outer_p, inner_p, user_compare, table_p, &err_b); - if (err_b) { - return TABLE_ERROR_COMPARE; - } - if (ret >= 0) { - break; - } - } - inner_p += ele_size; + /* look for the place to insert the entry */ + for (inner_p = outer_p - ele_size; + inner_p >= first_p; + inner_p -= ele_size) { + ret = compare(outer_p, inner_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret >= 0) { + break; + } + } + inner_p += ele_size; - /* do we need to insert the entry in? */ - if (outer_p != inner_p) { - /* - * Now we shift the entry down into its place in the already - * sorted list. - */ - memcpy(holder_p, outer_p, ele_size); - memmove(inner_p + ele_size, inner_p, outer_p - inner_p); - memcpy(inner_p, holder_p, ele_size); - } + /* do we need to insert the entry in? */ + if (outer_p != inner_p) { + /* + * Now we shift the entry down into its place in the already + * sorted list. + */ + memcpy(holder_p, outer_p, ele_size); + memmove(inner_p + ele_size, inner_p, outer_p - inner_p); + memcpy(inner_p, holder_p, ele_size); + } - outer_p += ele_size; - } + outer_p += ele_size; + } - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -874,197 +878,197 @@ static int insert_sort(unsigned char *first_p, unsigned char *last_p, * table_p -> Associated table being sorted. */ static int split(unsigned char *first_p, unsigned char *last_p, - const unsigned int ele_size, compare_t compare, - table_compare_t user_compare, table_t *table_p) + const unsigned int ele_size, compare_t compare, + table_compare_t user_compare, table_t *table_p) { - unsigned char *left_p, *right_p, *pivot_p, *left_last_p, *right_first_p; - unsigned char *firsts[MAX_QSORT_SPLITS], *lasts[MAX_QSORT_SPLITS], *pivot; - unsigned int width, split_c = 0; - int size1, size2, min_qsort_size; - int ret, err_b; + unsigned char *left_p, *right_p, *pivot_p, *left_last_p, *right_first_p; + unsigned char *firsts[MAX_QSORT_SPLITS], *lasts[MAX_QSORT_SPLITS], *pivot; + unsigned int width, split_c = 0; + int size1, size2, min_qsort_size; + int ret, err_b; - /* - * Allocate some space for our pivot value. We also use this as - * holder space for our insert sort. - */ - pivot = alloca(ele_size); - if (pivot == NULL) { - /* what else can we do? */ - abort(); - } - - min_qsort_size = MAX_QSORT_MANY * ele_size; - - while (1) { - - /* find the left, right, and mid point */ - left_p = first_p; - right_p = last_p; - /* is there a faster way to find this? */ - width = (last_p - first_p) / ele_size; - pivot_p = first_p + ele_size * (width >> 1); - - /* - * Find which of the left, middle, and right elements is the - * median (Knuth vol3 p123). - */ - ret = compare(first_p, pivot_p, user_compare, table_p, &err_b); - if (err_b) { - return TABLE_ERROR_COMPARE; - } - if (ret > 0) { - swap_bytes(first_p, pivot_p, ele_size); - } - ret = compare(pivot_p, last_p, user_compare, table_p, &err_b); - if (err_b) { - return TABLE_ERROR_COMPARE; - } - if (ret > 0) { - swap_bytes(pivot_p, last_p, ele_size); - ret = compare(first_p, pivot_p, user_compare, table_p, &err_b); - if (err_b) { - return TABLE_ERROR_COMPARE; - } - if (ret > 0) { - swap_bytes(first_p, pivot_p, ele_size); - } - } - - /* - * save our pivot so we don't have to worry about hitting and - * swapping it elsewhere while we iterate across the list below. - */ - memcpy(pivot, pivot_p, ele_size); - - do { - - /* shift the left side up until we reach the pivot value */ - while (1) { - ret = compare(left_p, pivot, user_compare, table_p, &err_b); - if (err_b) { - return TABLE_ERROR_COMPARE; - } - if (ret >= 0) { - break; - } - left_p += ele_size; - } - /* shift the right side down until we reach the pivot value */ - while (1) { - ret = compare(pivot, right_p, user_compare, table_p, &err_b); - if (err_b) { - return TABLE_ERROR_COMPARE; - } - if (ret >= 0) { - break; - } - right_p -= ele_size; - } - - /* if we met in the middle then we are done */ - if (left_p == right_p) { - left_p += ele_size; - right_p -= ele_size; - break; - } - else if (left_p < right_p) { /* - * swap the left and right since they both were on the wrong - * size of the pivot and continue + * Allocate some space for our pivot value. We also use this as + * holder space for our insert sort. */ - swap_bytes(left_p, right_p, ele_size); - left_p += ele_size; - right_p -= ele_size; - } - } while (left_p <= right_p); - - /* Rename variables to make more sense. This will get optimized out. */ - right_first_p = left_p; - left_last_p = right_p; - - /* determine the size of the left and right hand parts */ - size1 = left_last_p - first_p; - size2 = last_p - right_first_p; - - /* is the 1st half small enough to just insert-sort? */ - if (size1 < min_qsort_size) { - - /* use the pivot as our temporary space */ - ret = insert_sort(first_p, left_last_p, pivot, ele_size, compare, - user_compare, table_p); - if (ret != TABLE_ERROR_NONE) { - return ret; - } - - /* is the 2nd part small as well? */ - if (size2 < min_qsort_size) { - - /* use the pivot as our temporary space */ - ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare, - user_compare, table_p); - if (ret != TABLE_ERROR_NONE) { - return ret; + pivot = alloca(ele_size); + if (pivot == NULL) { + /* what else can we do? */ + abort(); } - - /* pop a partition off our stack */ - if (split_c == 0) { - /* we are done */ - return TABLE_ERROR_NONE; - } - split_c--; - first_p = firsts[split_c]; - last_p = lasts[split_c]; - } - else { - /* we can just handle the right side immediately */ - first_p = right_first_p; - /* last_p = last_p */ - } - } - else if (size2 < min_qsort_size) { - - /* use the pivot as our temporary space */ - ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare, - user_compare, table_p); - if (ret != TABLE_ERROR_NONE) { - return ret; - } - - /* we can just handle the left side immediately */ - /* first_p = first_p */ - last_p = left_last_p; - } - else { - /* - * neither partition is small, we'll have to push the larger one - * of them on the stack - */ - if (split_c >= MAX_QSORT_SPLITS) { - /* sanity check here -- we should never get here */ - abort(); - } - if (size1 > size2) { - /* push the left partition on the stack */ - firsts[split_c] = first_p; - lasts[split_c] = left_last_p; - split_c++; - /* continue handling the right side */ - first_p = right_first_p; - /* last_p = last_p */ - } - else { - /* push the right partition on the stack */ - firsts[split_c] = right_first_p; - lasts[split_c] = last_p; - split_c++; - /* continue handling the left side */ - /* first_p = first_p */ - last_p = left_last_p; - } - } - } - return TABLE_ERROR_NONE; + min_qsort_size = MAX_QSORT_MANY * ele_size; + + while (1) { + + /* find the left, right, and mid point */ + left_p = first_p; + right_p = last_p; + /* is there a faster way to find this? */ + width = (last_p - first_p) / ele_size; + pivot_p = first_p + ele_size * (width >> 1); + + /* + * Find which of the left, middle, and right elements is the + * median (Knuth vol3 p123). + */ + ret = compare(first_p, pivot_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret > 0) { + swap_bytes(first_p, pivot_p, ele_size); + } + ret = compare(pivot_p, last_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret > 0) { + swap_bytes(pivot_p, last_p, ele_size); + ret = compare(first_p, pivot_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret > 0) { + swap_bytes(first_p, pivot_p, ele_size); + } + } + + /* + * save our pivot so we don't have to worry about hitting and + * swapping it elsewhere while we iterate across the list below. + */ + memcpy(pivot, pivot_p, ele_size); + + do { + + /* shift the left side up until we reach the pivot value */ + while (1) { + ret = compare(left_p, pivot, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret >= 0) { + break; + } + left_p += ele_size; + } + /* shift the right side down until we reach the pivot value */ + while (1) { + ret = compare(pivot, right_p, user_compare, table_p, &err_b); + if (err_b) { + return TABLE_ERROR_COMPARE; + } + if (ret >= 0) { + break; + } + right_p -= ele_size; + } + + /* if we met in the middle then we are done */ + if (left_p == right_p) { + left_p += ele_size; + right_p -= ele_size; + break; + } + else if (left_p < right_p) { + /* + * swap the left and right since they both were on the wrong + * size of the pivot and continue + */ + swap_bytes(left_p, right_p, ele_size); + left_p += ele_size; + right_p -= ele_size; + } + } while (left_p <= right_p); + + /* Rename variables to make more sense. This will get optimized out. */ + right_first_p = left_p; + left_last_p = right_p; + + /* determine the size of the left and right hand parts */ + size1 = left_last_p - first_p; + size2 = last_p - right_first_p; + + /* is the 1st half small enough to just insert-sort? */ + if (size1 < min_qsort_size) { + + /* use the pivot as our temporary space */ + ret = insert_sort(first_p, left_last_p, pivot, ele_size, compare, + user_compare, table_p); + if (ret != TABLE_ERROR_NONE) { + return ret; + } + + /* is the 2nd part small as well? */ + if (size2 < min_qsort_size) { + + /* use the pivot as our temporary space */ + ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare, + user_compare, table_p); + if (ret != TABLE_ERROR_NONE) { + return ret; + } + + /* pop a partition off our stack */ + if (split_c == 0) { + /* we are done */ + return TABLE_ERROR_NONE; + } + split_c--; + first_p = firsts[split_c]; + last_p = lasts[split_c]; + } + else { + /* we can just handle the right side immediately */ + first_p = right_first_p; + /* last_p = last_p */ + } + } + else if (size2 < min_qsort_size) { + + /* use the pivot as our temporary space */ + ret = insert_sort(right_first_p, last_p, pivot, ele_size, compare, + user_compare, table_p); + if (ret != TABLE_ERROR_NONE) { + return ret; + } + + /* we can just handle the left side immediately */ + /* first_p = first_p */ + last_p = left_last_p; + } + else { + /* + * neither partition is small, we'll have to push the larger one + * of them on the stack + */ + if (split_c >= MAX_QSORT_SPLITS) { + /* sanity check here -- we should never get here */ + abort(); + } + if (size1 > size2) { + /* push the left partition on the stack */ + firsts[split_c] = first_p; + lasts[split_c] = left_last_p; + split_c++; + /* continue handling the right side */ + first_p = right_first_p; + /* last_p = last_p */ + } + else { + /* push the right partition on the stack */ + firsts[split_c] = right_first_p; + lasts[split_c] = last_p; + split_c++; + /* continue handling the left side */ + /* first_p = first_p */ + last_p = left_last_p; + } + } + } + + return TABLE_ERROR_NONE; } /*************************** exported routines *******************************/ @@ -1092,50 +1096,50 @@ static int split(unsigned char *first_p, unsigned char *last_p, */ table_t *table_alloc(const unsigned int bucket_n, int *error_p) { - table_t *table_p = NULL; - unsigned int buck_n; + table_t *table_p = NULL; + unsigned int buck_n; - /* allocate a table structure */ - table_p = malloc(sizeof(table_t)); - if (table_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - return NULL; - } + /* allocate a table structure */ + table_p = malloc(sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } - if (bucket_n > 0) { - buck_n = bucket_n; - } - else { - buck_n = DEFAULT_SIZE; - } + if (bucket_n > 0) { + buck_n = bucket_n; + } + else { + buck_n = DEFAULT_SIZE; + } - /* allocate the buckets which are NULLed */ - table_p->ta_buckets = (table_entry_t **)calloc(buck_n, - sizeof(table_entry_t *)); - if (table_p->ta_buckets == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - free(table_p); - return NULL; - } + /* allocate the buckets which are NULLed */ + table_p->ta_buckets = (table_entry_t **)calloc(buck_n, + sizeof(table_entry_t *)); + if (table_p->ta_buckets == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + free(table_p); + return NULL; + } - /* initialize structure */ - table_p->ta_magic = TABLE_MAGIC; - table_p->ta_flags = 0; - table_p->ta_bucket_n = buck_n; - table_p->ta_entry_n = 0; - table_p->ta_data_align = 0; - table_p->ta_linear.tl_magic = 0; - table_p->ta_linear.tl_bucket_c = 0; - table_p->ta_linear.tl_entry_c = 0; - table_p->ta_mmap = NULL; - table_p->ta_file_size = 0; - table_p->ta_mem_pool = NULL; - table_p->ta_alloc_func = NULL; - table_p->ta_resize_func = NULL; - table_p->ta_free_func = NULL; + /* initialize structure */ + table_p->ta_magic = TABLE_MAGIC; + table_p->ta_flags = 0; + table_p->ta_bucket_n = buck_n; + table_p->ta_entry_n = 0; + table_p->ta_data_align = 0; + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + table_p->ta_mmap = NULL; + table_p->ta_file_size = 0; + table_p->ta_mem_pool = NULL; + table_p->ta_alloc_func = NULL; + table_p->ta_resize_func = NULL; + table_p->ta_free_func = NULL; - SET_POINTER(error_p, TABLE_ERROR_NONE); - return table_p; + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; } /* @@ -1171,66 +1175,66 @@ table_t *table_alloc(const unsigned int bucket_n, int *error_p) * table error code. */ table_t *table_alloc_in_pool(const unsigned int bucket_n, - void *mem_pool, - table_mem_alloc_t alloc_func, - table_mem_resize_t resize_func, - table_mem_free_t free_func, int *error_p) + void *mem_pool, + table_mem_alloc_t alloc_func, + table_mem_resize_t resize_func, + table_mem_free_t free_func, int *error_p) { - table_t *table_p = NULL; - unsigned int buck_n, size; + table_t *table_p = NULL; + unsigned int buck_n, size; - /* make sure we have real functions, mem_pool and resize_func can be NULL */ - if (alloc_func == NULL || free_func == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); - return NULL; - } + /* make sure we have real functions, mem_pool and resize_func can be NULL */ + if (alloc_func == NULL || free_func == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); + return NULL; + } - /* allocate a table structure */ - table_p = alloc_func(mem_pool, sizeof(table_t)); - if (table_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - return NULL; - } + /* allocate a table structure */ + table_p = alloc_func(mem_pool, sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } - if (bucket_n > 0) { - buck_n = bucket_n; - } - else { - buck_n = DEFAULT_SIZE; - } + if (bucket_n > 0) { + buck_n = bucket_n; + } + else { + buck_n = DEFAULT_SIZE; + } - /* allocate the buckets which are NULLed */ - size = buck_n * sizeof(table_entry_t *); - table_p->ta_buckets = (table_entry_t **)alloc_func(mem_pool, size); - if (table_p->ta_buckets == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - (void)free_func(mem_pool, table_p, sizeof(table_t)); - return NULL; - } - /* - * We zero it ourselves to save the necessity of having a - * table_mem_calloc_t memory override function. - */ - memset(table_p->ta_buckets, 0, size); + /* allocate the buckets which are NULLed */ + size = buck_n * sizeof(table_entry_t *); + table_p->ta_buckets = (table_entry_t **)alloc_func(mem_pool, size); + if (table_p->ta_buckets == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + (void)free_func(mem_pool, table_p, sizeof(table_t)); + return NULL; + } + /* + * We zero it ourselves to save the necessity of having a + * table_mem_calloc_t memory override function. + */ + memset(table_p->ta_buckets, 0, size); - /* initialize structure */ - table_p->ta_magic = TABLE_MAGIC; - table_p->ta_flags = 0; - table_p->ta_bucket_n = buck_n; - table_p->ta_entry_n = 0; - table_p->ta_data_align = 0; - table_p->ta_linear.tl_magic = 0; - table_p->ta_linear.tl_bucket_c = 0; - table_p->ta_linear.tl_entry_c = 0; - table_p->ta_mmap = NULL; - table_p->ta_file_size = 0; - table_p->ta_mem_pool = mem_pool; - table_p->ta_alloc_func = alloc_func; - table_p->ta_resize_func = resize_func; - table_p->ta_free_func = free_func; + /* initialize structure */ + table_p->ta_magic = TABLE_MAGIC; + table_p->ta_flags = 0; + table_p->ta_bucket_n = buck_n; + table_p->ta_entry_n = 0; + table_p->ta_data_align = 0; + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + table_p->ta_mmap = NULL; + table_p->ta_file_size = 0; + table_p->ta_mem_pool = mem_pool; + table_p->ta_alloc_func = alloc_func; + table_p->ta_resize_func = resize_func; + table_p->ta_free_func = free_func; - SET_POINTER(error_p, TABLE_ERROR_NONE); - return table_p; + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; } /* @@ -1255,16 +1259,16 @@ table_t *table_alloc_in_pool(const unsigned int bucket_n, */ int table_attr(table_t *table_p, const int attr) { - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } - table_p->ta_flags = attr; + table_p->ta_flags = attr; - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -1306,36 +1310,36 @@ int table_attr(table_t *table_p, const int attr) */ int table_set_data_alignment(table_t *table_p, const int alignment) { - int val; + int val; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (table_p->ta_entry_n > 0) { - return TABLE_ERROR_NOT_EMPTY; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_entry_n > 0) { + return TABLE_ERROR_NOT_EMPTY; + } - /* defaults */ - if (alignment < 2) { - table_p->ta_data_align = 0; - } - else { - /* verify we have a base 2 number */ - for (val = 2; val < MAX_ALIGNMENT; val *= 2) { - if (val == alignment) { - break; - } - } - if (val >= MAX_ALIGNMENT) { - return TABLE_ERROR_ALIGNMENT; - } - table_p->ta_data_align = alignment; - } + /* defaults */ + if (alignment < 2) { + table_p->ta_data_align = 0; + } + else { + /* verify we have a base 2 number */ + for (val = 2; val < MAX_ALIGNMENT; val *= 2) { + if (val == alignment) { + break; + } + } + if (val >= MAX_ALIGNMENT) { + return TABLE_ERROR_ALIGNMENT; + } + table_p->ta_data_align = alignment; + } - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -1357,52 +1361,52 @@ int table_set_data_alignment(table_t *table_p, const int alignment) */ int table_clear(table_t *table_p) { - int final = TABLE_ERROR_NONE; - table_entry_t *entry_p, *next_p; - table_entry_t **bucket_p, **bounds_p; + int final = TABLE_ERROR_NONE; + table_entry_t *entry_p, *next_p; + table_entry_t **bucket_p, **bounds_p; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } #ifndef NO_MMAP - /* no mmap support so immediate error */ - if (table_p->ta_mmap != NULL) { - return TABLE_ERROR_MMAP_OP; - } + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } #endif - /* free the table allocation and table structure */ - bounds_p = table_p->ta_buckets + table_p->ta_bucket_n; - for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) { - for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) { - /* record the next pointer before we free */ - next_p = entry_p->te_next_p; - if (table_p->ta_free_func == NULL) { - free(entry_p); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, - entry_size(table_p, - entry_p->te_key_size, - entry_p->te_data_size))) { - final = TABLE_ERROR_FREE; - } - } + /* free the table allocation and table structure */ + bounds_p = table_p->ta_buckets + table_p->ta_bucket_n; + for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) { + for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) { + /* record the next pointer before we free */ + next_p = entry_p->te_next_p; + if (table_p->ta_free_func == NULL) { + free(entry_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + entry_size(table_p, + entry_p->te_key_size, + entry_p->te_data_size))) { + final = TABLE_ERROR_FREE; + } + } - /* clear the bucket entry after we free its entries */ - *bucket_p = NULL; - } + /* clear the bucket entry after we free its entries */ + *bucket_p = NULL; + } - /* reset table state info */ - table_p->ta_entry_n = 0; - table_p->ta_linear.tl_magic = 0; - table_p->ta_linear.tl_bucket_c = 0; - table_p->ta_linear.tl_entry_c = 0; + /* reset table state info */ + table_p->ta_entry_n = 0; + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; - return final; + return final; } /* @@ -1424,47 +1428,47 @@ int table_clear(table_t *table_p) */ int table_free(table_t *table_p) { - int ret; + int ret; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } #ifndef NO_MMAP - /* no mmap support so immediate error */ - if (table_p->ta_mmap != NULL) { - return TABLE_ERROR_MMAP_OP; - } + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } #endif - ret = table_clear(table_p); + ret = table_clear(table_p); - if (table_p->ta_buckets != NULL) { - if (table_p->ta_free_func == NULL) { - free(table_p->ta_buckets); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, - table_p->ta_buckets, - table_p->ta_bucket_n * - sizeof(table_entry_t *))) { - return TABLE_ERROR_FREE; - } - } - table_p->ta_magic = 0; - if (table_p->ta_free_func == NULL) { - free(table_p); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, table_p, - sizeof(table_t))) { - if (ret == TABLE_ERROR_NONE) { - ret = TABLE_ERROR_FREE; - } - } + if (table_p->ta_buckets != NULL) { + if (table_p->ta_free_func == NULL) { + free(table_p->ta_buckets); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, + table_p->ta_buckets, + table_p->ta_bucket_n * + sizeof(table_entry_t *))) { + return TABLE_ERROR_FREE; + } + } + table_p->ta_magic = 0; + if (table_p->ta_free_func == NULL) { + free(table_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, table_p, + sizeof(table_t))) { + if (ret == TABLE_ERROR_NONE) { + ret = TABLE_ERROR_FREE; + } + } - return ret; + return ret; } /* @@ -1544,241 +1548,241 @@ int table_free(table_t *table_p) * in the table. */ int table_insert_kd(table_t *table_p, - const void *key_buf, const int key_size, - const void *data_buf, const int data_size, - void **key_buf_p, void **data_buf_p, - const char overwrite_b) + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **key_buf_p, void **data_buf_p, + const char overwrite_b) { - int bucket; - unsigned int ksize, dsize, new_size, old_size, copy_size; - table_entry_t *entry_p, *last_p, *new_entry_p; - void *key_copy_p, *data_copy_p; + int bucket; + unsigned int ksize, dsize, new_size, old_size, copy_size; + table_entry_t *entry_p, *last_p, *new_entry_p; + void *key_copy_p, *data_copy_p; - /* check the arguments */ - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (key_buf == NULL) { - return TABLE_ERROR_ARG_NULL; - } - /* data_buf can be null but size must be >= 0, if it isn't null size != 0 */ - if ((data_buf == NULL && data_size < 0) - || (data_buf != NULL && data_size == 0)) { - return TABLE_ERROR_SIZE; - } + /* check the arguments */ + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (key_buf == NULL) { + return TABLE_ERROR_ARG_NULL; + } + /* data_buf can be null but size must be >= 0, if it isn't null size != 0 */ + if ((data_buf == NULL && data_size < 0) + || (data_buf != NULL && data_size == 0)) { + return TABLE_ERROR_SIZE; + } #ifndef NO_MMAP - /* no mmap support so immediate error */ - if (table_p->ta_mmap != NULL) { - return TABLE_ERROR_MMAP_OP; - } + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } #endif - /* determine sizes of key and data */ - if (key_size < 0) { - ksize = strlen((char *)key_buf) + sizeof(char); - } - else { - ksize = key_size; - } - if (data_size < 0) { - dsize = strlen((char *)data_buf) + sizeof(char); - } - else { - dsize = data_size; - } - - /* get the bucket number via a hash function */ - bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; - - /* look for the entry in this bucket, only check keys of the same size */ - last_p = NULL; - for (entry_p = table_p->ta_buckets[bucket]; - entry_p != NULL; - last_p = entry_p, entry_p = entry_p->te_next_p) { - if (entry_p->te_key_size == ksize - && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { - break; - } - } - - /* did we find it? then we are in replace mode. */ - if (entry_p != NULL) { - - /* can we not overwrite existing data? */ - if (! overwrite_b) { - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; + /* determine sizes of key and data */ + if (key_size < 0) { + ksize = strlen((char *)key_buf) + sizeof(char); } else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } + ksize = key_size; } - } - return TABLE_ERROR_OVERWRITE; - } + if (data_size < 0) { + dsize = strlen((char *)data_buf) + sizeof(char); + } + else { + dsize = data_size; + } + + /* get the bucket number via a hash function */ + bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; + + /* look for the entry in this bucket, only check keys of the same size */ + last_p = NULL; + for (entry_p = table_p->ta_buckets[bucket]; + entry_p != NULL; + last_p = entry_p, entry_p = entry_p->te_next_p) { + if (entry_p->te_key_size == ksize + && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { + break; + } + } + + /* did we find it? then we are in replace mode. */ + if (entry_p != NULL) { - /* re-alloc entry's data if the new size != the old */ - if (dsize != entry_p->te_data_size) { + /* can we not overwrite existing data? */ + if (! overwrite_b) { + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + return TABLE_ERROR_OVERWRITE; + } + + /* re-alloc entry's data if the new size != the old */ + if (dsize != entry_p->te_data_size) { - /* - * First we delete it from the list to keep the list whole. - * This properly preserves the linked list in case we have a - * thread marching through the linked list while we are - * inserting. Maybe this is an unnecessary protection but it - * should not harm that much. - */ - if (last_p == NULL) { - table_p->ta_buckets[bucket] = entry_p->te_next_p; - } - else { - last_p->te_next_p = entry_p->te_next_p; - } + /* + * First we delete it from the list to keep the list whole. + * This properly preserves the linked list in case we have a + * thread marching through the linked list while we are + * inserting. Maybe this is an unnecessary protection but it + * should not harm that much. + */ + if (last_p == NULL) { + table_p->ta_buckets[bucket] = entry_p->te_next_p; + } + else { + last_p->te_next_p = entry_p->te_next_p; + } - /* - * Realloc the structure which may change its pointer. NOTE: - * this may change any previous data_key_p and data_copy_p - * pointers. - */ - new_size = entry_size(table_p, entry_p->te_key_size, dsize); - if (table_p->ta_resize_func == NULL) { - /* if the alloc function has not been overriden do realloc */ + /* + * Realloc the structure which may change its pointer. NOTE: + * this may change any previous data_key_p and data_copy_p + * pointers. + */ + new_size = entry_size(table_p, entry_p->te_key_size, dsize); + if (table_p->ta_resize_func == NULL) { + /* if the alloc function has not been overriden do realloc */ + if (table_p->ta_alloc_func == NULL) { + entry_p = (table_entry_t *)realloc(entry_p, new_size); + if (entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + } + else { + old_size = new_size - dsize + entry_p->te_data_size; + /* + * if the user did override alloc but not resize, assume + * that the user's allocation functions can't grok realloc + * and do it ourselves the hard way. + */ + new_entry_p = + (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, + new_size); + if (new_entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + if (new_size > old_size) { + copy_size = old_size; + } + else { + copy_size = new_size; + } + memcpy(new_entry_p, entry_p, copy_size); + if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + old_size)) { + return TABLE_ERROR_FREE; + } + entry_p = new_entry_p; + } + } + else { + old_size = new_size - dsize + entry_p->te_data_size; + entry_p = (table_entry_t *) + table_p->ta_resize_func(table_p->ta_mem_pool, entry_p, + old_size, new_size); + if (entry_p == NULL) { + return TABLE_ERROR_ALLOC; + } + } + + /* add it back to the front of the list */ + entry_p->te_data_size = dsize; + entry_p->te_next_p = table_p->ta_buckets[bucket]; + table_p->ta_buckets[bucket] = entry_p; + } + + /* copy or replace data in storage */ + if (dsize > 0) { + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + if (data_buf != NULL) { + memcpy(data_copy_p, data_buf, dsize); + } + } + else { + data_copy_p = NULL; + } + + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(data_buf_p, data_copy_p); + + /* returning from the section where we were overwriting table data */ + return TABLE_ERROR_NONE; + } + + /* + * It is a new entry. + */ + + /* allocate a new entry */ + new_size = entry_size(table_p, ksize, dsize); if (table_p->ta_alloc_func == NULL) { - entry_p = (table_entry_t *)realloc(entry_p, new_size); - if (entry_p == NULL) { - return TABLE_ERROR_ALLOC; - } + entry_p = (table_entry_t *)malloc(new_size); } else { - old_size = new_size - dsize + entry_p->te_data_size; - /* - * if the user did override alloc but not resize, assume - * that the user's allocation functions can't grok realloc - * and do it ourselves the hard way. - */ - new_entry_p = - (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, - new_size); - if (new_entry_p == NULL) { - return TABLE_ERROR_ALLOC; - } - if (new_size > old_size) { - copy_size = old_size; - } - else { - copy_size = new_size; - } - memcpy(new_entry_p, entry_p, copy_size); - if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, - old_size)) { - return TABLE_ERROR_FREE; - } - entry_p = new_entry_p; + entry_p = + (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, new_size); } - } - else { - old_size = new_size - dsize + entry_p->te_data_size; - entry_p = (table_entry_t *) - table_p->ta_resize_func(table_p->ta_mem_pool, entry_p, - old_size, new_size); if (entry_p == NULL) { - return TABLE_ERROR_ALLOC; + return TABLE_ERROR_ALLOC; } - } - - /* add it back to the front of the list */ - entry_p->te_data_size = dsize; - entry_p->te_next_p = table_p->ta_buckets[bucket]; - table_p->ta_buckets[bucket] = entry_p; - } - - /* copy or replace data in storage */ - if (dsize > 0) { - if (table_p->ta_data_align == 0) { - data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - data_copy_p = entry_data_buf(table_p, entry_p); - } - if (data_buf != NULL) { - memcpy(data_copy_p, data_buf, dsize); - } - } - else { - data_copy_p = NULL; - } - - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(data_buf_p, data_copy_p); - - /* returning from the section where we were overwriting table data */ - return TABLE_ERROR_NONE; - } - /* - * It is a new entry. - */ + /* copy key into storage */ + entry_p->te_key_size = ksize; + key_copy_p = ENTRY_KEY_BUF(entry_p); + memcpy(key_copy_p, key_buf, ksize); - /* allocate a new entry */ - new_size = entry_size(table_p, ksize, dsize); - if (table_p->ta_alloc_func == NULL) { - entry_p = (table_entry_t *)malloc(new_size); - } - else { - entry_p = - (table_entry_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, new_size); - } - if (entry_p == NULL) { - return TABLE_ERROR_ALLOC; - } + /* copy data in */ + entry_p->te_data_size = dsize; + if (dsize > 0) { + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + if (data_buf != NULL) { + memcpy(data_copy_p, data_buf, dsize); + } + } + else { + data_copy_p = NULL; + } - /* copy key into storage */ - entry_p->te_key_size = ksize; - key_copy_p = ENTRY_KEY_BUF(entry_p); - memcpy(key_copy_p, key_buf, ksize); + SET_POINTER(key_buf_p, key_copy_p); + SET_POINTER(data_buf_p, data_copy_p); - /* copy data in */ - entry_p->te_data_size = dsize; - if (dsize > 0) { - if (table_p->ta_data_align == 0) { - data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - data_copy_p = entry_data_buf(table_p, entry_p); - } - if (data_buf != NULL) { - memcpy(data_copy_p, data_buf, dsize); - } - } - else { - data_copy_p = NULL; - } + /* insert into list, no need to append */ + entry_p->te_next_p = table_p->ta_buckets[bucket]; + table_p->ta_buckets[bucket] = entry_p; - SET_POINTER(key_buf_p, key_copy_p); - SET_POINTER(data_buf_p, data_copy_p); + table_p->ta_entry_n++; - /* insert into list, no need to append */ - entry_p->te_next_p = table_p->ta_buckets[bucket]; - table_p->ta_buckets[bucket] = entry_p; + /* do we need auto-adjust? */ + if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) + && SHOULD_TABLE_GROW(table_p)) { + return table_adjust(table_p, table_p->ta_entry_n); + } - table_p->ta_entry_n++; - - /* do we need auto-adjust? */ - if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) - && SHOULD_TABLE_GROW(table_p)) { - return table_adjust(table_p, table_p->ta_entry_n); - } - - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -1834,12 +1838,12 @@ int table_insert_kd(table_t *table_p, * in the table. */ int table_insert(table_t *table_p, - const void *key_buf, const int key_size, - const void *data_buf, const int data_size, - void **data_buf_p, const char overwrite_b) + const void *key_buf, const int key_size, + const void *data_buf, const int data_size, + void **data_buf_p, const char overwrite_b) { - return table_insert_kd(table_p, key_buf, key_size, data_buf, data_size, - NULL, data_buf_p, overwrite_b); + return table_insert_kd(table_p, key_buf, key_size, data_buf, data_size, + NULL, data_buf_p, overwrite_b); } /* @@ -1882,67 +1886,67 @@ int table_insert(table_t *table_p, * the key. */ int table_retrieve(table_t *table_p, - const void *key_buf, const int key_size, - void **data_buf_p, int *data_size_p) + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p) { - int bucket; - unsigned int ksize; - table_entry_t *entry_p, **buckets; + int bucket; + unsigned int ksize; + table_entry_t *entry_p, **buckets; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (key_buf == NULL) { - return TABLE_ERROR_ARG_NULL; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (key_buf == NULL) { + return TABLE_ERROR_ARG_NULL; + } - /* find key size */ - if (key_size < 0) { - ksize = strlen((char *)key_buf) + sizeof(char); - } - else { - ksize = key_size; - } + /* find key size */ + if (key_size < 0) { + ksize = strlen((char *)key_buf) + sizeof(char); + } + else { + ksize = key_size; + } - /* get the bucket number via a has function */ - bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; + /* get the bucket number via a has function */ + bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; - /* look for the entry in this bucket, only check keys of the same size */ - buckets = table_p->ta_buckets; - for (entry_p = buckets[bucket]; - entry_p != NULL; - entry_p = entry_p->te_next_p) { - entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p); - if (entry_p->te_key_size == ksize - && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { - break; - } - } + /* look for the entry in this bucket, only check keys of the same size */ + buckets = table_p->ta_buckets; + for (entry_p = buckets[bucket]; + entry_p != NULL; + entry_p = entry_p->te_next_p) { + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p); + if (entry_p->te_key_size == ksize + && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { + break; + } + } - /* not found? */ - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + /* not found? */ + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -1991,121 +1995,121 @@ int table_retrieve(table_t *table_p, * associated with the key. */ int table_delete(table_t *table_p, - const void *key_buf, const int key_size, - void **data_buf_p, int *data_size_p) + const void *key_buf, const int key_size, + void **data_buf_p, int *data_size_p) { - int bucket; - unsigned int ksize; - unsigned char *data_copy_p; - table_entry_t *entry_p, *last_p; + int bucket; + unsigned int ksize; + unsigned char *data_copy_p; + table_entry_t *entry_p, *last_p; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (key_buf == NULL) { - return TABLE_ERROR_ARG_NULL; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (key_buf == NULL) { + return TABLE_ERROR_ARG_NULL; + } #ifndef NO_MMAP - /* no mmap support so immediate error */ - if (table_p->ta_mmap != NULL) { - return TABLE_ERROR_MMAP_OP; - } + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } #endif - /* get the key size */ - if (key_size < 0) { - ksize = strlen((char *)key_buf) + sizeof(char); - } - else { - ksize = key_size; - } + /* get the key size */ + if (key_size < 0) { + ksize = strlen((char *)key_buf) + sizeof(char); + } + else { + ksize = key_size; + } - /* find our bucket */ - bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; + /* find our bucket */ + bucket = hash(key_buf, ksize, 0) % table_p->ta_bucket_n; - /* look for the entry in this bucket, only check keys of the same size */ - for (last_p = NULL, entry_p = table_p->ta_buckets[bucket]; - entry_p != NULL; - last_p = entry_p, entry_p = entry_p->te_next_p) { - if (entry_p->te_key_size == ksize - && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { - break; - } - } + /* look for the entry in this bucket, only check keys of the same size */ + for (last_p = NULL, entry_p = table_p->ta_buckets[bucket]; + entry_p != NULL; + last_p = entry_p, entry_p = entry_p->te_next_p) { + if (entry_p->te_key_size == ksize + && memcmp(ENTRY_KEY_BUF(entry_p), key_buf, ksize) == 0) { + break; + } + } - /* did we find it? */ - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + /* did we find it? */ + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - /* - * NOTE: we may want to adjust the linear counters here if the entry - * we are deleting is the one we are pointing on or is ahead of the - * one in the bucket list - */ + /* + * NOTE: we may want to adjust the linear counters here if the entry + * we are deleting is the one we are pointing on or is ahead of the + * one in the bucket list + */ - /* remove entry from the linked list */ - if (last_p == NULL) { - table_p->ta_buckets[bucket] = entry_p->te_next_p; - } - else { - last_p->te_next_p = entry_p->te_next_p; - } + /* remove entry from the linked list */ + if (last_p == NULL) { + table_p->ta_buckets[bucket] = entry_p->te_next_p; + } + else { + last_p->te_next_p = entry_p->te_next_p; + } - /* free entry */ - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - /* - * if we were storing it compacted, we now need to malloc some - * space if the user wants the value after the delete. - */ - if (table_p->ta_alloc_func == NULL) { - *data_buf_p = malloc(entry_p->te_data_size); - } - else { - *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, - entry_p->te_data_size); - } - if (*data_buf_p == NULL) { - return TABLE_ERROR_ALLOC; - } - if (table_p->ta_data_align == 0) { - data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - data_copy_p = entry_data_buf(table_p, entry_p); - } - memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size); - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); - if (table_p->ta_free_func == NULL) { - free(entry_p); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, - entry_size(table_p, - entry_p->te_key_size, - entry_p->te_data_size))) { - return TABLE_ERROR_FREE; - } + /* free entry */ + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + /* + * if we were storing it compacted, we now need to malloc some + * space if the user wants the value after the delete. + */ + if (table_p->ta_alloc_func == NULL) { + *data_buf_p = malloc(entry_p->te_data_size); + } + else { + *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, + entry_p->te_data_size); + } + if (*data_buf_p == NULL) { + return TABLE_ERROR_ALLOC; + } + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size); + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + if (table_p->ta_free_func == NULL) { + free(entry_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + entry_size(table_p, + entry_p->te_key_size, + entry_p->te_data_size))) { + return TABLE_ERROR_FREE; + } - table_p->ta_entry_n--; + table_p->ta_entry_n--; - /* do we need auto-adjust down? */ - if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) - && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN) - && SHOULD_TABLE_SHRINK(table_p)) { - return table_adjust(table_p, table_p->ta_entry_n); - } + /* do we need auto-adjust down? */ + if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) + && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN) + && SHOULD_TABLE_SHRINK(table_p)) { + return table_adjust(table_p, table_p->ta_entry_n); + } - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2158,116 +2162,116 @@ int table_delete(table_t *table_p, * associated with the key. */ int table_delete_first(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - unsigned char *data_copy_p; - table_entry_t *entry_p; - table_linear_t linear; + unsigned char *data_copy_p; + table_entry_t *entry_p; + table_linear_t linear; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } #ifndef NO_MMAP - /* no mmap support so immediate error */ - if (table_p->ta_mmap != NULL) { - return TABLE_ERROR_MMAP_OP; - } + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } #endif - /* take the first entry */ - entry_p = first_entry(table_p, &linear); - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + /* take the first entry */ + entry_p = first_entry(table_p, &linear); + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - /* - * NOTE: we may want to adjust the linear counters here if the entry - * we are deleting is the one we are pointing on or is ahead of the - * one in the bucket list - */ + /* + * NOTE: we may want to adjust the linear counters here if the entry + * we are deleting is the one we are pointing on or is ahead of the + * one in the bucket list + */ - /* remove entry from the linked list */ - table_p->ta_buckets[linear.tl_bucket_c] = entry_p->te_next_p; + /* remove entry from the linked list */ + table_p->ta_buckets[linear.tl_bucket_c] = entry_p->te_next_p; - /* free entry */ - if (key_buf_p != NULL) { - if (entry_p->te_key_size == 0) { - *key_buf_p = NULL; - } - else { - /* - * if we were storing it compacted, we now need to malloc some - * space if the user wants the value after the delete. - */ - if (table_p->ta_alloc_func == NULL) { - *key_buf_p = malloc(entry_p->te_key_size); - } - else { - *key_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, - entry_p->te_key_size); - } - if (*key_buf_p == NULL) { - return TABLE_ERROR_ALLOC; - } - memcpy(*key_buf_p, ENTRY_KEY_BUF(entry_p), entry_p->te_key_size); - } - } - SET_POINTER(key_size_p, entry_p->te_key_size); + /* free entry */ + if (key_buf_p != NULL) { + if (entry_p->te_key_size == 0) { + *key_buf_p = NULL; + } + else { + /* + * if we were storing it compacted, we now need to malloc some + * space if the user wants the value after the delete. + */ + if (table_p->ta_alloc_func == NULL) { + *key_buf_p = malloc(entry_p->te_key_size); + } + else { + *key_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, + entry_p->te_key_size); + } + if (*key_buf_p == NULL) { + return TABLE_ERROR_ALLOC; + } + memcpy(*key_buf_p, ENTRY_KEY_BUF(entry_p), entry_p->te_key_size); + } + } + SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - /* - * if we were storing it compacted, we now need to malloc some - * space if the user wants the value after the delete. - */ - if (table_p->ta_alloc_func == NULL) { - *data_buf_p = malloc(entry_p->te_data_size); - } - else { - *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, - entry_p->te_data_size); - } - if (*data_buf_p == NULL) { - return TABLE_ERROR_ALLOC; - } - if (table_p->ta_data_align == 0) { - data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - data_copy_p = entry_data_buf(table_p, entry_p); - } - memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size); - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); - if (table_p->ta_free_func == NULL) { - free(entry_p); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, - entry_size(table_p, - entry_p->te_key_size, - entry_p->te_data_size))) { - return TABLE_ERROR_FREE; - } + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + /* + * if we were storing it compacted, we now need to malloc some + * space if the user wants the value after the delete. + */ + if (table_p->ta_alloc_func == NULL) { + *data_buf_p = malloc(entry_p->te_data_size); + } + else { + *data_buf_p = table_p->ta_alloc_func(table_p->ta_mem_pool, + entry_p->te_data_size); + } + if (*data_buf_p == NULL) { + return TABLE_ERROR_ALLOC; + } + if (table_p->ta_data_align == 0) { + data_copy_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + data_copy_p = entry_data_buf(table_p, entry_p); + } + memcpy(*data_buf_p, data_copy_p, entry_p->te_data_size); + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); + if (table_p->ta_free_func == NULL) { + free(entry_p); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, entry_p, + entry_size(table_p, + entry_p->te_key_size, + entry_p->te_data_size))) { + return TABLE_ERROR_FREE; + } - table_p->ta_entry_n--; + table_p->ta_entry_n--; - /* do we need auto-adjust down? */ - if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) - && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN) - && SHOULD_TABLE_SHRINK(table_p)) { - return table_adjust(table_p, table_p->ta_entry_n); - } + /* do we need auto-adjust down? */ + if ((table_p->ta_flags & TABLE_FLAG_AUTO_ADJUST) + && (table_p->ta_flags & TABLE_FLAG_ADJUST_DOWN) + && SHOULD_TABLE_SHRINK(table_p)) { + return table_adjust(table_p, table_p->ta_entry_n); + } - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2296,17 +2300,17 @@ int table_delete_first(table_t *table_p, */ int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p) { - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } - SET_POINTER(num_buckets_p, table_p->ta_bucket_n); - SET_POINTER(num_entries_p, table_p->ta_entry_n); + SET_POINTER(num_buckets_p, table_p->ta_bucket_n); + SET_POINTER(num_entries_p, table_p->ta_entry_n); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2331,111 +2335,111 @@ int table_info(table_t *table_p, int *num_buckets_p, int *num_entries_p) */ int table_adjust(table_t *table_p, const int bucket_n) { - table_entry_t *entry_p, *next_p; - table_entry_t **buckets, **bucket_p, **bounds_p; - int bucket; - unsigned int buck_n, bucket_size; + table_entry_t *entry_p, *next_p; + table_entry_t **buckets, **bucket_p, **bounds_p; + int bucket; + unsigned int buck_n, bucket_size; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } #ifndef NO_MMAP - /* no mmap support so immediate error */ - if (table_p->ta_mmap != NULL) { - return TABLE_ERROR_MMAP_OP; - } + /* no mmap support so immediate error */ + if (table_p->ta_mmap != NULL) { + return TABLE_ERROR_MMAP_OP; + } #endif - /* - * NOTE: we walk through the entries and rehash them. If we stored - * the hash value as a full int in the table-entry, all we would - * have to do is remod it. - */ + /* + * NOTE: we walk through the entries and rehash them. If we stored + * the hash value as a full int in the table-entry, all we would + * have to do is remod it. + */ - /* normalize to the number of entries */ - if (bucket_n == 0) { - buck_n = table_p->ta_entry_n; - } - else { - buck_n = bucket_n; - } + /* normalize to the number of entries */ + if (bucket_n == 0) { + buck_n = table_p->ta_entry_n; + } + else { + buck_n = bucket_n; + } - /* we must have at least 1 bucket */ - if (buck_n == 0) { - buck_n = 1; - } + /* we must have at least 1 bucket */ + if (buck_n == 0) { + buck_n = 1; + } - (void)printf("growing table to %d\n", buck_n); + (void)printf("growing table to %d\n", buck_n); - /* make sure we have something to do */ - if (buck_n == table_p->ta_bucket_n) { - return TABLE_ERROR_NONE; - } + /* make sure we have something to do */ + if (buck_n == table_p->ta_bucket_n) { + return TABLE_ERROR_NONE; + } - /* allocate a new bucket list */ - bucket_size = buck_n * sizeof(table_entry_t *); - if (table_p->ta_alloc_func == NULL) { - buckets = (table_entry_t **)malloc(bucket_size); - } - else { - buckets = - (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, - bucket_size); - } - if (buckets == NULL) { - return TABLE_ERROR_ALLOC; - } - /* - * We zero it ourselves to save the necessity of having a - * table_mem_calloc_t memory override function. - */ - memset(buckets, 0, bucket_size); + /* allocate a new bucket list */ + bucket_size = buck_n * sizeof(table_entry_t *); + if (table_p->ta_alloc_func == NULL) { + buckets = (table_entry_t **)malloc(bucket_size); + } + else { + buckets = + (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, + bucket_size); + } + if (buckets == NULL) { + return TABLE_ERROR_ALLOC; + } + /* + * We zero it ourselves to save the necessity of having a + * table_mem_calloc_t memory override function. + */ + memset(buckets, 0, bucket_size); - /* - * run through each of the items in the current table and rehash - * them into the newest bucket sizes - */ - bounds_p = table_p->ta_buckets + table_p->ta_bucket_n; - for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) { - for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) { + /* + * run through each of the items in the current table and rehash + * them into the newest bucket sizes + */ + bounds_p = table_p->ta_buckets + table_p->ta_bucket_n; + for (bucket_p = table_p->ta_buckets; bucket_p < bounds_p; bucket_p++) { + for (entry_p = *bucket_p; entry_p != NULL; entry_p = next_p) { - /* hash the old data into the new table size */ - bucket = hash(ENTRY_KEY_BUF(entry_p), entry_p->te_key_size, 0) % buck_n; + /* hash the old data into the new table size */ + bucket = hash(ENTRY_KEY_BUF(entry_p), entry_p->te_key_size, 0) % buck_n; - /* record the next one now since we overwrite next below */ - next_p = entry_p->te_next_p; + /* record the next one now since we overwrite next below */ + next_p = entry_p->te_next_p; - /* insert into new list, no need to append */ - entry_p->te_next_p = buckets[bucket]; - buckets[bucket] = entry_p; + /* insert into new list, no need to append */ + entry_p->te_next_p = buckets[bucket]; + buckets[bucket] = entry_p; - /* - * NOTE: we may want to adjust the bucket_c linear entry here to - * keep it current - */ - } - /* remove the old table pointers as we go by */ - *bucket_p = NULL; - } + /* + * NOTE: we may want to adjust the bucket_c linear entry here to + * keep it current + */ + } + /* remove the old table pointers as we go by */ + *bucket_p = NULL; + } - /* replace the table buckets with the new ones */ - if (table_p->ta_free_func == NULL) { - free(table_p->ta_buckets); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, - table_p->ta_buckets, - table_p->ta_bucket_n * - sizeof(table_entry_t *))) { - return TABLE_ERROR_FREE; - } - table_p->ta_buckets = buckets; - table_p->ta_bucket_n = buck_n; + /* replace the table buckets with the new ones */ + if (table_p->ta_free_func == NULL) { + free(table_p->ta_buckets); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, + table_p->ta_buckets, + table_p->ta_bucket_n * + sizeof(table_entry_t *))) { + return TABLE_ERROR_FREE; + } + table_p->ta_buckets = buckets; + table_p->ta_bucket_n = buck_n; - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2455,7 +2459,7 @@ int table_adjust(table_t *table_p, const int bucket_n) */ int table_type_size(void) { - return sizeof(table_t); + return sizeof(table_t); } /************************* linear access routines ****************************/ @@ -2504,44 +2508,44 @@ int table_type_size(void) * associated with the first key. */ int table_first(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p; + table_entry_t *entry_p; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } - /* initialize our linear magic number */ - table_p->ta_linear.tl_magic = LINEAR_MAGIC; + /* initialize our linear magic number */ + table_p->ta_linear.tl_magic = LINEAR_MAGIC; - entry_p = first_entry(table_p, &table_p->ta_linear); - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + entry_p = first_entry(table_p, &table_p->ta_linear); + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2588,46 +2592,46 @@ int table_first(table_t *table_p, * associated with the next key. */ int table_next(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p; - int error; + table_entry_t *entry_p; + int error; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) { - return TABLE_ERROR_LINEAR; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } - /* move to the next entry */ - entry_p = next_entry(table_p, &table_p->ta_linear, &error); - if (entry_p == NULL) { - return error; - } + /* move to the next entry */ + entry_p = next_entry(table_p, &table_p->ta_linear, &error); + if (entry_p == NULL) { + return error; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2673,65 +2677,65 @@ int table_next(table_t *table_p, * associated with the current key. */ int table_this(table_t *table_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p = NULL; - int entry_c; + table_entry_t *entry_p = NULL; + int entry_c; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) { - return TABLE_ERROR_LINEAR; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_linear.tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } - /* if we removed an item that shorted the bucket list, we may get this */ - if (table_p->ta_linear.tl_bucket_c >= table_p->ta_bucket_n) { - /* - * NOTE: this might happen if we delete an item which shortens the - * table bucket numbers. - */ - return TABLE_ERROR_NOT_FOUND; - } + /* if we removed an item that shorted the bucket list, we may get this */ + if (table_p->ta_linear.tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + return TABLE_ERROR_NOT_FOUND; + } - /* find the entry which is the nth in the list */ - entry_p = table_p->ta_buckets[table_p->ta_linear.tl_bucket_c]; - /* NOTE: we swap the order here to be more efficient */ - for (entry_c = table_p->ta_linear.tl_entry_c; entry_c > 0; entry_c--) { - /* did we reach the end of the list? */ - if (entry_p == NULL) { - break; - } - entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; - } + /* find the entry which is the nth in the list */ + entry_p = table_p->ta_buckets[table_p->ta_linear.tl_bucket_c]; + /* NOTE: we swap the order here to be more efficient */ + for (entry_c = table_p->ta_linear.tl_entry_c; entry_c > 0; entry_c--) { + /* did we reach the end of the list? */ + if (entry_p == NULL) { + break; + } + entry_p = TABLE_POINTER(table_p, table_entry_t *, entry_p)->te_next_p; + } - /* is this a NOT_FOUND or a LINEAR error */ - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + /* is this a NOT_FOUND or a LINEAR error */ + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2779,47 +2783,47 @@ int table_this(table_t *table_p, * associated with the first key. */ int table_first_r(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p; + table_entry_t *entry_p; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (linear_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } - /* initialize our linear magic number */ - linear_p->tl_magic = LINEAR_MAGIC; + /* initialize our linear magic number */ + linear_p->tl_magic = LINEAR_MAGIC; - entry_p = first_entry(table_p, linear_p); - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + entry_p = first_entry(table_p, linear_p); + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2867,49 +2871,49 @@ int table_first_r(table_t *table_p, table_linear_t *linear_p, * associated with the next key. */ int table_next_r(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p; - int error; + table_entry_t *entry_p; + int error; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (linear_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (linear_p->tl_magic != LINEAR_MAGIC) { - return TABLE_ERROR_LINEAR; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (linear_p->tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } - /* move to the next entry */ - entry_p = next_entry(table_p, linear_p, &error); - if (entry_p == NULL) { - return error; - } + /* move to the next entry */ + entry_p = next_entry(table_p, linear_p, &error); + if (entry_p == NULL) { + return error; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -2957,61 +2961,61 @@ int table_next_r(table_t *table_p, table_linear_t *linear_p, * associated with the current key. */ int table_this_r(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p; - int entry_c; + table_entry_t *entry_p; + int entry_c; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (linear_p->tl_magic != LINEAR_MAGIC) { - return TABLE_ERROR_LINEAR; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p->tl_magic != LINEAR_MAGIC) { + return TABLE_ERROR_LINEAR; + } - /* if we removed an item that shorted the bucket list, we may get this */ - if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { - /* - * NOTE: this might happen if we delete an item which shortens the - * table bucket numbers. - */ - return TABLE_ERROR_NOT_FOUND; - } + /* if we removed an item that shorted the bucket list, we may get this */ + if (linear_p->tl_bucket_c >= table_p->ta_bucket_n) { + /* + * NOTE: this might happen if we delete an item which shortens the + * table bucket numbers. + */ + return TABLE_ERROR_NOT_FOUND; + } - /* find the entry which is the nth in the list */ - for (entry_c = linear_p->tl_entry_c, - entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; - entry_p != NULL && entry_c > 0; - entry_c--, entry_p = TABLE_POINTER(table_p, table_entry_t *, - entry_p)->te_next_p) { - } + /* find the entry which is the nth in the list */ + for (entry_c = linear_p->tl_entry_c, + entry_p = table_p->ta_buckets[linear_p->tl_bucket_c]; + entry_p != NULL && entry_c > 0; + entry_c--, entry_p = TABLE_POINTER(table_p, table_entry_t *, + entry_p)->te_next_p) { + } - if (entry_p == NULL) { - return TABLE_ERROR_NOT_FOUND; - } + if (entry_p == NULL) { + return TABLE_ERROR_NOT_FOUND; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /******************************* mmap routines *******************************/ @@ -3040,81 +3044,81 @@ table_t *table_mmap(const char *path, int *error_p) { #ifdef NO_MMAP - /* no mmap support so immediate error */ - SET_POINTER(error_p, TABLE_ERROR_MMAP_NONE); - return NULL; + /* no mmap support so immediate error */ + SET_POINTER(error_p, TABLE_ERROR_MMAP_NONE); + return NULL; #else - table_t *table_p; - struct stat sbuf; - int fd, state; + table_t *table_p; + struct stat sbuf; + int fd, state; - table_p = (table_t *)malloc(sizeof(table_t)); - if (table_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - return NULL; - } + table_p = (table_t *)malloc(sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } - /* open the mmap file */ - fd = open(path, O_RDONLY, 0); - if (fd < 0) { - free(table_p); - SET_POINTER(error_p, TABLE_ERROR_OPEN); - return NULL; - } + /* open the mmap file */ + fd = open(path, O_RDONLY, 0); + if (fd < 0) { + free(table_p); + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } - /* get the file size */ - if (fstat(fd, &sbuf) != 0) { - free(table_p); - SET_POINTER(error_p, TABLE_ERROR_OPEN); - return NULL; - } + /* get the file size */ + if (fstat(fd, &sbuf) != 0) { + free(table_p); + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } - /* mmap the space and close the file */ + /* mmap the space and close the file */ #ifdef __alpha - state = (MAP_SHARED | MAP_FILE | MAP_VARIABLE); + state = (MAP_SHARED | MAP_FILE | MAP_VARIABLE); #else - state = MAP_SHARED; + state = MAP_SHARED; #endif - table_p->ta_mmap = (table_t *)mmap((caddr_t)0, sbuf.st_size, PROT_READ, - state, fd, 0); - (void)close(fd); + table_p->ta_mmap = (table_t *)mmap((caddr_t)0, sbuf.st_size, PROT_READ, + state, fd, 0); + (void)close(fd); - if (table_p->ta_mmap == (table_t *)MAP_FAILED) { - SET_POINTER(error_p, TABLE_ERROR_MMAP); - return NULL; - } + if (table_p->ta_mmap == (table_t *)MAP_FAILED) { + SET_POINTER(error_p, TABLE_ERROR_MMAP); + return NULL; + } - /* is the mmap file contain bad info or maybe another system type? */ - if (table_p->ta_mmap->ta_magic != TABLE_MAGIC) { - SET_POINTER(error_p, TABLE_ERROR_PNT); - return NULL; - } + /* is the mmap file contain bad info or maybe another system type? */ + if (table_p->ta_mmap->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } - /* sanity check on the file size */ - if (table_p->ta_mmap->ta_file_size != sbuf.st_size) { - SET_POINTER(error_p, TABLE_ERROR_SIZE); - return NULL; - } + /* sanity check on the file size */ + if (table_p->ta_mmap->ta_file_size != sbuf.st_size) { + SET_POINTER(error_p, TABLE_ERROR_SIZE); + return NULL; + } - /* copy the fields out of the mmap file into our memory version */ - table_p->ta_magic = TABLE_MAGIC; - table_p->ta_flags = table_p->ta_mmap->ta_flags; - table_p->ta_bucket_n = table_p->ta_mmap->ta_bucket_n; - table_p->ta_entry_n = table_p->ta_mmap->ta_entry_n; - table_p->ta_data_align = table_p->ta_mmap->ta_data_align; - table_p->ta_buckets = TABLE_POINTER(table_p, table_entry_t **, - table_p->ta_mmap->ta_buckets); - table_p->ta_linear.tl_magic = 0; - table_p->ta_linear.tl_bucket_c = 0; - table_p->ta_linear.tl_entry_c = 0; - /* mmap is already set */ - table_p->ta_file_size = table_p->ta_mmap->ta_file_size; + /* copy the fields out of the mmap file into our memory version */ + table_p->ta_magic = TABLE_MAGIC; + table_p->ta_flags = table_p->ta_mmap->ta_flags; + table_p->ta_bucket_n = table_p->ta_mmap->ta_bucket_n; + table_p->ta_entry_n = table_p->ta_mmap->ta_entry_n; + table_p->ta_data_align = table_p->ta_mmap->ta_data_align; + table_p->ta_buckets = TABLE_POINTER(table_p, table_entry_t **, + table_p->ta_mmap->ta_buckets); + table_p->ta_linear.tl_magic = 0; + table_p->ta_linear.tl_bucket_c = 0; + table_p->ta_linear.tl_entry_c = 0; + /* mmap is already set */ + table_p->ta_file_size = table_p->ta_mmap->ta_file_size; - SET_POINTER(error_p, TABLE_ERROR_NONE); - return table_p; + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; #endif } @@ -3138,25 +3142,25 @@ int table_munmap(table_t *table_p) { #ifdef NO_MMAP - /* no mmap support so immediate error */ - return TABLE_ERROR_MMAP_NONE; + /* no mmap support so immediate error */ + return TABLE_ERROR_MMAP_NONE; #else - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (table_p->ta_mmap == NULL) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (table_p->ta_mmap == NULL) { + return TABLE_ERROR_PNT; + } - (void)munmap((caddr_t)table_p->ta_mmap, table_p->ta_file_size); - table_p->ta_magic = 0; - free(table_p); - return TABLE_ERROR_NONE; + (void)munmap((caddr_t)table_p->ta_mmap, table_p->ta_file_size); + table_p->ta_magic = 0; + free(table_p); + return TABLE_ERROR_NONE; #endif } @@ -3187,146 +3191,146 @@ int table_munmap(table_t *table_p) */ table_t *table_read(const char *path, int *error_p) { - unsigned int size; - int fd, ent_size; - FILE *infile; - table_entry_t entry, **bucket_p, *entry_p = NULL, *last_p; - unsigned long pos; - table_t *table_p; + unsigned int size; + int fd, ent_size; + FILE *infile; + table_entry_t entry, **bucket_p, *entry_p = NULL, *last_p; + unsigned long pos; + table_t *table_p; - /* open the file */ - fd = open(path, O_RDONLY, 0); - if (fd < 0) { - SET_POINTER(error_p, TABLE_ERROR_OPEN); - return NULL; - } - - /* allocate a table structure */ - table_p = malloc(sizeof(table_t)); - if (table_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - return NULL; - } - - /* now open the fd to get buffered i/o */ - infile = fdopen(fd, "r"); - if (infile == NULL) { - SET_POINTER(error_p, TABLE_ERROR_OPEN); - return NULL; - } - - /* read the main table struct */ - if (fread(table_p, sizeof(table_t), 1, infile) != 1) { - SET_POINTER(error_p, TABLE_ERROR_READ); - free(table_p); - return NULL; - } - table_p->ta_file_size = 0; - - /* is the mmap file contain bad info or maybe another system type? */ - if (table_p->ta_magic != TABLE_MAGIC) { - SET_POINTER(error_p, TABLE_ERROR_PNT); - return NULL; - } - - /* allocate the buckets */ - table_p->ta_buckets = (table_entry_t **)calloc(table_p->ta_bucket_n, - sizeof(table_entry_t *)); - if (table_p->ta_buckets == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - free(table_p); - return NULL; - } - - if (fread(table_p->ta_buckets, sizeof(table_entry_t *), table_p->ta_bucket_n, - infile) != (size_t)table_p->ta_bucket_n) { - SET_POINTER(error_p, TABLE_ERROR_READ); - free(table_p->ta_buckets); - free(table_p); - return NULL; - } - - /* read in the entries */ - for (bucket_p = table_p->ta_buckets; - bucket_p < table_p->ta_buckets + table_p->ta_bucket_n; - bucket_p++) { - - /* skip null buckets */ - if (*bucket_p == NULL) { - continue; - } - - /* run through the entry list */ - last_p = NULL; - for (pos = *(unsigned long *)bucket_p;; - pos = (unsigned long)entry_p->te_next_p) { - - /* read in the entry */ - if (fseek(infile, pos, SEEK_SET) != 0) { - SET_POINTER(error_p, TABLE_ERROR_SEEK); - free(table_p->ta_buckets); - free(table_p); - if (entry_p != NULL) { - free(entry_p); + /* open the file */ + fd = open(path, O_RDONLY, 0); + if (fd < 0) { + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; } - /* the other table elements will not be freed */ - return NULL; - } - if (fread(&entry, sizeof(struct table_shell_st), 1, infile) != 1) { - SET_POINTER(error_p, TABLE_ERROR_READ); - free(table_p->ta_buckets); - free(table_p); - if (entry_p != NULL) { - free(entry_p); + + /* allocate a table structure */ + table_p = malloc(sizeof(table_t)); + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; } - /* the other table elements will not be freed */ - return NULL; - } - - /* make a new entry */ - ent_size = entry_size(table_p, entry.te_key_size, entry.te_data_size); - entry_p = (table_entry_t *)malloc(ent_size); - if (entry_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - free(table_p->ta_buckets); - free(table_p); - /* the other table elements will not be freed */ - return NULL; - } - entry_p->te_key_size = entry.te_key_size; - entry_p->te_data_size = entry.te_data_size; - entry_p->te_next_p = entry.te_next_p; - - if (last_p == NULL) { - *bucket_p = entry_p; - } - else { - last_p->te_next_p = entry_p; - } - - /* determine how much more we have to read */ - size = ent_size - sizeof(struct table_shell_st); - if (fread(ENTRY_KEY_BUF(entry_p), sizeof(char), size, infile) != size) { - SET_POINTER(error_p, TABLE_ERROR_READ); - free(table_p->ta_buckets); - free(table_p); - free(entry_p); - /* the other table elements will not be freed */ - return NULL; - } - - /* we are done if the next pointer is null */ - if (entry_p->te_next_p == (unsigned long)0) { - break; - } - last_p = entry_p; - } - } - (void)fclose(infile); + /* now open the fd to get buffered i/o */ + infile = fdopen(fd, "r"); + if (infile == NULL) { + SET_POINTER(error_p, TABLE_ERROR_OPEN); + return NULL; + } - SET_POINTER(error_p, TABLE_ERROR_NONE); - return table_p; + /* read the main table struct */ + if (fread(table_p, sizeof(table_t), 1, infile) != 1) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p); + return NULL; + } + table_p->ta_file_size = 0; + + /* is the mmap file contain bad info or maybe another system type? */ + if (table_p->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } + + /* allocate the buckets */ + table_p->ta_buckets = (table_entry_t **)calloc(table_p->ta_bucket_n, + sizeof(table_entry_t *)); + if (table_p->ta_buckets == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + free(table_p); + return NULL; + } + + if (fread(table_p->ta_buckets, sizeof(table_entry_t *), table_p->ta_bucket_n, + infile) != (size_t)table_p->ta_bucket_n) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p->ta_buckets); + free(table_p); + return NULL; + } + + /* read in the entries */ + for (bucket_p = table_p->ta_buckets; + bucket_p < table_p->ta_buckets + table_p->ta_bucket_n; + bucket_p++) { + + /* skip null buckets */ + if (*bucket_p == NULL) { + continue; + } + + /* run through the entry list */ + last_p = NULL; + for (pos = *(unsigned long *)bucket_p;; + pos = (unsigned long)entry_p->te_next_p) { + + /* read in the entry */ + if (fseek(infile, pos, SEEK_SET) != 0) { + SET_POINTER(error_p, TABLE_ERROR_SEEK); + free(table_p->ta_buckets); + free(table_p); + if (entry_p != NULL) { + free(entry_p); + } + /* the other table elements will not be freed */ + return NULL; + } + if (fread(&entry, sizeof(struct table_shell_st), 1, infile) != 1) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p->ta_buckets); + free(table_p); + if (entry_p != NULL) { + free(entry_p); + } + /* the other table elements will not be freed */ + return NULL; + } + + /* make a new entry */ + ent_size = entry_size(table_p, entry.te_key_size, entry.te_data_size); + entry_p = (table_entry_t *)malloc(ent_size); + if (entry_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + free(table_p->ta_buckets); + free(table_p); + /* the other table elements will not be freed */ + return NULL; + } + entry_p->te_key_size = entry.te_key_size; + entry_p->te_data_size = entry.te_data_size; + entry_p->te_next_p = entry.te_next_p; + + if (last_p == NULL) { + *bucket_p = entry_p; + } + else { + last_p->te_next_p = entry_p; + } + + /* determine how much more we have to read */ + size = ent_size - sizeof(struct table_shell_st); + if (fread(ENTRY_KEY_BUF(entry_p), sizeof(char), size, infile) != size) { + SET_POINTER(error_p, TABLE_ERROR_READ); + free(table_p->ta_buckets); + free(table_p); + free(entry_p); + /* the other table elements will not be freed */ + return NULL; + } + + /* we are done if the next pointer is null */ + if (entry_p->te_next_p == (unsigned long)0) { + break; + } + last_p = entry_p; + } + } + + (void)fclose(infile); + + SET_POINTER(error_p, TABLE_ERROR_NONE); + return table_p; } /* @@ -3353,186 +3357,186 @@ table_t *table_read(const char *path, int *error_p) */ int table_write(const table_t *table_p, const char *path, const int mode) { - int fd, rem, ent_size; - unsigned int bucket_c, bucket_size; - unsigned long size; - table_entry_t *entry_p, **buckets, **bucket_p, *next_p; - table_t main_tab; - FILE *outfile; + int fd, rem, ent_size; + unsigned int bucket_c, bucket_size; + unsigned long size; + table_entry_t *entry_p, **buckets, **bucket_p, *next_p; + table_t main_tab; + FILE *outfile; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } - fd = open(path, O_WRONLY | O_CREAT, mode); - if (fd < 0) { - return TABLE_ERROR_OPEN; - } + fd = open(path, O_WRONLY | O_CREAT, mode); + if (fd < 0) { + return TABLE_ERROR_OPEN; + } - outfile = fdopen(fd, "w"); - if (outfile == NULL) { - return TABLE_ERROR_OPEN; - } + outfile = fdopen(fd, "w"); + if (outfile == NULL) { + return TABLE_ERROR_OPEN; + } - /* allocate a block of sizes for each bucket */ - bucket_size = sizeof(table_entry_t *) * table_p->ta_bucket_n; - if (table_p->ta_alloc_func == NULL) { - buckets = (table_entry_t **)malloc(bucket_size); - } - else { - buckets = - (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, - bucket_size); - } - if (buckets == NULL) { - return TABLE_ERROR_ALLOC; - } - - /* make a copy of the main struct */ - main_tab = *table_p; - - /* start counting the bytes */ - size = 0; - size += sizeof(table_t); - - /* buckets go right after main struct */ - main_tab.ta_buckets = (table_entry_t **)size; - size += sizeof(table_entry_t *) * table_p->ta_bucket_n; - - /* run through and count the buckets */ - for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) { - bucket_p = table_p->ta_buckets + bucket_c; - if (*bucket_p == NULL) { - buckets[bucket_c] = NULL; - continue; - } - buckets[bucket_c] = (table_entry_t *)size; - for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) { - size += entry_size(table_p, entry_p->te_key_size, entry_p->te_data_size); - /* - * We now have to round the file to the nearest long so the - * mmaping of the longs in the entry structs will work. - */ - rem = size & (sizeof(long) - 1); - if (rem > 0) { - size += sizeof(long) - rem; - } - } - } - /* add a \0 at the end to fill the last section */ - size++; - - /* set the main fields */ - main_tab.ta_linear.tl_magic = 0; - main_tab.ta_linear.tl_bucket_c = 0; - main_tab.ta_linear.tl_entry_c = 0; - main_tab.ta_mmap = NULL; - main_tab.ta_file_size = size; - - /* - * Now we can start the writing because we got the bucket offsets. - */ - - /* write the main table struct */ - size = 0; - if (fwrite(&main_tab, sizeof(table_t), 1, outfile) != 1) { - if (table_p->ta_free_func == NULL) { - free(buckets); - } - else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size); - } - return TABLE_ERROR_WRITE; - } - size += sizeof(table_t); - if (fwrite(buckets, sizeof(table_entry_t *), table_p->ta_bucket_n, - outfile) != (size_t)table_p->ta_bucket_n) { - if (table_p->ta_free_func == NULL) { - free(buckets); - } - else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size); - } - return TABLE_ERROR_WRITE; - } - size += sizeof(table_entry_t *) * table_p->ta_bucket_n; - - /* write out the entries */ - for (bucket_p = table_p->ta_buckets; - bucket_p < table_p->ta_buckets + table_p->ta_bucket_n; - bucket_p++) { - for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) { - - ent_size = entry_size(table_p, entry_p->te_key_size, - entry_p->te_data_size); - size += ent_size; - /* round to nearest long here so we can write copy */ - rem = size & (sizeof(long) - 1); - if (rem > 0) { - size += sizeof(long) - rem; - } - next_p = entry_p->te_next_p; - if (next_p != NULL) { - entry_p->te_next_p = (table_entry_t *)size; - } - - /* now write to disk */ - if (fwrite(entry_p, ent_size, 1, outfile) != 1) { - if (table_p->ta_free_func == NULL) { - free(buckets); + /* allocate a block of sizes for each bucket */ + bucket_size = sizeof(table_entry_t *) * table_p->ta_bucket_n; + if (table_p->ta_alloc_func == NULL) { + buckets = (table_entry_t **)malloc(bucket_size); } else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, - bucket_size); + buckets = + (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, + bucket_size); } - return TABLE_ERROR_WRITE; - } - - /* restore the next pointer */ - if (next_p != NULL) { - entry_p->te_next_p = next_p; - } - - /* now write the padding information */ - if (rem > 0) { - rem = sizeof(long) - rem; + if (buckets == NULL) { + return TABLE_ERROR_ALLOC; + } + + /* make a copy of the main struct */ + main_tab = *table_p; + + /* start counting the bytes */ + size = 0; + size += sizeof(table_t); + + /* buckets go right after main struct */ + main_tab.ta_buckets = (table_entry_t **)size; + size += sizeof(table_entry_t *) * table_p->ta_bucket_n; + + /* run through and count the buckets */ + for (bucket_c = 0; bucket_c < table_p->ta_bucket_n; bucket_c++) { + bucket_p = table_p->ta_buckets + bucket_c; + if (*bucket_p == NULL) { + buckets[bucket_c] = NULL; + continue; + } + buckets[bucket_c] = (table_entry_t *)size; + for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) { + size += entry_size(table_p, entry_p->te_key_size, entry_p->te_data_size); + /* + * We now have to round the file to the nearest long so the + * mmaping of the longs in the entry structs will work. + */ + rem = size & (sizeof(long) - 1); + if (rem > 0) { + size += sizeof(long) - rem; + } + } + } + /* add a \0 at the end to fill the last section */ + size++; + + /* set the main fields */ + main_tab.ta_linear.tl_magic = 0; + main_tab.ta_linear.tl_bucket_c = 0; + main_tab.ta_linear.tl_entry_c = 0; + main_tab.ta_mmap = NULL; + main_tab.ta_file_size = size; + /* - * NOTE: this won't leave fseek'd space at the end but we - * don't care there because there is no accessed memory - * afterwards. We write 1 \0 at the end to make sure. + * Now we can start the writing because we got the bucket offsets. */ - if (fseek(outfile, rem, SEEK_CUR) != 0) { - if (table_p->ta_free_func == NULL) { - free(buckets); - } - else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, - bucket_size); - } - return TABLE_ERROR_SEEK; + + /* write the main table struct */ + size = 0; + if (fwrite(&main_tab, sizeof(table_t), 1, outfile) != 1) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size); + } + return TABLE_ERROR_WRITE; } - } - } - } - /* - * Write a \0 at the end of the file to make sure that the last - * fseek filled with nulls. - */ - (void)fputc('\0', outfile); + size += sizeof(table_t); + if (fwrite(buckets, sizeof(table_entry_t *), table_p->ta_bucket_n, + outfile) != (size_t)table_p->ta_bucket_n) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, bucket_size); + } + return TABLE_ERROR_WRITE; + } + size += sizeof(table_entry_t *) * table_p->ta_bucket_n; - (void)fclose(outfile); - if (table_p->ta_free_func == NULL) { - free(buckets); - } - else if (! table_p->ta_free_func(table_p->ta_mem_pool, buckets, - bucket_size)) { - return TABLE_ERROR_FREE; - } + /* write out the entries */ + for (bucket_p = table_p->ta_buckets; + bucket_p < table_p->ta_buckets + table_p->ta_bucket_n; + bucket_p++) { + for (entry_p = *bucket_p; entry_p != NULL; entry_p = entry_p->te_next_p) { + + ent_size = entry_size(table_p, entry_p->te_key_size, + entry_p->te_data_size); + size += ent_size; + /* round to nearest long here so we can write copy */ + rem = size & (sizeof(long) - 1); + if (rem > 0) { + size += sizeof(long) - rem; + } + next_p = entry_p->te_next_p; + if (next_p != NULL) { + entry_p->te_next_p = (table_entry_t *)size; + } + + /* now write to disk */ + if (fwrite(entry_p, ent_size, 1, outfile) != 1) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, + bucket_size); + } + return TABLE_ERROR_WRITE; + } + + /* restore the next pointer */ + if (next_p != NULL) { + entry_p->te_next_p = next_p; + } + + /* now write the padding information */ + if (rem > 0) { + rem = sizeof(long) - rem; + /* + * NOTE: this won't leave fseek'd space at the end but we + * don't care there because there is no accessed memory + * afterwards. We write 1 \0 at the end to make sure. + */ + if (fseek(outfile, rem, SEEK_CUR) != 0) { + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, buckets, + bucket_size); + } + return TABLE_ERROR_SEEK; + } + } + } + } + /* + * Write a \0 at the end of the file to make sure that the last + * fseek filled with nulls. + */ + (void)fputc('\0', outfile); - return TABLE_ERROR_NONE; + (void)fclose(outfile); + if (table_p->ta_free_func == NULL) { + free(buckets); + } + else if (! table_p->ta_free_func(table_p->ta_mem_pool, buckets, + bucket_size)) { + return TABLE_ERROR_FREE; + } + + return TABLE_ERROR_NONE; } /******************************** table order ********************************/ @@ -3572,104 +3576,104 @@ int table_write(const table_t *table_p, const char *path, const int mode) * table error code. */ table_entry_t **table_order(table_t *table_p, table_compare_t compare, - int *num_entries_p, int *error_p) + int *num_entries_p, int *error_p) { - table_entry_t *entry_p, **entries, **entries_p; - table_linear_t linear; - compare_t comp_func; - unsigned int entries_size; - int ret; + table_entry_t *entry_p, **entries, **entries_p; + table_linear_t linear; + compare_t comp_func; + unsigned int entries_size; + int ret; - if (table_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); - return NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - SET_POINTER(error_p, TABLE_ERROR_PNT); - return NULL; - } + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); + return NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } - /* there must be at least 1 element in the table for this to work */ - if (table_p->ta_entry_n == 0) { - SET_POINTER(error_p, TABLE_ERROR_EMPTY); - return NULL; - } + /* there must be at least 1 element in the table for this to work */ + if (table_p->ta_entry_n == 0) { + SET_POINTER(error_p, TABLE_ERROR_EMPTY); + return NULL; + } - entries_size = table_p->ta_entry_n * sizeof(table_entry_t *); - if (table_p->ta_alloc_func == NULL) { - entries = (table_entry_t **)malloc(entries_size); - } - else { - entries = - (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, - entries_size); - } - if (entries == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - return NULL; - } + entries_size = table_p->ta_entry_n * sizeof(table_entry_t *); + if (table_p->ta_alloc_func == NULL) { + entries = (table_entry_t **)malloc(entries_size); + } + else { + entries = + (table_entry_t **)table_p->ta_alloc_func(table_p->ta_mem_pool, + entries_size); + } + if (entries == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } - /* get a pointer to all entries */ - entry_p = first_entry(table_p, &linear); - if (entry_p == NULL) { - if (table_p->ta_free_func == NULL) { - free(entries); - } - else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); - } - SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); - return NULL; - } + /* get a pointer to all entries */ + entry_p = first_entry(table_p, &linear); + if (entry_p == NULL) { + if (table_p->ta_free_func == NULL) { + free(entries); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); + } + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } - /* add all of the entries to the array */ - for (entries_p = entries; - entry_p != NULL; - entry_p = next_entry(table_p, &linear, &ret)) { - *entries_p++ = entry_p; - } + /* add all of the entries to the array */ + for (entries_p = entries; + entry_p != NULL; + entry_p = next_entry(table_p, &linear, &ret)) { + *entries_p++ = entry_p; + } - if (ret != TABLE_ERROR_NOT_FOUND) { - if (table_p->ta_free_func == NULL) { - free(entries); - } - else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); - } - SET_POINTER(error_p, ret); - return NULL; - } + if (ret != TABLE_ERROR_NOT_FOUND) { + if (table_p->ta_free_func == NULL) { + free(entries); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); + } + SET_POINTER(error_p, ret); + return NULL; + } - if (compare == NULL) { - /* this is regardless of the alignment */ - comp_func = local_compare; - } - else if (table_p->ta_data_align == 0) { - comp_func = external_compare; - } - else { - comp_func = external_compare_align; - } + if (compare == NULL) { + /* this is regardless of the alignment */ + comp_func = local_compare; + } + else if (table_p->ta_data_align == 0) { + comp_func = external_compare; + } + else { + comp_func = external_compare_align; + } - /* now qsort the entire entries array from first to last element */ - ret = split((unsigned char *)entries, - (unsigned char *)(entries + table_p->ta_entry_n - 1), - sizeof(table_entry_t *), comp_func, compare, table_p); - if (ret != TABLE_ERROR_NONE) { - if (table_p->ta_free_func == NULL) { - free(entries); - } - else { - (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); - } - SET_POINTER(error_p, ret); - return NULL; - } + /* now qsort the entire entries array from first to last element */ + ret = split((unsigned char *)entries, + (unsigned char *)(entries + table_p->ta_entry_n - 1), + sizeof(table_entry_t *), comp_func, compare, table_p); + if (ret != TABLE_ERROR_NONE) { + if (table_p->ta_free_func == NULL) { + free(entries); + } + else { + (void)table_p->ta_free_func(table_p->ta_mem_pool, entries, entries_size); + } + SET_POINTER(error_p, ret); + return NULL; + } - SET_POINTER(num_entries_p, table_p->ta_entry_n); + SET_POINTER(num_entries_p, table_p->ta_entry_n); - SET_POINTER(error_p, TABLE_ERROR_NONE); - return entries; + SET_POINTER(error_p, TABLE_ERROR_NONE); + return entries; } /* @@ -3697,29 +3701,29 @@ table_entry_t **table_order(table_t *table_p, table_compare_t compare, * table_order or table_order_pos in num_entries_p. */ int table_order_free(table_t *table_p, table_entry_t **table_entries, - const int entry_n) + const int entry_n) { - int ret, final = TABLE_ERROR_NONE; + int ret, final = TABLE_ERROR_NONE; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } - if (table_p->ta_free_func == NULL) { - free(table_entries); - } - else { - ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries, - sizeof(table_entry_t *) * entry_n); - if (ret != 1) { - final = TABLE_ERROR_FREE; - } - } + if (table_p->ta_free_func == NULL) { + free(table_entries); + } + else { + ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries, + sizeof(table_entry_t *) * entry_n); + if (ret != 1) { + final = TABLE_ERROR_FREE; + } + } - return final; + return final; } /* @@ -3762,37 +3766,37 @@ int table_order_free(table_t *table_p, table_entry_t **table_entries, * to the size of the data that is stored in the table. */ int table_entry(table_t *table_p, table_entry_t *entry_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (entry_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (entry_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } - SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); - SET_POINTER(key_size_p, entry_p->te_key_size); - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - SET_POINTER(data_size_p, entry_p->te_data_size); + SET_POINTER(key_buf_p, ENTRY_KEY_BUF(entry_p)); + SET_POINTER(key_size_p, entry_p->te_key_size); + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + SET_POINTER(data_size_p, entry_p->te_data_size); - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -3830,84 +3834,84 @@ int table_entry(table_t *table_p, table_entry_t *entry_p, * table error code. */ table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare, - int *num_entries_p, int *error_p) + int *num_entries_p, int *error_p) { - table_entry_t *entry_p; - table_linear_t linear, *linears, *linears_p; - compare_t comp_func; - int ret; + table_entry_t *entry_p; + table_linear_t linear, *linears, *linears_p; + compare_t comp_func; + int ret; - if (table_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); - return NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - SET_POINTER(error_p, TABLE_ERROR_PNT); - return NULL; - } + if (table_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ARG_NULL); + return NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + SET_POINTER(error_p, TABLE_ERROR_PNT); + return NULL; + } - /* there must be at least 1 element in the table for this to work */ - if (table_p->ta_entry_n == 0) { - SET_POINTER(error_p, TABLE_ERROR_EMPTY); - return NULL; - } + /* there must be at least 1 element in the table for this to work */ + if (table_p->ta_entry_n == 0) { + SET_POINTER(error_p, TABLE_ERROR_EMPTY); + return NULL; + } - if (table_p->ta_alloc_func == NULL) { - linears = (table_linear_t *)malloc(table_p->ta_entry_n * - sizeof(table_linear_t)); - } - else { - linears = - (table_linear_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, - table_p->ta_entry_n * - sizeof(table_linear_t)); - } - if (linears == NULL) { - SET_POINTER(error_p, TABLE_ERROR_ALLOC); - return NULL; - } + if (table_p->ta_alloc_func == NULL) { + linears = (table_linear_t *)malloc(table_p->ta_entry_n * + sizeof(table_linear_t)); + } + else { + linears = + (table_linear_t *)table_p->ta_alloc_func(table_p->ta_mem_pool, + table_p->ta_entry_n * + sizeof(table_linear_t)); + } + if (linears == NULL) { + SET_POINTER(error_p, TABLE_ERROR_ALLOC); + return NULL; + } - /* get a pointer to all entries */ - entry_p = first_entry(table_p, &linear); - if (entry_p == NULL) { - SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); - return NULL; - } + /* get a pointer to all entries */ + entry_p = first_entry(table_p, &linear); + if (entry_p == NULL) { + SET_POINTER(error_p, TABLE_ERROR_NOT_FOUND); + return NULL; + } - /* add all of the entries to the array */ - for (linears_p = linears; - entry_p != NULL; - entry_p = next_entry(table_p, &linear, &ret)) { - *linears_p++ = linear; - } + /* add all of the entries to the array */ + for (linears_p = linears; + entry_p != NULL; + entry_p = next_entry(table_p, &linear, &ret)) { + *linears_p++ = linear; + } - if (ret != TABLE_ERROR_NOT_FOUND) { - SET_POINTER(error_p, ret); - return NULL; - } + if (ret != TABLE_ERROR_NOT_FOUND) { + SET_POINTER(error_p, ret); + return NULL; + } - if (compare == NULL) { - /* this is regardless of the alignment */ - comp_func = local_compare_pos; - } - else if (table_p->ta_data_align == 0) { - comp_func = external_compare_pos; - } - else { - comp_func = external_compare_align_pos; - } + if (compare == NULL) { + /* this is regardless of the alignment */ + comp_func = local_compare_pos; + } + else if (table_p->ta_data_align == 0) { + comp_func = external_compare_pos; + } + else { + comp_func = external_compare_align_pos; + } - /* now qsort the entire entries array from first to last element */ - split((unsigned char *)linears, - (unsigned char *)(linears + table_p->ta_entry_n - 1), - sizeof(table_linear_t), comp_func, compare, table_p); + /* now qsort the entire entries array from first to last element */ + split((unsigned char *)linears, + (unsigned char *)(linears + table_p->ta_entry_n - 1), + sizeof(table_linear_t), comp_func, compare, table_p); - if (num_entries_p != NULL) { - *num_entries_p = table_p->ta_entry_n; - } + if (num_entries_p != NULL) { + *num_entries_p = table_p->ta_entry_n; + } - SET_POINTER(error_p, TABLE_ERROR_NONE); - return linears; + SET_POINTER(error_p, TABLE_ERROR_NONE); + return linears; } /* @@ -3935,29 +3939,29 @@ table_linear_t *table_order_pos(table_t *table_p, table_compare_t compare, * table_order or table_order_pos in num_entries_p. */ int table_order_pos_free(table_t *table_p, table_linear_t *table_entries, - const int entry_n) + const int entry_n) { - int ret, final = TABLE_ERROR_NONE; + int ret, final = TABLE_ERROR_NONE; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } - if (table_p->ta_free_func == NULL) { - free(table_entries); - } - else { - ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries, - sizeof(table_linear_t) * entry_n); - if (ret != 1) { - final = TABLE_ERROR_FREE; - } - } + if (table_p->ta_free_func == NULL) { + free(table_entries); + } + else { + ret = table_p->ta_free_func(table_p->ta_mem_pool, table_entries, + sizeof(table_linear_t) * entry_n); + if (ret != 1) { + final = TABLE_ERROR_FREE; + } + } - return final; + return final; } /* @@ -4000,52 +4004,52 @@ int table_order_pos_free(table_t *table_p, table_linear_t *table_entries, * to the size of the data that is stored in the table. */ int table_entry_pos(table_t *table_p, table_linear_t *linear_p, - void **key_buf_p, int *key_size_p, - void **data_buf_p, int *data_size_p) + void **key_buf_p, int *key_size_p, + void **data_buf_p, int *data_size_p) { - table_entry_t *entry_p; - int ret; + table_entry_t *entry_p; + int ret; - if (table_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } - if (table_p->ta_magic != TABLE_MAGIC) { - return TABLE_ERROR_PNT; - } - if (linear_p == NULL) { - return TABLE_ERROR_ARG_NULL; - } + if (table_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } + if (table_p->ta_magic != TABLE_MAGIC) { + return TABLE_ERROR_PNT; + } + if (linear_p == NULL) { + return TABLE_ERROR_ARG_NULL; + } - /* find the associated entry */ - entry_p = this_entry(table_p, linear_p, &ret); - if (entry_p == NULL) { - return ret; - } + /* find the associated entry */ + entry_p = this_entry(table_p, linear_p, &ret); + if (entry_p == NULL) { + return ret; + } - if (key_buf_p != NULL) { - *key_buf_p = ENTRY_KEY_BUF(entry_p); - } - if (key_size_p != NULL) { - *key_size_p = entry_p->te_key_size; - } - if (data_buf_p != NULL) { - if (entry_p->te_data_size == 0) { - *data_buf_p = NULL; - } - else { - if (table_p->ta_data_align == 0) { - *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); - } - else { - *data_buf_p = entry_data_buf(table_p, entry_p); - } - } - } - if (data_size_p != NULL) { - *data_size_p = entry_p->te_data_size; - } + if (key_buf_p != NULL) { + *key_buf_p = ENTRY_KEY_BUF(entry_p); + } + if (key_size_p != NULL) { + *key_size_p = entry_p->te_key_size; + } + if (data_buf_p != NULL) { + if (entry_p->te_data_size == 0) { + *data_buf_p = NULL; + } + else { + if (table_p->ta_data_align == 0) { + *data_buf_p = ENTRY_DATA_BUF(table_p, entry_p); + } + else { + *data_buf_p = entry_data_buf(table_p, entry_p); + } + } + } + if (data_size_p != NULL) { + *data_size_p = entry_p->te_data_size; + } - return TABLE_ERROR_NONE; + return TABLE_ERROR_NONE; } /* @@ -4067,13 +4071,24 @@ int table_entry_pos(table_t *table_p, table_linear_t *linear_p, */ const char *table_strerror(const int error) { - error_str_t *err_p; + error_str_t *err_p; - for (err_p = errors; err_p->es_error != 0; err_p++) { - if (err_p->es_error == error) { - return err_p->es_string; - } - } + for (err_p = errors; err_p->es_error != 0; err_p++) { + if (err_p->es_error == error) { + return err_p->es_string; + } + } - return INVALID_ERROR; + return INVALID_ERROR; } + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/table_util.c b/libs/libks/src/table_util.c index 2fcfda3778..8b8c20f0b7 100644 --- a/libs/libks/src/table_util.c +++ b/libs/libks/src/table_util.c @@ -28,7 +28,7 @@ #include "table.h" static char *rcs_id = - "$Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $"; + "$Id: table_util.c,v 1.5 2000/03/09 03:30:42 gray Exp $"; #define WRITE_MODE 0640 /* mode to write out table */ #define SPECIAL_CHARS "e\033^^\"\"''\\\\n\nr\rt\tb\bf\fa\007" @@ -61,67 +61,67 @@ static char *rcs_id = * out_size - size of the output buffer. */ int expand_chars(const void *buf, const int buf_size, - char *out, const int out_size) + char *out, const int out_size) { - int buf_c; - const unsigned char *buf_p, *spec_p; - char *max_p, *out_p = out; + int buf_c; + const unsigned char *buf_p, *spec_p; + char *max_p, *out_p = out; - /* setup our max pointer */ - max_p = out + out_size; + /* setup our max pointer */ + max_p = out + out_size; - /* run through the input buffer, counting the characters as we go */ - for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) { + /* run through the input buffer, counting the characters as we go */ + for (buf_c = 0, buf_p = (const unsigned char *)buf;; buf_c++, buf_p++) { - /* did we reach the end of the buffer? */ - if (buf_size < 0) { - if (*buf_p == '\0') { - break; - } - } - else { - if (buf_c >= buf_size) { - break; - } - } + /* did we reach the end of the buffer? */ + if (buf_size < 0) { + if (*buf_p == '\0') { + break; + } + } + else { + if (buf_c >= buf_size) { + break; + } + } - /* search for special characters */ - for (spec_p = (unsigned char *)SPECIAL_CHARS + 1; - *(spec_p - 1) != '\0'; - spec_p += 2) { - if (*spec_p == *buf_p) { - break; - } - } + /* search for special characters */ + for (spec_p = (unsigned char *)SPECIAL_CHARS + 1; + *(spec_p - 1) != '\0'; + spec_p += 2) { + if (*spec_p == *buf_p) { + break; + } + } - /* did we find one? */ - if (*(spec_p - 1) != '\0') { - if (out_p + 2 >= max_p) { - break; - } - (void)sprintf(out_p, "\\%c", *(spec_p - 1)); - out_p += 2; - continue; - } + /* did we find one? */ + if (*(spec_p - 1) != '\0') { + if (out_p + 2 >= max_p) { + break; + } + (void)sprintf(out_p, "\\%c", *(spec_p - 1)); + out_p += 2; + continue; + } - /* print out any 7-bit printable characters */ - if (*buf_p < 128 && isprint(*buf_p)) { - if (out_p + 1 >= max_p) { - break; - } - *out_p = *(char *)buf_p; - out_p += 1; - } - else { - if (out_p + 4 >= max_p) { - break; - } - (void)sprintf(out_p, "\\%03o", *buf_p); - out_p += 4; - } - } + /* print out any 7-bit printable characters */ + if (*buf_p < 128 && isprint(*buf_p)) { + if (out_p + 1 >= max_p) { + break; + } + *out_p = *(char *)buf_p; + out_p += 1; + } + else { + if (out_p + 4 >= max_p) { + break; + } + (void)sprintf(out_p, "\\%03o", *buf_p); + out_p += 4; + } + } - return out_p - out; + return out_p - out; } /* @@ -141,22 +141,22 @@ int expand_chars(const void *buf, const int buf_size, */ static void dump_table(table_t *tab_p) { - char buf[10240]; - void *key_p, *data_p; - int ret, key_size, data_size, len, entry_c; + char buf[10240]; + void *key_p, *data_p; + int ret, key_size, data_size, len, entry_c; - for (ret = table_first(tab_p, (void **)&key_p, &key_size, - (void **)&data_p, &data_size), entry_c = 0; - ret == TABLE_ERROR_NONE; - ret = table_next(tab_p, (void **)&key_p, &key_size, - (void **)&data_p, &data_size), entry_c++) { - /* expand the key */ - len = expand_chars(key_p, key_size, buf, sizeof(buf)); - (void)printf("%d: key '%.*s' (%d), ", entry_c, len, buf, len); - /* now dump the data */ - len = expand_chars(data_p, data_size, buf, sizeof(buf)); - (void)printf("data '%.*s' (%d)\n", len, buf, len); - } + for (ret = table_first(tab_p, (void **)&key_p, &key_size, + (void **)&data_p, &data_size), entry_c = 0; + ret == TABLE_ERROR_NONE; + ret = table_next(tab_p, (void **)&key_p, &key_size, + (void **)&data_p, &data_size), entry_c++) { + /* expand the key */ + len = expand_chars(key_p, key_size, buf, sizeof(buf)); + (void)printf("%d: key '%.*s' (%d), ", entry_c, len, buf, len); + /* now dump the data */ + len = expand_chars(data_p, data_size, buf, sizeof(buf)); + (void)printf("data '%.*s' (%d)\n", len, buf, len); + } } /* @@ -176,120 +176,131 @@ static void dump_table(table_t *tab_p) */ static void usage(void) { - (void)fprintf(stderr, - "Usage: table_util\n" - " [-b number] or --buckets num buckets to adjust table\n" - " [-o file] or --out-file output filename\n" - " [-v] or --verbose verbose messages\n" - " file input table filename\n"); - exit(1); + (void)fprintf(stderr, + "Usage: table_util\n" + " [-b number] or --buckets num buckets to adjust table\n" + " [-o file] or --out-file output filename\n" + " [-v] or --verbose verbose messages\n" + " file input table filename\n"); + exit(1); } int main(int argc, char **argv) { - table_t *tab_p; - char do_write = 0, verbose = 0; - char *out_file = NULL, *in_file; - int ret, entry_n, bucket_n, num_buckets = 0; + table_t *tab_p; + char do_write = 0, verbose = 0; + char *out_file = NULL, *in_file; + int ret, entry_n, bucket_n, num_buckets = 0; - /* process the args */ - for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) { + /* process the args */ + for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) { - switch (*(*argv + 1)) { + switch (*(*argv + 1)) { - case 'b': - argc--, argv++; - if (argc == 0) { - usage(); - } - num_buckets = atoi(*argv); - break; + case 'b': + argc--, argv++; + if (argc == 0) { + usage(); + } + num_buckets = atoi(*argv); + break; - case 'o': - argc--, argv++; - if (argc == 0) { - usage(); - } - out_file = *argv; - break; + case 'o': + argc--, argv++; + if (argc == 0) { + usage(); + } + out_file = *argv; + break; - case 'v': - verbose = 1; - break; + case 'v': + verbose = 1; + break; - default: - usage(); - break; - } - } + default: + usage(); + break; + } + } - if (argc != 1) { - usage(); - } + if (argc != 1) { + usage(); + } - /* take the last argument as the input file */ - in_file = *argv; + /* take the last argument as the input file */ + in_file = *argv; - /* read in the table from disk */ - tab_p = table_read(in_file, &ret); - if (tab_p == NULL) { - (void)fprintf(stderr, "table_util: unable to table_read from '%s': %s\n", - in_file, table_strerror(ret)); - exit(1); - } + /* read in the table from disk */ + tab_p = table_read(in_file, &ret); + if (tab_p == NULL) { + (void)fprintf(stderr, "table_util: unable to table_read from '%s': %s\n", + in_file, table_strerror(ret)); + exit(1); + } - /* get info about the table */ - ret = table_info(tab_p, &bucket_n, &entry_n); - if (ret != TABLE_ERROR_NONE) { - (void)fprintf(stderr, - "table_util: unable to get info on table in '%s': %s\n", - in_file, table_strerror(ret)); - exit(1); - } + /* get info about the table */ + ret = table_info(tab_p, &bucket_n, &entry_n); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, + "table_util: unable to get info on table in '%s': %s\n", + in_file, table_strerror(ret)); + exit(1); + } - (void)printf("Read table of %d buckets and %d entries from '%s'\n", - bucket_n, entry_n, in_file); + (void)printf("Read table of %d buckets and %d entries from '%s'\n", + bucket_n, entry_n, in_file); - if (verbose) { - dump_table(tab_p); - } + if (verbose) { + dump_table(tab_p); + } - if (num_buckets > 0) { - /* adjust the table's buckets */ - ret = table_adjust(tab_p, num_buckets); - if (ret != TABLE_ERROR_NONE) { - (void)fprintf(stderr, - "table_util: unable to adjust table to %d buckets: %s\n", - num_buckets, table_strerror(ret)); - exit(1); - } - do_write = 1; - } + if (num_buckets > 0) { + /* adjust the table's buckets */ + ret = table_adjust(tab_p, num_buckets); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, + "table_util: unable to adjust table to %d buckets: %s\n", + num_buckets, table_strerror(ret)); + exit(1); + } + do_write = 1; + } - /* did we modify the table at all */ - if (do_write) { - if (out_file == NULL) { - out_file = in_file; - } + /* did we modify the table at all */ + if (do_write) { + if (out_file == NULL) { + out_file = in_file; + } - /* write out our table */ - ret = table_write(tab_p, out_file, WRITE_MODE); - if (ret != TABLE_ERROR_NONE) { - (void)fprintf(stderr, "table_util: unable to write table to '%s': %s\n", - out_file, table_strerror(ret)); - exit(1); - } + /* write out our table */ + ret = table_write(tab_p, out_file, WRITE_MODE); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, "table_util: unable to write table to '%s': %s\n", + out_file, table_strerror(ret)); + exit(1); + } - (void)printf("Wrote table to '%s'\n", out_file); - } + (void)printf("Wrote table to '%s'\n", out_file); + } - /* free the table */ - ret = table_free(tab_p); - if (ret != TABLE_ERROR_NONE) { - (void)fprintf(stderr, "table_util: unable to free table: %s\n", - table_strerror(ret)); - /* NOTE: not a critical error */ - } + /* free the table */ + ret = table_free(tab_p); + if (ret != TABLE_ERROR_NONE) { + (void)fprintf(stderr, "table_util: unable to free table: %s\n", + table_strerror(ret)); + /* NOTE: not a critical error */ + } - exit(0); + exit(0); } + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/libs/libks/src/win/mman.c b/libs/libks/src/win/mman.c new file mode 100644 index 0000000000..b154317e98 --- /dev/null +++ b/libs/libks/src/win/mman.c @@ -0,0 +1,180 @@ + +#include +#include +#include + +#include "mman.h" + +#ifndef FILE_MAP_EXECUTE +#define FILE_MAP_EXECUTE 0x0020 +#endif /* FILE_MAP_EXECUTE */ + +static int __map_mman_error(const DWORD err, const int deferr) +{ + if (err == 0) + return 0; + //TODO: implement + return err; +} + +static DWORD __map_mmap_prot_page(const int prot) +{ + DWORD protect = 0; + + if (prot == PROT_NONE) + return protect; + + if ((prot & PROT_EXEC) != 0) + { + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; + } + else + { + protect = ((prot & PROT_WRITE) != 0) ? + PAGE_READWRITE : PAGE_READONLY; + } + + return protect; +} + +static DWORD __map_mmap_prot_file(const int prot) +{ + DWORD desiredAccess = 0; + + if (prot == PROT_NONE) + return desiredAccess; + + if ((prot & PROT_READ) != 0) + desiredAccess |= FILE_MAP_READ; + if ((prot & PROT_WRITE) != 0) + desiredAccess |= FILE_MAP_WRITE; + if ((prot & PROT_EXEC) != 0) + desiredAccess |= FILE_MAP_EXECUTE; + + return desiredAccess; +} + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) +{ + HANDLE fm, h; + + void * map = MAP_FAILED; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4293) +#endif + + const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); + const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); + const DWORD protect = __map_mmap_prot_page(prot); + const DWORD desiredAccess = __map_mmap_prot_file(prot); + + const off_t maxSize = off + (off_t)len; + + const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); + const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ? + (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + errno = 0; + + if (len == 0 + /* Unsupported flag combinations */ + || (flags & MAP_FIXED) != 0 + /* Usupported protection combinations */ + || prot == PROT_EXEC) + { + errno = EINVAL; + return MAP_FAILED; + } + + h = ((flags & MAP_ANONYMOUS) == 0) ? + (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; + + if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return MAP_FAILED; + } + + fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); + + if (fm == NULL) + { + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; + } + + map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); + + CloseHandle(fm); + + if (map == NULL) + { + errno = __map_mman_error(GetLastError(), EPERM); + return MAP_FAILED; + } + + return map; +} + +int munmap(void *addr, size_t len) +{ + if (UnmapViewOfFile(addr)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int _mprotect(void *addr, size_t len, int prot) +{ + DWORD newProtect = __map_mmap_prot_page(prot); + DWORD oldProtect = 0; + + if (VirtualProtect(addr, len, newProtect, &oldProtect)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int msync(void *addr, size_t len, int flags) +{ + if (FlushViewOfFile(addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int mlock(const void *addr, size_t len) +{ + if (VirtualLock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} + +int munlock(const void *addr, size_t len) +{ + if (VirtualUnlock((LPVOID)addr, len)) + return 0; + + errno = __map_mman_error(GetLastError(), EPERM); + + return -1; +} diff --git a/libs/libks/src/win/sys/mman.h b/libs/libks/src/win/sys/mman.h new file mode 100644 index 0000000000..7c1197b819 --- /dev/null +++ b/libs/libks/src/win/sys/mman.h @@ -0,0 +1,55 @@ +/* + * sys/mman.h + * mman-win32 + */ + +#ifndef _SYS_MMAN_H_ +#define _SYS_MMAN_H_ + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +/* All the headers include this file. */ +#ifndef _MSC_VER +#include <_mingw.h> +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 + +#define MAP_FILE 0 +#define MAP_SHARED 1 +#define MAP_PRIVATE 2 +#define MAP_TYPE 0xf +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS + +#define MAP_FAILED ((void *)-1) + +/* Flags for msync. */ +#define MS_ASYNC 1 +#define MS_SYNC 2 +#define MS_INVALIDATE 4 + +void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); +int munmap(void *addr, size_t len); +int _mprotect(void *addr, size_t len, int prot); +int msync(void *addr, size_t len, int flags); +int mlock(const void *addr, size_t len); +int munlock(const void *addr, size_t len); + +#ifdef __cplusplus +}; +#endif + +#endif /* _SYS_MMAN_H_ */ diff --git a/libs/libks/test/testpools.c b/libs/libks/test/testpools.c new file mode 100644 index 0000000000..48580a0525 --- /dev/null +++ b/libs/libks/test/testpools.c @@ -0,0 +1,47 @@ +#include +#include +#include "mpool.h" +#include + +int main(int argc, char **argv) +{ + mpool_t *pool; + int err = 0; + char *str = NULL; + int x = 0; + int bytes = 1024; + + if (argc > 1) { + int tmp = atoi(argv[1]); + + if (tmp > 0) { + bytes = tmp; + } else { + fprintf(stderr, "INVALID\n"); + exit(255); + } + } + + pool = mpool_open(MPOOL_FLAG_ANONYMOUS, 0, NULL, &err); + + if (!pool || err != MPOOL_ERROR_NONE) { + fprintf(stderr, "ERR: %d [%s]\n", err, mpool_strerror(err)); + exit(255); + } + + str = mpool_alloc(pool, bytes, &err); + memset(str+x, '.', bytes -1); + *(str+(bytes-1)) = '\0'; + + printf("%s\n", str); + + //mpool_clear(pool); + err = mpool_close(pool); + + if (err != MPOOL_ERROR_NONE) { + fprintf(stderr, "ERR: [%s]\n", mpool_strerror(err)); + exit(255); + } + + exit(0); +} diff --git a/libs/libks/test/testpools/testpools.vcxproj b/libs/libks/test/testpools/testpools.vcxproj new file mode 100644 index 0000000000..0313278219 --- /dev/null +++ b/libs/libks/test/testpools/testpools.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {766F7FF4-CF39-4CDF-ABDC-4E9C88568F1F} + Win32Proj + testpools + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\src\include + + + Console + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\src\include + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\src\include + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(ProjectDir)..\..\src\include + + + Console + true + true + true + + + + + + + + {70d178d8-1100-4152-86c0-809a91cff832} + + + + + + \ No newline at end of file diff --git a/libs/libks/test/testpools/testpools.vcxproj.filters b/libs/libks/test/testpools/testpools.vcxproj.filters new file mode 100644 index 0000000000..85777cf3ad --- /dev/null +++ b/libs/libks/test/testpools/testpools.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 5c4b697a66..984a340a65 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1,26 +1 @@ -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -Wed Feb 11 12:35:25 EST 2015 -======= -======= ->>>>>>> sofia rebuild -======= ->>>>>>> sofia rebuild -<<<<<<< HEAD -Wed Jan 7 11:24:56 PST 2015 -======= -Tue Jan 6 20:12:24 CST 2015 ->>>>>>> sofia update -<<<<<<< HEAD ->>>>>>> sofia update -======= -======= -Wed Jan 7 11:18:02 CST 2015 ->>>>>>> sofia rebuild -<<<<<<< HEAD -======= -======= -Mon Jan 12 11:34:52 CST 2015 ->>>>>>> sofia rebuild ->>>>>>> sofia rebuild +Wed Sep 9 12:25:38 CDT 2015 diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c index e15d6787de..8efaa31d4c 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c @@ -1593,10 +1593,6 @@ int nua_client_next_request(nua_client_request_t *cr, int invite) for (; cr; cr = cr->cr_next) { if (cr->cr_method == sip_method_cancel) continue; - - if (invite - ? cr->cr_method == sip_method_invite - : cr->cr_method != sip_method_invite) break; } diff --git a/libs/spandsp/.gitignore b/libs/spandsp/.gitignore index 123403b0f9..9d3e352ee3 100644 --- a/libs/spandsp/.gitignore +++ b/libs/spandsp/.gitignore @@ -10,3 +10,5 @@ src/v27ter_tx_4800_rrc.h src/v29rx_rrc.h src/v29tx_rrc.h INSTALL +test-data/itu/tiff-fx/Makefile +test-data/itu/tiff-fx/Makefile.in diff --git a/libs/spandsp/tests/pcap_parse.c b/libs/spandsp/tests/pcap_parse.c index bc3805af2a..56d8d288e8 100644 --- a/libs/spandsp/tests/pcap_parse.c +++ b/libs/spandsp/tests/pcap_parse.c @@ -113,7 +113,7 @@ typedef struct _null_hdr typedef struct _ipv6_hdr { char dontcare[6]; - u_int8_t nxt_header; /* we only need the next header, so we can determine, if the next header is UDP or not */ + uint8_t nxt_header; /* we only need the next header, so we can determine, if the next header is UDP or not */ char dontcare2[33]; } ipv6_hdr; #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 294a5fb0d7..52e3381006 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,7 +52,6 @@ switch_log.c switch_xml.c switch_config.c switch_time.c -switch_stfu.c switch_cpp.cpp g711.c switch_pcm.c diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 3522cf0269..6b46994075 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -309,16 +309,10 @@ struct switch_session_manager { uint32_t session_limit; switch_size_t session_id; switch_queue_t *thread_queue; - switch_thread_t *manager_thread; switch_mutex_t *mutex; switch_thread_cond_t *cond; - switch_mutex_t *cond_mutex; - switch_mutex_t *cond2_mutex; - int ready; int running; int busy; - int popping; - int starting; }; extern struct switch_session_manager session_manager; diff --git a/src/include/switch.h b/src/include/switch.h index 1c55e261aa..d612532612 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -111,7 +111,6 @@ #include "switch_platform.h" #include "switch_types.h" -#include "switch_stfu.h" #include "switch_apr.h" #include "switch_mprintf.h" #include "switch_core_db.h" @@ -144,6 +143,7 @@ #include "switch_limit.h" #include "switch_core_media.h" #include "switch_core_video.h" +#include "switch_jitterbuffer.h" #include diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 0bddcd4978..5ab5d35e7e 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -659,6 +659,8 @@ SWITCH_DECLARE(switch_status_t) switch_queue_trypop(switch_queue_t *queue, void SWITCH_DECLARE(switch_status_t) switch_queue_interrupt_all(switch_queue_t *queue); +SWITCH_DECLARE(switch_status_t) switch_queue_term(switch_queue_t *queue); + /** * push/add a object to the queue, returning immediatly if the queue is full * diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 96afd617bf..75172cff6e 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -861,7 +861,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(switch_core_ses */ SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_session_t *session); -SWITCH_DECLARE(stfu_instance_t *) switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type); +SWITCH_DECLARE(switch_jb_t *) switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type); SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec); SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session); SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target); @@ -1651,6 +1651,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_encode_video(switch_codec_t *c \param cmd the command to send \param ctype the type of the arguement \param cmd_data a void pointer to the data matching the passed type + \param atype the type of the extra arguement + \param cmd_arg a void pointer to the data matching the passed type \param rtype the type of the response if any \param ret_data a void pointer to a pointer of return data \return SWITCH_STATUS_SUCCESS if the command was received @@ -1659,6 +1661,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data); diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index da991e016a..9a60b7a5d1 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -1,3 +1,4 @@ + /* * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application * Copyright (C) 2005-2014, Anthony Minessale II @@ -107,6 +108,8 @@ typedef struct switch_core_media_params_s { char *local_sdp_str; char *last_sdp_str; char *last_sdp_response; + char *prev_sdp_str; + char *prev_sdp_response; char *stun_ip; switch_port_t stun_port; @@ -253,7 +256,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_udptl_mode(switch_core_session SWITCH_DECLARE(void) switch_core_media_set_rtp_flag(switch_core_session_t *session, switch_media_type_t type, switch_rtp_flag_t flag); SWITCH_DECLARE(void) switch_core_media_clear_rtp_flag(switch_core_session_t *session, switch_media_type_t type, switch_rtp_flag_t flag); -SWITCH_DECLARE(stfu_instance_t *) switch_core_media_get_jb(switch_core_session_t *session, switch_media_type_t type); +SWITCH_DECLARE(switch_jb_t *) switch_core_media_get_jb(switch_core_session_t *session, switch_media_type_t type); SWITCH_DECLARE(switch_rtp_stats_t *) switch_core_media_get_stats(switch_core_session_t *session, switch_media_type_t type, switch_memory_pool_t *pool); @@ -307,15 +310,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data); #define switch_core_media_gen_key_frame(_session) switch_core_media_codec_control(_session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_WRITE, \ - SCC_VIDEO_REFRESH, SCCT_NONE, NULL, NULL, NULL) \ + SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL) \ #define switch_core_media_write_bandwidth(_session, _val) switch_core_media_codec_control(_session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_WRITE, \ - SCC_VIDEO_BANDWIDTH, SCCT_STRING, _val, NULL, NULL) \ + SCC_VIDEO_BANDWIDTH, SCCT_STRING, _val, SCCT_NONE, NULL, NULL, NULL) \ SWITCH_DECLARE(switch_timer_t *) switch_core_media_get_timer(switch_core_session_t *session, switch_media_type_t mtype); diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 12f18a9b94..d13af7d471 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -254,6 +254,8 @@ SWITCH_DECLARE(void) switch_event_prep_for_delivery_detailed(const char *file, c SWITCH_DECLARE(switch_status_t) switch_event_bind(const char *id, switch_event_types_t event, const char *subclass_name, switch_event_callback_t callback, void *user_data); +SWITCH_DECLARE(switch_status_t) switch_event_get_custom_events(switch_console_callback_match_t **matches); + /*! \brief Bind an event callback to a specific event \param id an identifier token of the binder diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 999d028eba..412cb63757 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -122,6 +122,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_events(switch_core_session_ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_event(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_session_t *session); +SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_signal_data(switch_core_session_t *session); SWITCH_DECLARE(switch_status_t) switch_ivr_process_indications(switch_core_session_t *session, switch_core_session_message_t *message); /*! diff --git a/src/include/switch_jitterbuffer.h b/src/include/switch_jitterbuffer.h new file mode 100644 index 0000000000..de423fd7fd --- /dev/null +++ b/src/include/switch_jitterbuffer.h @@ -0,0 +1,79 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2014, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * switch_jitterbuffer.h -- Audio/Video Jitter Buffer + * + */ + + +#ifndef SWITCH_VIDDERBUFFER_H +#define SWITCH_VIDDERBUFFER_H + +typedef enum { + SJB_QUEUE_ONLY = (1 << 0) +} switch_jb_flag_t; + +typedef enum { + SJB_VIDEO = 0, + SJB_AUDIO +} switch_jb_type_t; + + +SWITCH_BEGIN_EXTERN_C +SWITCH_DECLARE(switch_status_t) switch_jb_create(switch_jb_t **jbp, switch_jb_type_t type, + uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool); +SWITCH_DECLARE(switch_status_t) switch_jb_set_frames(switch_jb_t *jb, uint32_t min_frame_len, uint32_t max_frame_len); +SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame); +SWITCH_DECLARE(switch_status_t) switch_jb_get_frames(switch_jb_t *jb, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len); +SWITCH_DECLARE(switch_status_t) switch_jb_destroy(switch_jb_t **jbp); +SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb); +SWITCH_DECLARE(void) switch_jb_debug_level(switch_jb_t *jb, uint8_t level); +SWITCH_DECLARE(int) switch_jb_frame_count(switch_jb_t *jb); +SWITCH_DECLARE(int) switch_jb_poll(switch_jb_t *jb); +SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len); +SWITCH_DECLARE(switch_size_t) switch_jb_get_last_read_len(switch_jb_t *jb); +SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len); +SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb); +SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len); +SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session); +SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second); +SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag); +SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag); + +SWITCH_END_EXTERN_C +#endif + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 9732e40b59..feb9337d54 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -119,7 +119,7 @@ typedef switch_status_t (*switch_io_state_change_t) (switch_core_session_t *); typedef switch_status_t (*switch_io_state_run_t) (switch_core_session_t *); typedef switch_status_t (*switch_io_read_video_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int); typedef switch_status_t (*switch_io_write_video_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int); -typedef stfu_instance_t *(*switch_io_get_jb_t) (switch_core_session_t *, switch_media_type_t); +typedef switch_jb_t *(*switch_io_get_jb_t) (switch_core_session_t *, switch_media_type_t); typedef enum { SWITCH_IO_OUTGOING_CHANNEL, diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index 40c1ecde25..933c4d3688 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -128,6 +128,7 @@ typedef int gid_t; #include #include #include +#include #endif // _MSC_VER #ifndef __LITTLE_ENDIAN #define __LITTLE_ENDIAN 1234 diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 6fed5c1502..2c5dce8f58 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -328,8 +328,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_session); -SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *rtp_session, uint32_t frames); -SWITCH_DECLARE(uint32_t) switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_session); +SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *rtp_session, uint32_t frames, uint32_t max_frames); +SWITCH_DECLARE(switch_status_t) switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_session, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len); /*! \brief Acvite a jitter buffer on an RTP session @@ -340,13 +340,13 @@ SWITCH_DECLARE(uint32_t) switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_sess SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames, uint32_t max_queue_frames, - uint32_t samples_per_packet, uint32_t samples_per_second, uint32_t max_drift); + uint32_t samples_per_packet, uint32_t samples_per_second); SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name); SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session); SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause); -SWITCH_DECLARE(stfu_instance_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session); +SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session); diff --git a/src/include/switch_stfu.h b/src/include/switch_stfu.h deleted file mode 100644 index d15067ba98..0000000000 --- a/src/include/switch_stfu.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * STFU (S)ort (T)ransportable (F)ramed (U)tterances - * Copyright (c) 2007-2014 Anthony Minessale II - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * THOSE WHO DISAGREE MAY CERTAINLY STFU - */ - -#ifndef STFU_H -#define STFU_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif -#ifdef __STUPIDFORMATBUG__ -} -#endif - -#if !defined(MACOSX) && !defined(_XOPEN_SOURCE) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__cplusplus) -#define _XOPEN_SOURCE 600 -#endif - -#include -#include -#include -#include - -#if (_MSC_VER >= 1400) // VC8+ -#define stfu_assert(expr) assert(expr);__analysis_assume( expr ) -#endif - -#ifndef stfu_assert -#define stfu_assert(_x) assert(_x) -#endif - -#ifdef _MSC_VER -#if _MSC_VER < 1900 -#if !defined(_STDINT) && !defined(uint32_t) -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned long in_addr_t; -#endif -#define snprintf _snprintf -#endif -#else -#include -#include -#include -#include -#include -#include -#endif -#include - -#ifdef WIN32 -#include -#include -typedef SOCKET stfu_socket_t; -#ifndef _STDINT -typedef unsigned __int64 uint64_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int8 uint8_t; -typedef __int64 int64_t; -typedef __int32 int32_t; -typedef __int16 int16_t; -typedef __int8 int8_t; -#endif -typedef intptr_t stfu_ssize_t; -typedef int stfu_filehandle_t; -#define STFU_SOCK_INVALID INVALID_SOCKET -#define strerror_r(num, buf, size) strerror_s(buf, size, num) -#else -#include -#include -#include -#include -#include -#include -#include -#define STFU_SOCK_INVALID -1 -typedef int stfu_socket_t; -typedef ssize_t stfu_ssize_t; -typedef int stfu_filehandle_t; -#endif - - -#define STFU_PRE __FILE__, __SWITCH_FUNC__, __LINE__ -#define STFU_LOG_LEVEL_DEBUG 7 -#define STFU_LOG_LEVEL_INFO 6 -#define STFU_LOG_LEVEL_NOTICE 5 -#define STFU_LOG_LEVEL_WARNING 4 -#define STFU_LOG_LEVEL_ERROR 3 -#define STFU_LOG_LEVEL_CRIT 2 -#define STFU_LOG_LEVEL_ALERT 1 -#define STFU_LOG_LEVEL_EMERG 0 - -#define STFU_LOG_DEBUG STFU_PRE, STFU_LOG_LEVEL_DEBUG -#define STFU_LOG_INFO STFU_PRE, STFU_LOG_LEVEL_INFO -#define STFU_LOG_NOTICE STFU_PRE, STFU_LOG_LEVEL_NOTICE -#define STFU_LOG_WARNING STFU_PRE, STFU_LOG_LEVEL_WARNING -#define STFU_LOG_ERROR STFU_PRE, STFU_LOG_LEVEL_ERROR -#define STFU_LOG_CRIT STFU_PRE, STFU_LOG_LEVEL_CRIT -#define STFU_LOG_ALERT STFU_PRE, STFU_LOG_LEVEL_ALERT -#define STFU_LOG_EMERG STFU_PRE, STFU_LOG_LEVEL_EMERG -typedef void (*stfu_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...); - - -int stfu_vasprintf(char **ret, const char *fmt, va_list ap); - -extern stfu_logger_t stfu_log; - -/*! Sets the logger for libstfu. Default is the null_logger */ -void stfu_global_set_logger(stfu_logger_t logger); -/*! Sets the default log level for libstfu */ -void stfu_global_set_default_logger(int level); - -#define STFU_DATALEN 16384 -#define STFU_QLEN 300 -#define STFU_MAX_TRACK 256 - -typedef enum { - STFU_IT_FAILED, - STFU_IT_WORKED, - STFU_IM_DONE, - STFU_ITS_TOO_LATE -} stfu_status_t; - -struct stfu_frame { - uint32_t ts; - uint16_t seq; - uint32_t pt; - uint8_t data[STFU_DATALEN]; - size_t dlen; - uint8_t was_read; - uint8_t plc; -}; -typedef struct stfu_frame stfu_frame_t; - -struct stfu_instance; -typedef struct stfu_instance stfu_instance_t; - -typedef struct { - uint32_t qlen; - uint32_t packet_in_count; - uint32_t clean_count; - uint32_t consecutive_good_count; - uint32_t consecutive_bad_count; - double period_jitter_percent; - double period_missing_percent; -} stfu_report_t; - -typedef void (*stfu_n_call_me_t)(stfu_instance_t *i, void *); - -void stfu_n_report(stfu_instance_t *i, stfu_report_t *r); -void stfu_n_destroy(stfu_instance_t **i); -stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second, uint32_t max_drift_ms); -stfu_status_t _stfu_n_resize(stfu_instance_t *i, uint32_t qlen, int line); -#define stfu_n_resize(_i, _ql) _stfu_n_resize(_i, _ql, __LINE__) -stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last); -stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i); -SWITCH_DECLARE(int32_t) stfu_n_peek_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t **rframe); -void _stfu_n_reset(stfu_instance_t *i, const char *file, const char *func, int line); -#define stfu_n_reset(_i) _stfu_n_reset(_i, STFU_PRE) -stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets); -void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata); -void stfu_n_debug(stfu_instance_t *i, const char *name); -int32_t stfu_n_get_drift(stfu_instance_t *i); -int32_t stfu_n_get_most_qlen(stfu_instance_t *i); - -#define stfu_im_done(i) stfu_n_add_data(i, 0, 0, NULL, 0, 0, 1) -#define stfu_n_eat(i,t,s,p,d,l,tt) stfu_n_add_data(i, t, s, p, d, l, tt, 0) - -#ifdef __cplusplus -} -#endif -#endif /*STFU_H*/ - diff --git a/src/include/switch_types.h b/src/include/switch_types.h index e248f2507f..126f722ce2 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -752,6 +752,7 @@ typedef enum { SWITCH_RTP_FLAG_MUTE, SWITCH_RTP_FLAG_NACK, SWITCH_RTP_FLAG_TMMBR, + SWITCH_RTP_FLAG_GEN_TS_DELTA, SWITCH_RTP_FLAG_INVALID } switch_rtp_flag_t; @@ -1077,6 +1078,8 @@ typedef enum { SWITCH_MESSAGE_INDICATE_HARD_MUTE, SWITCH_MESSAGE_INDICATE_BITRATE_REQ, SWITCH_MESSAGE_INDICATE_BITRATE_ACK, + SWITCH_MESSAGE_INDICATE_CODEC_DEBUG_REQ, + SWITCH_MESSAGE_INDICATE_CODEC_SPECIFIC_REQ, SWITCH_MESSAGE_REFER_EVENT, SWITCH_MESSAGE_ANSWER_EVENT, SWITCH_MESSAGE_PROGRESS_EVENT, @@ -1473,6 +1476,7 @@ typedef enum { CF_3PCC, CF_VIDEO_PASSIVE, CF_NOVIDEO, + CF_VIDEO_BITRATE_UNMANAGABLE, CF_VIDEO_ECHO, CF_VIDEO_BLANK, CF_SLA_INTERCEPT, @@ -2240,10 +2244,12 @@ typedef switch_status_t (*switch_core_codec_video_encode_func_t) (switch_codec_t typedef switch_status_t (*switch_core_codec_video_decode_func_t) (switch_codec_t *codec, switch_frame_t *frame); typedef enum { - SCC_VIDEO_REFRESH = 0, + SCC_VIDEO_GEN_KEYFRAME = 0, SCC_VIDEO_BANDWIDTH, SCC_VIDEO_RESET, - SCC_AUDIO_PACKET_LOSS + SCC_AUDIO_PACKET_LOSS, + SCC_DEBUG, + SCC_CODEC_SPECIFIC } switch_codec_control_command_t; typedef enum { @@ -2261,6 +2267,8 @@ typedef switch_status_t (*switch_core_codec_control_func_t) (switch_codec_t *cod switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data); @@ -2554,8 +2562,8 @@ typedef struct switch_waitlist_s { uint32_t revents; } switch_waitlist_t; -struct switch_vb_s; -typedef struct switch_vb_s switch_vb_t; +struct switch_jb_s; +typedef struct switch_jb_s switch_jb_t; struct switch_img_txt_handle_s; typedef struct switch_img_txt_handle_s switch_img_txt_handle_t; diff --git a/src/include/switch_utf8.h b/src/include/switch_utf8.h index 2089370b49..11699843ee 100644 --- a/src/include/switch_utf8.h +++ b/src/include/switch_utf8.h @@ -110,10 +110,4 @@ SWITCH_DECLARE(int) switch_u8_strlen(char *s); SWITCH_DECLARE(int) switch_u8_is_locale_utf8(char *locale); -/* printf where the format string and arguments may be in UTF-8. - you can avoid this function and just use ordinary printf() if the current - locale is UTF-8. */ -SWITCH_DECLARE(int) switch_u8_vprintf(char *fmt, va_list ap); -SWITCH_DECLARE(int) switch_u8_printf(char *fmt, ...); - SWITCH_DECLARE(uint32_t) switch_u8_get_char(char *s, int *i); diff --git a/src/include/switch_vidderbuffer.h b/src/include/switch_vidderbuffer.h deleted file mode 100644 index 73942daa03..0000000000 --- a/src/include/switch_vidderbuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * switch_vidderbuffer.h -- Video Buffer - * - */ - - -#ifndef SWITCH_VIDDERBUFFER_H -#define SWITCH_VIDDERBUFFER_H - -typedef enum { - SVB_QUEUE_ONLY = (1 << 0) -} switch_vb_flag_t; - - -SWITCH_BEGIN_EXTERN_C -SWITCH_DECLARE(switch_status_t) switch_vb_create(switch_vb_t **vbp, uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool); -SWITCH_DECLARE(switch_status_t) switch_vb_set_frames(switch_vb_t *vb, uint32_t min_frame_len, uint32_t max_frame_len); -SWITCH_DECLARE(switch_status_t) switch_vb_get_frames(switch_vb_t *vb, uint32_t *min_frame_len, uint32_t *max_frame_len); -SWITCH_DECLARE(switch_status_t) switch_vb_destroy(switch_vb_t **vbp); -SWITCH_DECLARE(void) switch_vb_reset(switch_vb_t *vb); -SWITCH_DECLARE(void) switch_vb_debug_level(switch_vb_t *vb, uint8_t level); -SWITCH_DECLARE(int) switch_vb_frame_count(switch_vb_t *vb); -SWITCH_DECLARE(int) switch_vb_poll(switch_vb_t *vb); -SWITCH_DECLARE(switch_status_t) switch_vb_push_packet(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t len); -SWITCH_DECLARE(switch_status_t) switch_vb_put_packet(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t len); -SWITCH_DECLARE(switch_status_t) switch_vb_get_packet(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t *len); -SWITCH_DECLARE(uint32_t) switch_vb_pop_nack(switch_vb_t *vb); -SWITCH_DECLARE(switch_status_t) switch_vb_get_packet_by_seq(switch_vb_t *vb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len); -SWITCH_DECLARE(void) switch_vb_set_flag(switch_vb_t *vb, switch_vb_flag_t flag); -SWITCH_DECLARE(void) switch_vb_clear_flag(switch_vb_t *vb, switch_vb_flag_t flag); - -SWITCH_END_EXTERN_C -#endif - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 6779788808..5d4a0e1a16 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -1284,6 +1284,8 @@ static switch_status_t switch_h264_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data) { @@ -1292,7 +1294,7 @@ static switch_status_t switch_h264_control(switch_codec_t *codec, h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info; switch(cmd) { - case SCC_VIDEO_REFRESH: + case SCC_VIDEO_GEN_KEYFRAME: context->need_key_frame = 1; break; case SCC_VIDEO_BANDWIDTH: diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 02420c2899..e3f4ed6cd2 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -139,9 +139,11 @@ typedef struct record_helper_s { AVFormatContext *fc; MediaStream *video_st; switch_timer_t *timer; + switch_timer_t *other_timer; int in_callback; switch_queue_t *video_queue; switch_thread_t *video_thread; + switch_mm_t *mm; } record_helper_t; static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt) @@ -242,7 +244,8 @@ static switch_status_t add_stream(MediaStream *mst, AVFormatContext *fc, AVCodec } mst->st->id = fc->nb_streams - 1; c = mst->st->codec; - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "id:%d den:%d num:%d\n", mst->st->id, mst->st->time_base.den, mst->st->time_base.num); + + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "id:%d den:%d num:%d\n", mst->st->id, mst->st->time_base.den, mst->st->time_base.num); if (threads > 4) { threads = 4; @@ -256,6 +259,11 @@ static switch_status_t add_stream(MediaStream *mst, AVFormatContext *fc, AVCodec c->channels = mst->channels; c->channel_layout = av_get_default_channel_layout(c->channels); + mst->st->time_base.den = 1000; + mst->st->time_base.num = 1; + c->time_base.den = 1000; + c->time_base.num = 1; + if (mm) { if (mm->ab) { c->bit_rate = mm->ab * 1024; @@ -273,8 +281,12 @@ static switch_status_t add_stream(MediaStream *mst, AVFormatContext *fc, AVCodec if (mm->vbuf) { buffer_bytes = mm->vbuf; } - fps = mm->fps; - + if (mm->fps) { + fps = mm->fps; + } else { + mm->fps = fps; + } + if (mm->vw && mm->vh) { mst->width = mm->vw; mst->height = mm->vh; @@ -469,49 +481,62 @@ static switch_status_t open_audio(AVFormatContext *fc, AVCodec *codec, MediaStre return SWITCH_STATUS_SUCCESS; } - - static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void *obj) { record_helper_t *eh = (record_helper_t *) obj; void *pop; switch_image_t *img, *last_img = NULL, *tmp_img = NULL; + switch_size_t size; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "video thread start\n"); - + for(;;) { AVPacket pkt = { 0 }; int got_packet; - int ret = -1; + int ret = -1, popped = 0; - img = NULL; - - if (switch_queue_pop_timeout(eh->video_queue, &pop, 66000) == SWITCH_STATUS_SUCCESS) { - if (!pop) break; - img = (switch_image_t *) pop; - - if (last_img && (last_img->d_w != img->d_w || last_img->d_h != img->d_h)) { - /* scale to match established stream */ - switch_img_scale(img, &tmp_img, last_img->d_w, last_img->d_h); - switch_img_free(&img); - img = tmp_img; - tmp_img = NULL; - } - - switch_img_free(&last_img); - last_img = img; - } else { - if (last_img) { - img = last_img; + do { + switch_status_t status; + img = NULL; + + if (!popped) { + status = switch_queue_pop(eh->video_queue, &pop); + popped++; } else { - continue; + status = switch_queue_trypop(eh->video_queue, &pop); } - } + + if (status == SWITCH_STATUS_SUCCESS) { + switch_img_free(&img); + + if (!pop) { + goto endfor; + } + img = (switch_image_t *)pop; + } else { + if (img) { + break; + } else { + popped = 0; + continue; + } + } + + size = switch_queue_size(eh->video_queue); + } while(img && size > 1); - if (!img) { - continue; - } + if (last_img && (last_img->d_w != img->d_w || last_img->d_h != img->d_h)) { + /* scale to match established stream */ + switch_img_scale(img, &tmp_img, last_img->d_w, last_img->d_h); + switch_img_free(&img); + img = tmp_img; + tmp_img = NULL; + } + + switch_img_free(&last_img); + last_img = img; + //switch_mutex_lock(eh->mutex); eh->in_callback = 1; @@ -526,6 +551,14 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * fill_avframe(eh->video_st->frame, img); switch_core_timer_sync(eh->timer); + + if (eh->other_timer) { + if (eh->timer->samplecount > eh->other_timer->samplecount) { + int sleepfor = (eh->timer->samplecount - eh->other_timer->samplecount) * 1000; + switch_yield(sleepfor); + switch_core_timer_sync(eh->timer); + } + } if (eh->video_st->frame->pts == eh->timer->samplecount) { // never use the same pts, or the encoder coughs @@ -555,6 +588,8 @@ static void *SWITCH_THREAD_FUNC video_thread_run(switch_thread_t *thread, void * //switch_mutex_unlock(eh->mutex); } + endfor: + switch_img_free(&last_img); while(switch_queue_trypop(eh->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { @@ -1041,7 +1076,8 @@ struct av_file_context { switch_mutex_t *mutex; switch_buffer_t *buf; switch_buffer_t *audio_buffer; - switch_timer_t timer; + switch_timer_t video_timer; + switch_timer_t audio_timer; int offset; int audio_start; int vid_ready; @@ -1398,9 +1434,6 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa } switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool); - switch_core_timer_init(&context->timer, "soft", 1, 1000, context->pool); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "init timer\n"); - switch_buffer_create_dynamic(&context->audio_buffer, 512, 512, 0); if (!context->audio_buffer) { @@ -1529,6 +1562,10 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa handle->speed = 0; handle->pos = 0; + + switch_core_timer_init(&context->audio_timer, "soft", 1, 1, /*handle->samplerate / 1000,*/ context->pool); + switch_core_timer_init(&context->video_timer, "soft", 1, 1, context->pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Opening File [%s] %dhz %s\n", file, handle->samplerate, switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) ? " with VIDEO" : ""); @@ -1540,8 +1577,12 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa mod_avformat_destroy_output_context(context); } - if (context->timer.interval) { - switch_core_timer_destroy(&context->timer); + if (context->video_timer.interval) { + switch_core_timer_destroy(&context->video_timer); + } + + if (context->audio_timer.interval) { + switch_core_timer_destroy(&context->audio_timer); } if (context->audio_buffer) { @@ -1599,8 +1640,12 @@ static switch_status_t av_file_close(switch_file_handle_t *handle) mod_avformat_destroy_output_context(context); } - if (context->timer.interval) { - switch_core_timer_destroy(&context->timer); + if (context->video_timer.interval) { + switch_core_timer_destroy(&context->video_timer); + } + + if (context->audio_timer.interval) { + switch_core_timer_destroy(&context->audio_timer); } switch_img_free(&context->last_img); @@ -1684,15 +1729,13 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s context->offset = 0; } - - switch_buffer_write(context->audio_buffer, data, datalen); bytes = context->audio_st.frame->nb_samples * 2 * context->audio_st.st->codec->channels; //inuse = switch_buffer_inuse(context->audio_buffer); //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "inuse: %d samples: %d bytes: %d\n", inuse, context->audio_st.frame->nb_samples, bytes); - while ((inuse = switch_buffer_inuse(context->audio_buffer)) >= bytes * 5) { + while ((inuse = switch_buffer_inuse(context->audio_buffer)) >= bytes) { AVPacket pkt = { 0 }; int got_packet = 0; int ret; @@ -1707,9 +1750,9 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s switch_buffer_read(context->audio_buffer, context->audio_st.frame->data[0], bytes); /* convert to destination format */ ret = avresample_convert(context->audio_st.resample_ctx, - (uint8_t **)context->audio_st.frame->data, 0, out_samples, - context->audio_st.tmp_frame->data, 0, context->audio_st.frame->nb_samples); - + (uint8_t **)context->audio_st.frame->data, 0, out_samples, + context->audio_st.tmp_frame->data, 0, context->audio_st.frame->nb_samples); + if (ret < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error while converting %d samples, error text: %s\n", context->audio_st.frame->nb_samples, get_error_text(ret)); @@ -1718,13 +1761,15 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s context->audio_st.tmp_frame->pts = context->audio_st.next_pts; context->audio_st.next_pts += context->audio_st.frame->nb_samples; - ret = avcodec_encode_audio2(context->audio_st.st->codec, &pkt, context->audio_st.tmp_frame, &got_packet); } else { av_frame_make_writable(context->audio_st.frame); switch_buffer_read(context->audio_buffer, context->audio_st.frame->data[0], bytes); - context->audio_st.frame->pts = context->audio_st.next_pts; - context->audio_st.next_pts += context->audio_st.frame->nb_samples; + + switch_core_timer_sync(&context->audio_timer); + context->audio_st.frame->pts = context->audio_timer.samplecount; + //context->audio_st.frame->pts = context->audio_st.next_pts; + //context->audio_st.next_pts += context->audio_st.frame->nb_samples; ret = avcodec_encode_audio2(context->audio_st.st->codec, &pkt, context->audio_st.frame, &got_packet); } @@ -1744,6 +1789,7 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s } } + break; } @@ -1917,11 +1963,9 @@ static switch_status_t av_file_write_video(switch_file_handle_t *handle, switch_ context->eh.mutex = context->mutex; context->eh.video_st = &context->video_st; context->eh.fc = context->fc; - if (switch_core_timer_init(&context->timer, "soft", 1, 1, handle->memory_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timer Activation Fail\n"); - switch_goto_status(SWITCH_STATUS_FALSE, end); - } - context->eh.timer = &context->timer; + context->eh.mm = &handle->mm; + context->eh.timer = &context->video_timer; + context->eh.other_timer = &context->audio_timer; switch_queue_create(&context->eh.video_queue, SWITCH_CORE_QUEUE_LEN, handle->memory_pool); switch_threadattr_create(&thd_attr, handle->memory_pool); diff --git a/src/mod/applications/mod_avmd/mod_avmd.c b/src/mod/applications/mod_avmd/mod_avmd.c index 3722365397..a4a1c07815 100644 --- a/src/mod/applications/mod_avmd/mod_avmd.c +++ b/src/mod/applications/mod_avmd/mod_avmd.c @@ -216,6 +216,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + if (switch_event_reserve_subclass(AVMD_EVENT_BEEP) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", AVMD_EVENT_BEEP); + return SWITCH_STATUS_TERM; + } + + switch_log_printf( SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, @@ -322,6 +329,8 @@ SWITCH_STANDARD_APP(avmd_start_function) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) { + switch_event_free_subclass(AVMD_EVENT_BEEP); + #ifdef FASTMATH destroy_fast_acosf(); #endif diff --git a/src/mod/applications/mod_bert/mod_bert.c b/src/mod/applications/mod_bert/mod_bert.c index 35f7b87ab8..70badc1354 100644 --- a/src/mod/applications/mod_bert/mod_bert.c +++ b/src/mod/applications/mod_bert/mod_bert.c @@ -377,6 +377,24 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_bert_load) { switch_application_interface_t *app_interface = NULL; + if (switch_event_reserve_subclass(BERT_EVENT_TIMEOUT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", BERT_EVENT_TIMEOUT); + return SWITCH_STATUS_TERM; + } + + + if (switch_event_reserve_subclass(BERT_EVENT_LOST_SYNC) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", BERT_EVENT_LOST_SYNC); + return SWITCH_STATUS_TERM; + } + + + if (switch_event_reserve_subclass(BERT_EVENT_IN_SYNC) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", BERT_EVENT_IN_SYNC); + return SWITCH_STATUS_TERM; + } + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_APP(app_interface, "bert_test", "Start BERT Test", "Start BERT Test", bert_test_function, "", SAF_NONE); @@ -385,6 +403,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_bert_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_bert_shutdown) { + switch_event_free_subclass(BERT_EVENT_TIMEOUT); + switch_event_free_subclass(BERT_EVENT_LOST_SYNC); + switch_event_free_subclass(BERT_EVENT_IN_SYNC); + return SWITCH_STATUS_UNLOAD; } diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c index 594908dd4d..2b0e28a5e7 100644 --- a/src/mod/applications/mod_callcenter/mod_callcenter.c +++ b/src/mod/applications/mod_callcenter/mod_callcenter.c @@ -3421,6 +3421,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load) switch_api_interface_t *api_interface; switch_status_t status; + + if (switch_event_reserve_subclass(CALLCENTER_EVENT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", CALLCENTER_EVENT); + return SWITCH_STATUS_TERM; + } + memset(&globals, 0, sizeof(globals)); globals.pool = pool; @@ -3495,6 +3501,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_callcenter_shutdown) switch_ssize_t keylen; int sanity = 0; + + switch_event_free_subclass(CALLCENTER_EVENT); + switch_mutex_lock(globals.mutex); if (globals.running == 1) { globals.running = 0; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 768f170988..26f895e8a4 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -4086,6 +4086,100 @@ SWITCH_STANDARD_API(uuid_video_bitrate_function) return SWITCH_STATUS_SUCCESS; } +#define CODEC_DEBUG_SYNTAX " audio|video " +SWITCH_STANDARD_API(uuid_codec_debug_function) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + char *mycmd = NULL, *argv[3] = { 0 }; + int argc = 0; + + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argc < 3) { + stream->write_function(stream, "-USAGE: %s\n", CODEC_DEBUG_SYNTAX); + } else { + switch_core_session_t *lsession = NULL; + + if ((lsession = switch_core_session_locate(argv[0]))) { + int level = atoi(argv[2]); + switch_media_type_t type = SWITCH_MEDIA_TYPE_AUDIO; + switch_core_session_message_t msg = { 0 }; + + if (!strcasecmp(argv[1], "video")) { + type = SWITCH_MEDIA_TYPE_VIDEO; + } + + if (level < 0) level = 0; + + msg.message_id = SWITCH_MESSAGE_INDICATE_CODEC_DEBUG_REQ; + msg.numeric_arg = level; + msg.numeric_reply = type; + msg.from = __FILE__; + + switch_core_session_receive_message(lsession, &msg); + status = SWITCH_STATUS_SUCCESS; + switch_core_session_rwunlock(lsession); + } + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation Failed\n"); + } + + switch_safe_free(mycmd); + + return SWITCH_STATUS_SUCCESS; +} + + +#define CODEC_PARAM_SYNTAX " audio|video read|write " +SWITCH_STANDARD_API(uuid_codec_param_function) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + char *mycmd = NULL, *argv[5] = { 0 }; + int argc = 0; + switch_core_session_message_t msg = { 0 }; + + msg.string_array_arg[4] = "NOT SENT"; + + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argc < 3) { + stream->write_function(stream, "-USAGE: %s\n", CODEC_PARAM_SYNTAX); + } else { + switch_core_session_t *lsession = NULL; + + if ((lsession = switch_core_session_locate(argv[0]))) { + msg.message_id = SWITCH_MESSAGE_INDICATE_CODEC_SPECIFIC_REQ; + msg.string_array_arg[0] = argv[1]; + msg.string_array_arg[1] = argv[2]; + msg.string_array_arg[2] = argv[3]; + msg.string_array_arg[3] = argv[4]; + msg.from = __FILE__; + + switch_core_session_receive_message(lsession, &msg); + status = SWITCH_STATUS_SUCCESS; + switch_core_session_rwunlock(lsession); + } + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Command sent reply: [%s]\n", msg.string_array_arg[4]); + } else { + stream->write_function(stream, "-ERR Operation Failed [%s]\n", msg.string_array_arg[4]); + } + + switch_safe_free(mycmd); + + return SWITCH_STATUS_SUCCESS; +} + #define DEBUG_MEDIA_SYNTAX " " SWITCH_STANDARD_API(uuid_debug_media_function) @@ -6967,6 +7061,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_broadcast", "Execute dialplan application", uuid_broadcast_function, BROADCAST_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_buglist", "List media bugs on a session", uuid_buglist_function, BUGLIST_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_codec_debug", "Send codec a debug message", uuid_codec_debug_function, CODEC_DEBUG_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_codec_param", "Send codec a param", uuid_codec_param_function, CODEC_PARAM_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_debug_media", "Debug media", uuid_debug_media_function, DEBUG_MEDIA_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_deflect", "Send a deflect", uuid_deflect, UUID_DEFLECT_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_displace", "Displace audio", session_displace_function, " [start|stop] [] [mux]"); @@ -7144,6 +7240,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_broadcast ::console::list_uuid"); switch_console_set_complete("add uuid_buglist ::console::list_uuid"); switch_console_set_complete("add uuid_chat ::console::list_uuid"); + switch_console_set_complete("add uuid_codec_debug ::console::list_uuid audio"); + switch_console_set_complete("add uuid_codec_debug ::console::list_uuid video"); + switch_console_set_complete("add uuid_codec_param ::console::list_uuid audio read"); + switch_console_set_complete("add uuid_codec_param ::console::list_uuid audio write"); + switch_console_set_complete("add uuid_codec_param ::console::list_uuid video read"); + switch_console_set_complete("add uuid_codec_param ::console::list_uuid video write"); switch_console_set_complete("add uuid_debug_media ::console::list_uuid"); switch_console_set_complete("add uuid_deflect ::console::list_uuid"); switch_console_set_complete("add uuid_displace ::console::list_uuid"); diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 17d8438be3..b96563f178 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -401,7 +401,7 @@ switch_status_t conference_api_sub_conference_video_vmute_snap(conference_member if (member == NULL) return SWITCH_STATUS_GENERR; - if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) { + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { return SWITCH_STATUS_SUCCESS; } @@ -430,7 +430,7 @@ switch_status_t conference_api_sub_vmute(conference_member_t *member, switch_str if (member == NULL) return SWITCH_STATUS_GENERR; - if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) { + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { return SWITCH_STATUS_SUCCESS; } @@ -486,7 +486,7 @@ switch_status_t conference_api_sub_unvmute(conference_member_t *member, switch_s if (member == NULL) return SWITCH_STATUS_GENERR; - if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) { + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_conference/conference_event.c b/src/mod/applications/mod_conference/conference_event.c index bbed44305e..b37ecd7e66 100644 --- a/src/mod/applications/mod_conference/conference_event.c +++ b/src/mod/applications/mod_conference/conference_event.c @@ -378,7 +378,7 @@ void conference_event_la_command_handler(switch_live_array_t *la, const char *cm void conference_event_adv_la(conference_obj_t *conference, conference_member_t *member, switch_bool_t join) { - //if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) { + //if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { switch_channel_set_flag(member->channel, CF_VIDEO_REFRESH_REQ); switch_core_media_gen_key_frame(member->session); //} diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index bae690f061..8d5af7fa62 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -170,7 +170,7 @@ void conference_member_update_status_field(conference_member_t *member) if (switch_channel_test_flag(member->channel, CF_VIDEO) || member->avatar_png_img) { video = cJSON_CreateObject(); cJSON_AddItemToObject(video, "avatarPresented", cJSON_CreateBool(!!member->avatar_png_img)); - cJSON_AddItemToObject(video, "mediaFlow", cJSON_CreateString(member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY ? "sendOnly" : "sendRecv")); + cJSON_AddItemToObject(video, "mediaFlow", cJSON_CreateString(switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY ? "sendOnly" : "sendRecv")); cJSON_AddItemToObject(video, "muted", cJSON_CreateBool(!conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN))); cJSON_AddItemToObject(video, "floor", cJSON_CreateBool(member && member->id == member->conference->video_floor_holder)); if (member && member->id == member->conference->video_floor_holder && conference_utils_test_flag(member->conference, CFLAG_VID_FLOOR_LOCK)) { @@ -675,7 +675,7 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m switch_mutex_lock(member->audio_out_mutex); lock_member(member); switch_mutex_lock(conference->member_mutex); - + if (member->rec) { conference->recording_members++; } @@ -702,10 +702,6 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m switch_mutex_unlock(conference->canvas_mutex); } - if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) { - conference_utils_member_clear_flag_locked(member, MFLAG_CAN_BE_SEEN); - } - conference->members = member; conference_utils_member_set_flag_locked(member, MFLAG_INTREE); switch_mutex_unlock(conference->member_mutex); @@ -713,6 +709,11 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m if (!conference_utils_member_test_flag(member, MFLAG_NOCHANNEL)) { + + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { + conference_utils_member_clear_flag_locked(member, MFLAG_CAN_BE_SEEN); + } + if (conference_utils_member_test_flag(member, MFLAG_GHOST)) { conference->count_ghosts++; } else { @@ -728,7 +729,6 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m conference_send_presence(conference); channel = switch_core_session_get_channel(member->session); - member->video_flow = switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO); conference_video_check_avatar(member, SWITCH_FALSE); @@ -922,24 +922,26 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m member->status_field = cJSON_CreateString(""); cJSON_AddItemToArray(member->json, member->status_field); - switch_channel_get_variables(member->channel, &var_event); + if (conference_utils_test_flag(member->conference, CFLAG_JSON_STATUS)) { + switch_channel_get_variables(member->channel, &var_event); - dvars = cJSON_CreateObject(); + dvars = cJSON_CreateObject(); - for (hi = var_event->headers; hi; hi = hi->next) { - if (!strncasecmp(hi->name, "verto_dvar_", 11)) { - char *var = hi->name + 11; - - if (var) { - cJSON_AddItemToObject(dvars, var, cJSON_CreateString(hi->value)); + for (hi = var_event->headers; hi; hi = hi->next) { + if (!strncasecmp(hi->name, "verto_dvar_", 11)) { + char *var = hi->name + 11; + + if (var) { + cJSON_AddItemToObject(dvars, var, cJSON_CreateString(hi->value)); + } } } + + cJSON_AddItemToArray(member->json, dvars); + + switch_event_destroy(&var_event); } - cJSON_AddItemToArray(member->json, dvars); - - switch_event_destroy(&var_event); - cJSON_AddItemToArray(member->json, cJSON_CreateNull()); conference_member_update_status_field(member); @@ -1158,6 +1160,8 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m conference->count--; } + conference_video_check_flush(member); + if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) { if (!--conference->end_count) { //conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT); diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index f53e09ecae..e78aa25700 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -888,7 +888,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member, return SWITCH_STATUS_FALSE; } - if (member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) { + if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) { return SWITCH_STATUS_FALSE; } @@ -1200,7 +1200,7 @@ void conference_video_destroy_canvas(mcu_canvas_t **canvasP) { void conference_video_write_canvas_image_to_codec_group(conference_obj_t *conference, mcu_canvas_t *canvas, codec_set_t *codec_set, int codec_index, uint32_t timestamp, switch_bool_t need_refresh, - switch_bool_t need_keyframe, switch_bool_t need_reset) + switch_bool_t send_keyframe, switch_bool_t need_reset) { conference_member_t *imember; @@ -1219,12 +1219,12 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer if (need_reset) { int type = 1; // sum flags: 1 encoder; 2; decoder - switch_core_codec_control(&codec_set->codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, NULL, NULL); + switch_core_codec_control(&codec_set->codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL); need_refresh = SWITCH_TRUE; } - if (need_refresh || need_keyframe) { - switch_core_codec_control(&codec_set->codec, SCC_VIDEO_REFRESH, SCCT_NONE, NULL, NULL, NULL); + if (send_keyframe) { + switch_core_codec_control(&codec_set->codec, SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL); } do { @@ -1264,18 +1264,15 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer continue; } - if (imember->video_flow == SWITCH_MEDIA_FLOW_RECVONLY) { - continue; - } - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || + switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } - //if (need_refresh) { - // switch_core_session_request_video_refresh(imember->session); - //} + if (need_refresh) { + switch_core_session_request_video_refresh(imember->session); + } //switch_core_session_write_encoded_video_frame(imember->session, frame, 0, 0); switch_set_flag(frame, SFF_ENCODED); @@ -1432,6 +1429,7 @@ void conference_video_launch_muxing_write_thread(conference_member_t *member) switch_mutex_lock(conference_globals.hash_mutex); if (!member->video_muxing_write_thread) { switch_threadattr_create(&thd_attr, member->pool); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&member->video_muxing_write_thread, thd_attr, conference_video_muxing_write_thread_run, member, member->pool); } @@ -1459,61 +1457,75 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_ void *pop; switch_frame_t *frame; int loops = 0; - + switch_time_t last = 0; + if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) { return NULL; } while(conference_utils_member_test_flag(member, MFLAG_RUNNING)) { - if (conference_utils_member_test_flag(member, MFLAG_RUNNING)) { - if (switch_queue_pop(member->mux_out_queue, &pop) == SWITCH_STATUS_SUCCESS) { - mcu_layer_t *layer = NULL; - mcu_canvas_t *canvas = NULL; + if (switch_queue_pop(member->mux_out_queue, &pop) == SWITCH_STATUS_SUCCESS) { + mcu_layer_t *layer = NULL; + mcu_canvas_t *canvas = NULL; - if (!pop) { - break; - } + if (!pop) { + break; + } - if (loops == 0 || loops == 50) { - switch_core_media_gen_key_frame(member->session); - switch_core_session_request_video_refresh(member->session); + if (loops == 0 || loops == 50) { + switch_core_media_gen_key_frame(member->session); + switch_core_session_request_video_refresh(member->session); + } + + loops++; + + if ((switch_size_t)pop != 1) { + frame = (switch_frame_t *) pop; + if (switch_test_flag(frame, SFF_ENCODED)) { + switch_core_session_write_encoded_video_frame(member->session, frame, 0, 0); + } else { + switch_core_session_write_video_frame(member->session, frame, SWITCH_IO_FLAG_NONE, 0); } - loops++; - - if ((switch_size_t)pop != 1) { - frame = (switch_frame_t *) pop; - if (switch_test_flag(frame, SFF_ENCODED)) { - switch_core_session_write_encoded_video_frame(member->session, frame, 0, 0); - } else { - switch_core_session_write_video_frame(member->session, frame, SWITCH_IO_FLAG_NONE, 0); + if (!switch_test_flag(frame, SFF_ENCODED) || frame->m) { + switch_time_t now = switch_time_now(); + + if (last) { + int delta = now - last; + if (delta > member->conference->video_fps.ms * 2) { + switch_core_session_request_video_refresh(member->session); + } } - switch_frame_buffer_free(member->fb, &frame); + last = now; + + } - switch_mutex_lock(member->conference->canvas_mutex); - if (member->video_layer_id > -1 && member->canvas_id > -1) { - canvas = member->conference->canvases[member->canvas_id]; - layer = &canvas->layers[member->video_layer_id]; + switch_frame_buffer_free(member->fb, &frame); + } - if (layer->need_patch) { - switch_mutex_lock(canvas->mutex); - } else { - canvas = NULL; - layer = NULL; - } - } - switch_mutex_unlock(member->conference->canvas_mutex); + switch_mutex_lock(member->conference->canvas_mutex); + if (member->video_layer_id > -1 && member->canvas_id > -1) { + canvas = member->conference->canvases[member->canvas_id]; + layer = &canvas->layers[member->video_layer_id]; - if (canvas) { - switch_thread_rwlock_rdlock(canvas->video_rwlock); - conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE); - layer->need_patch = 0; - switch_thread_rwlock_unlock(canvas->video_rwlock); - switch_mutex_unlock(canvas->mutex); + if (layer->need_patch) { + switch_mutex_lock(canvas->mutex); + } else { + canvas = NULL; + layer = NULL; } } + switch_mutex_unlock(member->conference->canvas_mutex); + + if (canvas) { + switch_thread_rwlock_rdlock(canvas->video_rwlock); + conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE); + layer->need_patch = 0; + switch_thread_rwlock_unlock(canvas->video_rwlock); + switch_mutex_unlock(canvas->mutex); + } } } @@ -1571,7 +1583,7 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo canvas = member->conference->canvases[member->canvas_id]; if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) && - (!switch_channel_test_flag(member->channel, CF_VIDEO) || member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY)) { + (!switch_channel_test_flag(member->channel, CF_VIDEO) || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY)) { return; } @@ -1581,7 +1593,7 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo member->avatar_patched = 0; - if (!force && switch_channel_test_flag(member->channel, CF_VIDEO) && member->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) { + if (!force && switch_channel_test_flag(member->channel, CF_VIDEO) && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO); } else { if (member->conference->no_video_avatar) { @@ -1705,7 +1717,7 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca if (!layer && (canvas->layers_used < canvas->total_layers || (avatar_layers && !member->avatar_png_img) || conference_utils_member_test_flag(member, MFLAG_MOD)) && - (member->avatar_png_img || member->video_flow != SWITCH_MEDIA_FLOW_SENDONLY)) { + (member->avatar_png_img || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)) { /* find an empty layer */ for (i = 0; i < canvas->total_layers; i++) { mcu_layer_t *xlayer = &canvas->layers[i]; @@ -1778,7 +1790,7 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t size = switch_queue_size(member->video_queue); } while(size > 1); - if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && member->video_layer_id > -1 && member->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) { + if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && member->video_layer_id > -1 && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { if (img) { member->good_img++; if ((member->good_img % (int)(member->conference->video_fps.fps * 10)) == 0) { @@ -1817,7 +1829,10 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_t *layer) { - if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps) { + + if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) { + member->managed_kps = 0; + } else if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps) { switch_core_session_message_t msg = { 0 }; int kps; int w = 320; @@ -1900,9 +1915,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr canvas->video_timer_reset = 1; packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN); - + while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT) && conference_utils_test_flag(conference, CFLAG_VIDEO_MUXING)) { - switch_bool_t need_refresh = SWITCH_FALSE, need_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; + switch_bool_t need_refresh = SWITCH_FALSE, send_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; switch_time_t now; int min_members = 0; int count_changed = 0; @@ -1970,7 +1985,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (count_changed) { need_refresh = 1; - need_keyframe = 1; + send_keyframe = 1; do_refresh = 100; } @@ -2030,7 +2045,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (imember->watching_canvas_id == canvas->canvas_id && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; } if (conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) && @@ -2129,7 +2144,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_img_free(&img); } - if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO) && imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY)))) { + if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)))) { if (conference_video_find_layer(conference, canvas, imember, &layer) == SWITCH_STATUS_SUCCESS) { imember->layer_timeout = 0; } else { @@ -2220,7 +2235,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr conference_member_t *omember; if (video_key_freq && (now - last_key_time) > video_key_freq) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; last_key_time = now; } @@ -2245,7 +2260,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; } if (count_changed) { @@ -2255,7 +2270,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr total += conference->members_with_avatar; } - if (imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { total--; } @@ -2268,7 +2283,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } } - if (imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) { conference_video_pop_next_image(imember, &imember->pcanvas_img); } @@ -2299,7 +2314,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (imember = conference->members; imember; imember = imember->next) { int i = 0; - if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO || imember->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) || + if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } @@ -2308,7 +2323,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr mcu_layer_t *layer = NULL; switch_image_t *use_img = NULL; - if (!omember->session || !switch_channel_test_flag(omember->channel, CF_VIDEO) || omember->video_flow == SWITCH_MEDIA_FLOW_SENDONLY) { + if (!omember->session || !switch_channel_test_flag(omember->channel, CF_VIDEO) || switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { continue; } @@ -2418,7 +2433,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_session_request_video_refresh(imember->session); } - if (need_keyframe) { + if (send_keyframe) { switch_core_media_gen_key_frame(imember->session); } @@ -2468,7 +2483,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } if (layer->cur_img) { - if (layer->member) { + if (layer->member && switch_core_cpu_count() > 2) { layer->need_patch = 1; } else { conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE); @@ -2510,14 +2525,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (canvas->send_keyframe > 0) { if (canvas->send_keyframe == 1 || (canvas->send_keyframe % 10) == 0) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; need_refresh = SWITCH_TRUE; } canvas->send_keyframe--; } if (video_key_freq && (now - last_key_time) > video_key_freq) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; last_key_time = now; } @@ -2547,12 +2562,12 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr write_frame.img = write_img; + wait_for_canvas(canvas); + if (canvas->recording) { conference_video_check_recording(conference, canvas, &write_frame); } - wait_for_canvas(canvas); - if (conference->canvas_count > 1) { switch_image_t *img_copy = NULL; @@ -2567,10 +2582,11 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { write_codecs[i]->frame.img = write_img; conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, - timestamp, need_refresh, need_keyframe, need_reset); + timestamp, need_refresh, send_keyframe, need_reset); if (canvas->video_write_bandwidth) { - switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, SCCT_INT, &canvas->video_write_bandwidth, NULL, NULL); + switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, + SCCT_INT, &canvas->video_write_bandwidth, SCCT_NONE, NULL, NULL, NULL); canvas->video_write_bandwidth = 0; } @@ -2588,19 +2604,16 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } if (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || + switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) { continue; } - - if (imember->video_flow == SWITCH_MEDIA_FLOW_RECVONLY) { - continue; - } - + if (need_refresh) { switch_core_session_request_video_refresh(imember->session); } - if (need_keyframe) { + if (send_keyframe) { switch_core_media_gen_key_frame(imember->session); } @@ -2707,7 +2720,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN); while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT) && conference_utils_test_flag(conference, CFLAG_VIDEO_MUXING)) { - switch_bool_t need_refresh = SWITCH_FALSE, need_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; + switch_bool_t need_refresh = SWITCH_FALSE, send_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; switch_time_t now; int min_members = 0; int count_changed = 0; @@ -2741,14 +2754,14 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (canvas->send_keyframe > 0) { if (canvas->send_keyframe == 1 || (canvas->send_keyframe % 10) == 0) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; need_refresh = SWITCH_TRUE; } canvas->send_keyframe--; } if (video_key_freq && (now - last_key_time) > video_key_freq) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; last_key_time = now; } @@ -2792,7 +2805,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (imember->watching_canvas_id == canvas->canvas_id && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; } if (conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) && @@ -2912,10 +2925,11 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (min_members && conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) { for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { write_codecs[i]->frame.img = write_img; - conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, timestamp, need_refresh, need_keyframe, need_reset); + conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, timestamp, need_refresh, send_keyframe, need_reset); if (canvas->video_write_bandwidth) { - switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, SCCT_INT, &canvas->video_write_bandwidth, NULL, NULL); + switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, + SCCT_INT, &canvas->video_write_bandwidth, SCCT_NONE, NULL, NULL, NULL); canvas->video_write_bandwidth = 0; } } @@ -2931,7 +2945,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ continue; } - if (imember->video_flow == SWITCH_MEDIA_FLOW_RECVONLY) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { continue; } @@ -2944,7 +2958,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ switch_core_session_request_video_refresh(imember->session); } - if (need_keyframe) { + if (send_keyframe) { switch_core_media_gen_key_frame(imember->session); } @@ -3024,7 +3038,7 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente continue; } - if (imember->video_flow == SWITCH_MEDIA_FLOW_SENDONLY && !imember->avatar_png_img) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !imember->avatar_png_img) { continue; } @@ -3080,7 +3094,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_ return; } - if (member && member->video_flow == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) { + if (member && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) { return; } @@ -3264,13 +3278,27 @@ void conference_video_write_frame(conference_obj_t *conference, conference_membe switch_core_session_rwunlock(isession); } + + if (want_refresh) { + for (imember = conference->members; imember; imember = imember->next) { + switch_core_session_t *isession = imember->session; + + if (!isession || switch_core_session_read_lock(isession) != SWITCH_STATUS_SUCCESS) { + continue; + } + + if (!isession || !switch_channel_test_flag(imember->channel, CF_VIDEO) ) { + continue; + } + + switch_core_session_request_video_refresh(imember->session); + switch_core_session_rwunlock(isession); + } + } + switch_mutex_unlock(conference->member_mutex); switch_img_free(&tmp_frame.img); - - if (want_refresh && floor_holder->session) { - switch_core_session_request_video_refresh(floor_holder->session); - } } switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data) @@ -3286,6 +3314,9 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session, return SWITCH_STATUS_SUCCESS; } + if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) { + return SWITCH_STATUS_SUCCESS; + } if (switch_thread_rwlock_tryrdlock(member->conference->rwlock) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index b0be87268d..0802b95987 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -288,13 +288,29 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob if (conference_utils_member_test_flag(imember, MFLAG_RUNNING) && imember->session) { switch_channel_t *channel = switch_core_session_get_channel(imember->session); - + switch_media_flow_t video_media_flow; + if ((!floor_holder || (imember->score_iir > SCORE_IIR_SPEAKING_MAX && (floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN)))) {// && //(!conference_utils_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) { floor_holder = imember; } - if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO) && imember->video_flow != SWITCH_MEDIA_FLOW_SENDONLY) { + video_media_flow = switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO); + + if (video_media_flow != imember->video_media_flow) { + imember->video_media_flow = video_media_flow; + + if (imember->video_media_flow == SWITCH_MEDIA_FLOW_SENDONLY) { + conference_utils_member_clear_flag(imember, MFLAG_CAN_BE_SEEN); + conference_video_find_floor(imember, SWITCH_FALSE); + } else { + conference_utils_member_set_flag(imember, MFLAG_CAN_BE_SEEN); + conference_video_find_floor(imember, SWITCH_TRUE); + switch_core_session_request_video_refresh(imember->session); + } + } + + if (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_VIDEO) && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) { members_with_video++; } diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index b1c78a210e..ff19ff44f5 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -744,7 +744,6 @@ struct conference_member { char *video_logo; char *video_mute_png; char *video_reservation_id; - switch_media_flow_t video_flow; switch_frame_buffer_t *fb; switch_image_t *avatar_png_img; switch_image_t *video_mute_img; @@ -755,6 +754,7 @@ struct conference_member { int good_img; int auto_avatar; int avatar_patched; + switch_media_flow_t video_media_flow; mcu_canvas_t *canvas; switch_image_t *pcanvas_img; }; @@ -917,6 +917,7 @@ void conference_video_layer_set_banner(conference_member_t *member, mcu_layer_t void conference_video_layer_set_logo(conference_member_t *member, mcu_layer_t *layer, const char *path); void conference_video_detach_video_layer(conference_member_t *member); void conference_video_check_used_layers(mcu_canvas_t *canvas); +void conference_video_check_flush(conference_member_t *member); void conference_video_set_canvas_letterbox_bgcolor(mcu_canvas_t *canvas, char *color); void conference_video_set_canvas_bgcolor(mcu_canvas_t *canvas, char *color); void conference_video_scale_and_patch(mcu_layer_t *layer, switch_image_t *ximg, switch_bool_t freeze); diff --git a/src/mod/applications/mod_curl/mod_curl.c b/src/mod/applications/mod_curl/mod_curl.c index 9b9c7cc12b..4499fe4cea 100644 --- a/src/mod/applications/mod_curl/mod_curl.c +++ b/src/mod/applications/mod_curl/mod_curl.c @@ -1014,6 +1014,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_curl_load) { switch_api_interface_t *api_interface; switch_application_interface_t *app_interface; + + if (switch_event_reserve_subclass(HTTP_SENDFILE_ACK_EVENT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", HTTP_SENDFILE_ACK_EVENT); + 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); @@ -1037,6 +1043,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_curl_load) Macro expands to: switch_status_t mod_cidlookup_shutdown() */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_curl_shutdown) { + + switch_event_free_subclass(HTTP_SENDFILE_ACK_EVENT); + /* Cleanup dynamically allocated config settings */ return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_cv/mod_cv.cpp b/src/mod/applications/mod_cv/mod_cv.cpp index 50dd5862b4..9f5d95dac0 100644 --- a/src/mod/applications/mod_cv/mod_cv.cpp +++ b/src/mod/applications/mod_cv/mod_cv.cpp @@ -1334,6 +1334,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cv_load) switch_application_interface_t *app_interface; switch_api_interface_t *api_interface; + if (switch_event_reserve_subclass(MY_EVENT_VIDEO_DETECT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_VIDEO_DETECT); + return SWITCH_STATUS_TERM; + } + *module_interface = switch_loadable_module_create_module_interface(pool, modname); MODULE_INTERFACE = *module_interface; @@ -1354,7 +1359,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cv_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cv_shutdown) { - return SWITCH_STATUS_UNLOAD; + + switch_event_free_subclass(MY_EVENT_VIDEO_DETECT); + + return SWITCH_STATUS_UNLOAD; } diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 8cc2947343..310aa302e4 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -5909,6 +5909,11 @@ SWITCH_STANDARD_APP(deduplicate_dtmf_app_function) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dptools_shutdown) { + + switch_event_free_subclass(FILE_STRING_CLOSE); + switch_event_free_subclass(FILE_STRING_FAIL); + switch_event_free_subclass(FILE_STRING_OPEN); + switch_event_unbind_callback(pickup_pres_event_handler); switch_mutex_destroy(globals.pickup_mutex); switch_core_hash_destroy(&globals.pickup_hash); @@ -5926,6 +5931,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) switch_chat_interface_t *chat_interface; switch_file_interface_t *file_interface; + if (switch_event_reserve_subclass(FILE_STRING_CLOSE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", FILE_STRING_CLOSE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(FILE_STRING_FAIL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", FILE_STRING_FAIL); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(FILE_STRING_OPEN) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", FILE_STRING_OPEN); + return SWITCH_STATUS_TERM; + } + globals.pool = pool; switch_core_hash_init(&globals.pickup_hash); switch_mutex_init(&globals.pickup_mutex, SWITCH_MUTEX_NESTED, globals.pool); diff --git a/src/mod/applications/mod_hiredis/TODO b/src/mod/applications/mod_hiredis/TODO index 9966f0c7a0..08d8c0a032 100644 --- a/src/mod/applications/mod_hiredis/TODO +++ b/src/mod/applications/mod_hiredis/TODO @@ -2,5 +2,6 @@ 2. add lock for hiredis_profile for destroy vs running commands 3. Look into refactor/cleanup of xml processing 4. Add tab complete for profile names for APIs, and possibly for supported actions(and in theory look into key listing from redis) +5. Add linked list session pvt structure for keeping track of limit incr's on a session by session basis diff --git a/src/mod/applications/mod_hiredis/hiredis_profile.c b/src/mod/applications/mod_hiredis/hiredis_profile.c index f83f5cf55f..ab2d152e0c 100644 --- a/src/mod/applications/mod_hiredis/hiredis_profile.c +++ b/src/mod/applications/mod_hiredis/hiredis_profile.c @@ -143,6 +143,11 @@ switch_status_t hiredis_profile_execute_sync(hiredis_profile_t *profile, const c response = redisCommand(profile->conn->context, data); + if ( !response ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: empty response received\n"); + return SWITCH_STATUS_GENERR; + } + switch(response->type) { case REDIS_REPLY_STATUS: /* fallthrough */ case REDIS_REPLY_STRING: diff --git a/src/mod/applications/mod_hiredis/mod_hiredis.c b/src/mod/applications/mod_hiredis/mod_hiredis.c index f5cc90f5f3..8a6077390c 100644 --- a/src/mod/applications/mod_hiredis/mod_hiredis.c +++ b/src/mod/applications/mod_hiredis/mod_hiredis.c @@ -64,7 +64,7 @@ SWITCH_STANDARD_APP(raw_app) return; } - if ( hiredis_profile_execute_sync(profile, data, &response) != SWITCH_STATUS_SUCCESS) { + if ( hiredis_profile_execute_sync(profile, cmd, &response) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: profile[%s] error executing [%s] because [%s]\n", profile_name, cmd, response); } @@ -93,7 +93,7 @@ SWITCH_STANDARD_API(raw_api) data++; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: debug: profile[%s] for command [%s]\n", input, data); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hiredis: debug: profile[%s] for command [%s]\n", input, data); profile = switch_core_hash_find(mod_hiredis_globals.profiles, input); @@ -127,7 +127,7 @@ SWITCH_LIMIT_INCR(hiredis_limit_incr) time_t now = switch_epoch_time_now(NULL); switch_status_t status = SWITCH_STATUS_SUCCESS; - if ( !zstr(realm) ) { + if ( zstr(realm) ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis: realm must be defined\n"); switch_goto_status(SWITCH_STATUS_GENERR, done); } @@ -185,6 +185,11 @@ SWITCH_LIMIT_RELEASE(hiredis_limit_release) switch_goto_status(SWITCH_STATUS_GENERR, done); } + if ( !realm && !resource ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "hiredis does not yet support release on NULL realm[%s] and resource[%s]\n", realm, resource); + switch_goto_status(SWITCH_STATUS_GENERR, done); + } + hashkey = switch_mprintf("decr %s", resource); if ( hiredis_profile_execute_sync(profile, hashkey, &response) != SWITCH_STATUS_SUCCESS) { diff --git a/src/mod/applications/mod_mp4/mod_mp4.cpp b/src/mod/applications/mod_mp4/mod_mp4.cpp index 6617b8be29..64d6c728b3 100644 --- a/src/mod/applications/mod_mp4/mod_mp4.cpp +++ b/src/mod/applications/mod_mp4/mod_mp4.cpp @@ -266,7 +266,7 @@ static void *SWITCH_THREAD_FUNC play_video_function(switch_thread_t *thread, voi { AVParams * pt = reinterpret_cast(obj); u_int next = 0, first = 0xffffffff; - u_int64_t ts = 0, control = 0; + uint64_t ts = 0, control = 0; bool ok; bool sent = true; @@ -323,7 +323,7 @@ static void *SWITCH_THREAD_FUNC play_audio_function(switch_thread_t *thread, voi { AVParams * pt = reinterpret_cast(obj); u_int next = 0, first = 0xffffffff; - u_int64_t ts = 0, control = 0; + uint64_t ts = 0, control = 0; bool ok; bool sent = true; diff --git a/src/mod/applications/mod_mp4/mp4_helper.cpp b/src/mod/applications/mod_mp4/mp4_helper.cpp index c560cddb7d..ae6ee81da1 100644 --- a/src/mod/applications/mod_mp4/mp4_helper.cpp +++ b/src/mod/applications/mod_mp4/mp4_helper.cpp @@ -129,7 +129,7 @@ namespace MP4 } ts = rt.last_frame; - if (!MP4ReadRtpPacket(fh, hint, rt.packet, (u_int8_t **) &buffer, &size, 0, header, true)) return false; + if (!MP4ReadRtpPacket(fh, hint, rt.packet, (uint8_t **) &buffer, &size, 0, header, true)) return false; ++rt.packet; return true; } diff --git a/src/mod/applications/mod_mp4/mp4_helper.hpp b/src/mod/applications/mod_mp4/mp4_helper.hpp index 6b41fd5ded..8f61cd6c6b 100644 --- a/src/mod/applications/mod_mp4/mp4_helper.hpp +++ b/src/mod/applications/mod_mp4/mp4_helper.hpp @@ -56,10 +56,10 @@ namespace MP4 }; struct RuntimeProperties { - u_int32_t frame; // sampleID - u_int16_t packetsPerFrame; - u_int16_t packet; // packetID - u_int32_t last_frame; // timestamp + uint32_t frame; // sampleID + uint16_t packetsPerFrame; + uint16_t packet; // packetID + uint32_t last_frame; // timestamp RuntimeProperties(): frame(0), packetsPerFrame(0), packet(0) { @@ -72,9 +72,9 @@ namespace MP4 MP4TrackId track; char * codecName; - u_int8_t payload; - u_int32_t clock; - u_int32_t packetLength; // packet Length in time (ms) + uint8_t payload; + uint32_t clock; + uint32_t packetLength; // packet Length in time (ms) RuntimeProperties runtime; diff --git a/src/mod/applications/mod_sms/mod_sms.c b/src/mod/applications/mod_sms/mod_sms.c index 4529244b0d..9f10ef98a5 100644 --- a/src/mod/applications/mod_sms/mod_sms.c +++ b/src/mod/applications/mod_sms/mod_sms.c @@ -609,6 +609,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sms_load) switch_chat_interface_t *chat_interface; switch_chat_application_interface_t *chat_app_interface; + if (switch_event_reserve_subclass(MY_EVENT_DELIVERY_REPORT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_DELIVERY_REPORT); + return SWITCH_STATUS_TERM; + } if (switch_event_bind(modname, SWITCH_EVENT_CUSTOM, MY_EVENT_SEND_MESSAGE, event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); @@ -640,6 +644,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_shutdown) { switch_event_unbind_callback(event_handler); + switch_event_free_subclass(MY_EVENT_DELIVERY_REPORT); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_sonar/mod_sonar.c b/src/mod/applications/mod_sonar/mod_sonar.c index 2457703b55..ebf641a351 100644 --- a/src/mod/applications/mod_sonar/mod_sonar.c +++ b/src/mod/applications/mod_sonar/mod_sonar.c @@ -218,6 +218,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sonar_load) { switch_application_interface_t *app_interface; + if (switch_event_reserve_subclass("sonar::ping") != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", "sonar::ping"); + 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); @@ -233,6 +239,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sonar_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sonar_shutdown) { + switch_event_free_subclass("sonar::ping"); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.c b/src/mod/applications/mod_spandsp/mod_spandsp.c index 6f15ed79a3..fdbb44c5a6 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp.c @@ -772,6 +772,42 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spandsp_init) switch_application_interface_t *app_interface; switch_api_interface_t *api_interface; + + if (switch_event_reserve_subclass(MY_EVENT_TDD_RECV_MESSAGE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TDD_RECV_MESSAGE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(SPANDSP_EVENT_TXFAXNEGOCIATERESULT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SPANDSP_EVENT_TXFAXNEGOCIATERESULT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(SPANDSP_EVENT_RXFAXNEGOCIATERESULT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SPANDSP_EVENT_RXFAXNEGOCIATERESULT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(SPANDSP_EVENT_TXFAXPAGERESULT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SPANDSP_EVENT_TXFAXPAGERESULT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(SPANDSP_EVENT_RXFAXPAGERESULT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SPANDSP_EVENT_RXFAXPAGERESULT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(SPANDSP_EVENT_TXFAXRESULT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SPANDSP_EVENT_TXFAXRESULT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(SPANDSP_EVENT_RXFAXRESULT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", SPANDSP_EVENT_RXFAXRESULT); + return SWITCH_STATUS_TERM; + } + memset(&spandsp_globals, 0, sizeof(spandsp_globals)); spandsp_globals.pool = pool; @@ -855,7 +891,14 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spandsp_shutdown) switch_event_unbind_callback(event_handler); switch_event_unbind_callback(tdd_event_handler); - + switch_event_free_subclass(MY_EVENT_TDD_RECV_MESSAGE); + switch_event_free_subclass(SPANDSP_EVENT_TXFAXNEGOCIATERESULT); + switch_event_free_subclass(SPANDSP_EVENT_RXFAXNEGOCIATERESULT); + switch_event_free_subclass(SPANDSP_EVENT_TXFAXPAGERESULT); + switch_event_free_subclass(SPANDSP_EVENT_RXFAXPAGERESULT); + switch_event_free_subclass(SPANDSP_EVENT_TXFAXRESULT); + switch_event_free_subclass(SPANDSP_EVENT_RXFAXRESULT); + mod_spandsp_fax_shutdown(); mod_spandsp_dsp_shutdown(); #if defined(MODEM_SUPPORT) diff --git a/src/mod/applications/mod_spandsp/mod_spandsp.h b/src/mod/applications/mod_spandsp/mod_spandsp.h index 183426e7eb..4e8f1d2427 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp.h +++ b/src/mod/applications/mod_spandsp/mod_spandsp.h @@ -49,6 +49,17 @@ typedef int zap_socket_t; #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES #include +#define SPANDSP_EVENT_TXFAXRESULT "spandsp::txfaxresult" +#define SPANDSP_EVENT_RXFAXRESULT "spandsp::rxfaxresult" + +#define SPANDSP_EVENT_TXFAXPAGERESULT "spandsp::txfaxpageresult" +#define SPANDSP_EVENT_RXFAXPAGERESULT "spandsp::rxfaxpageresult" + +#define SPANDSP_EVENT_TXFAXNEGOCIATERESULT "spandsp::txfaxnegociateresult" +#define SPANDSP_EVENT_RXFAXNEGOCIATERESULT "spandsp::rxfaxnegociateresult" + + + /* The global stuff */ struct spandsp_globals { switch_memory_pool_t *pool; diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 31bb3a74d7..3d175a18e5 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -42,16 +42,6 @@ #define DEFAULT_FEC_ENTRIES 3 #define DEFAULT_FEC_SPAN 3 -#define SPANDSP_EVENT_TXFAXRESULT "spandsp::txfaxresult" -#define SPANDSP_EVENT_RXFAXRESULT "spandsp::rxfaxresult" - -#define SPANDSP_EVENT_TXFAXPAGERESULT "spandsp::txfaxpageresult" -#define SPANDSP_EVENT_RXFAXPAGERESULT "spandsp::rxfaxpageresult" - -#define SPANDSP_EVENT_TXFAXNEGOCIATERESULT "spandsp::txfaxnegociateresult" -#define SPANDSP_EVENT_RXFAXNEGOCIATERESULT "spandsp::rxfaxnegociateresult" - - /***************************************************************************** OUR DEFINES AND STRUCTS *****************************************************************************/ diff --git a/src/mod/applications/mod_vmd/mod_vmd.c b/src/mod/applications/mod_vmd/mod_vmd.c index 89dcc76ab9..e1932cc0d1 100644 --- a/src/mod/applications/mod_vmd/mod_vmd.c +++ b/src/mod/applications/mod_vmd/mod_vmd.c @@ -508,6 +508,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load) { switch_application_interface_t *app_interface; switch_api_interface_t *api_interface; + + if (switch_event_reserve_subclass(VMD_EVENT_BEEP) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", VMD_EVENT_BEEP); + 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); @@ -599,6 +605,8 @@ SWITCH_STANDARD_APP(vmd_start_function) */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown) { + + switch_event_free_subclass(VMD_EVENT_BEEP); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Voicemail detection disabled\n"); return SWITCH_STATUS_SUCCESS; diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index da6180aa98..994ec33cce 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -2215,11 +2215,12 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p num = atoi(input); - file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext); - if (num < 1 || num > VM_MAX_GREETINGS) { + if (num < 0 || num > VM_MAX_GREETINGS) { status = SWITCH_STATUS_FALSE; - } else { + } else if (num > 0) { switch_file_handle_t fh = { 0 }; + + file_path = switch_mprintf("%s%sgreeting_%d.%s", dir_path, SWITCH_PATH_SEPARATOR, num, profile->file_ext); memset(&fh, 0, sizeof(fh)); greeting_args.input_callback = control_playback; memset(&cc, 0, sizeof(cc)); @@ -2235,15 +2236,25 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_event_t *params; TRY_CODE(switch_ivr_phrase_macro(session, VM_CHOOSE_GREETING_SELECTED_MACRO, input, NULL, NULL)); - sql = - switch_mprintf("update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s'", file_path, myid, + if (file_path == NULL) { + sql = + switch_mprintf("update voicemail_prefs set greeting_path=NULL where username='%s' and domain='%s'", myid, domain_name); + } else { + sql = + switch_mprintf("update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s'", + file_path, myid, domain_name); + } vm_execute_sql(profile, sql, profile->mutex); switch_safe_free(sql); switch_event_create_subclass(¶ms, SWITCH_EVENT_CUSTOM, VM_EVENT_MAINT); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "change-greeting"); - switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Greeting-Path", file_path); + if (file_path == NULL) { + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "remove-greeting"); + } else { + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Action", "change-greeting"); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Greeting-Path", file_path); + } switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-User", myid); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name); switch_channel_event_set_data(channel, params); @@ -2305,6 +2316,9 @@ static void voicemail_check_main(switch_core_session_t *session, vm_profile_t *p switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "VM-Domain", domain_name); switch_channel_event_set_data(channel, params); + if (zstr(buf) && !profile->allow_empty_password_auth) { + fail = 1; + } if (switch_xml_locate_user("id", myid, domain_name, switch_channel_get_variable(channel, "network_addr"), &xx_domain_root, &xx_domain, &xx_user, NULL, params) == SWITCH_STATUS_SUCCESS) { switch_xml_t x_result; diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index e349ddfaa9..ea563869fb 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -4393,6 +4393,21 @@ static mrcp_client_t *mod_unimrcp_client_create(switch_memory_pool_t *mod_pool) */ SWITCH_MODULE_LOAD_FUNCTION(mod_unimrcp_load) { + if (switch_event_reserve_subclass(MY_EVENT_PROFILE_CREATE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_CREATE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_PROFILE_CLOSE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_CLOSE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_PROFILE_OPEN) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_OPEN); + 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); @@ -4449,6 +4464,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_unimrcp_load) */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_unimrcp_shutdown) { + + switch_event_free_subclass(MY_EVENT_PROFILE_CREATE); + switch_event_free_subclass(MY_EVENT_PROFILE_CLOSE); + switch_event_free_subclass(MY_EVENT_PROFILE_OPEN); + synth_shutdown(); recog_shutdown(); diff --git a/src/mod/codecs/mod_openh264/mod_openh264.cpp b/src/mod/codecs/mod_openh264/mod_openh264.cpp index 9248e2ea24..723462b1f2 100644 --- a/src/mod/codecs/mod_openh264/mod_openh264.cpp +++ b/src/mod/codecs/mod_openh264/mod_openh264.cpp @@ -733,6 +733,8 @@ static switch_status_t switch_h264_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data) { @@ -741,7 +743,7 @@ static switch_status_t switch_h264_control(switch_codec_t *codec, h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info; switch(cmd) { - case SCC_VIDEO_REFRESH: + case SCC_VIDEO_GEN_KEYFRAME: context->need_key_frame = 1; break; case SCC_VIDEO_BANDWIDTH: diff --git a/src/mod/codecs/mod_opus/mod_opus.c b/src/mod/codecs/mod_opus/mod_opus.c index 92618a5d98..159a50c22b 100644 --- a/src/mod/codecs/mod_opus/mod_opus.c +++ b/src/mod/codecs/mod_opus/mod_opus.c @@ -34,7 +34,6 @@ #include "switch.h" #include "opus.h" - SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load); SWITCH_MODULE_DEFINITION(mod_opus, mod_opus_load, NULL, NULL); @@ -76,21 +75,24 @@ struct opus_context { uint32_t enc_frame_size; uint32_t dec_frame_size; uint32_t old_plpct; + uint32_t debug; + uint32_t use_jb_lookahead; opus_codec_settings_t codec_settings; }; struct { - int use_vbr; - int use_dtx; - int complexity; - int maxaveragebitrate; - int maxplaybackrate; + int use_vbr; + int use_dtx; + int complexity; + int maxaveragebitrate; + int maxplaybackrate; int sprop_maxcapturerate; int plpct; int asymmetric_samplerates; int keep_fec; int debuginfo; - switch_mutex_t *mutex; + uint32_t use_jb_lookahead; + switch_mutex_t *mutex; } opus_prefs; static struct { @@ -99,9 +101,9 @@ static struct { static switch_bool_t switch_opus_acceptable_rate(int rate) { - if ( rate != 8000 && rate != 12000 && rate != 16000 && rate != 24000 && rate != 48000) { + if (rate != 8000 && rate != 12000 && rate != 16000 && rate != 24000 && rate != 48000) { return SWITCH_FALSE; - } + } return SWITCH_TRUE; } @@ -110,21 +112,21 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (codec_fmtp) { opus_codec_settings_t local_settings = { 0 }; opus_codec_settings_t *codec_settings = &local_settings; - + if (codec_fmtp->private_info) { codec_settings = codec_fmtp->private_info; if (zstr(fmtp)) { memcpy(codec_settings, &default_codec_settings, sizeof(*codec_settings)); } } - + if (fmtp) { int x, argc; char *argv[10]; char *fmtp_dup = strdup(fmtp); - + switch_assert(fmtp_dup); - + argc = switch_separate_string(fmtp_dup, ';', argv, (sizeof(argv) / sizeof(argv[0]))); for (x = 0; x < argc; x++) { char *data = argv[x]; @@ -133,16 +135,15 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt while (*data == ' ') { data++; } - - + if ((arg = strchr(data, '='))) { *arg++ = '\0'; - + if (codec_settings) { if (!strcasecmp(data, "useinbandfec")) { codec_settings->useinbandfec = switch_true(arg); } - + if (!strcasecmp(data, "usedtx")) { codec_settings->usedtx = switch_true(arg); } @@ -150,20 +151,20 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!strcasecmp(data, "cbr")) { codec_settings->cbr = switch_true(arg); } - + if (!strcasecmp(data, "maxptime")) { codec_settings->maxptime = atoi(arg); } - + if (!strcasecmp(data, "minptime")) { codec_settings->minptime = atoi(arg); } - + if (!strcasecmp(data, "ptime")) { codec_settings->ptime = atoi(arg); codec_fmtp->microseconds_per_packet = codec_settings->ptime * 1000; } - + if (!strcasecmp(data, "samplerate")) { codec_settings->samplerate = atoi(arg); codec_fmtp->actual_samples_per_second = codec_settings->samplerate; @@ -177,14 +178,14 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt if (!strcasecmp(data, "sprop-stereo")) { codec_settings->sprop_stereo = atoi(arg); } - + if (!strcasecmp(data, "maxaveragebitrate")) { codec_settings->maxaveragebitrate = atoi(arg); - if ( codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 510000 ) { + if (codec_settings->maxaveragebitrate < 6000 || codec_settings->maxaveragebitrate > 510000) { codec_settings->maxaveragebitrate = 0; /* values outside the range between 6000 and 510000 SHOULD be ignored */ } } - + if (!strcasecmp(data, "maxplaybackrate")) { codec_settings->maxplaybackrate = atoi(arg); if (!switch_opus_acceptable_rate(codec_settings->maxplaybackrate)) { @@ -210,11 +211,11 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt static char *gen_fmtp(opus_codec_settings_t *settings, switch_memory_pool_t *pool) { char buf[256] = { 0 }; - + if (settings->useinbandfec) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "useinbandfec=1; "); } - + if (settings->usedtx) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "usedtx=1; "); } @@ -222,11 +223,11 @@ static char *gen_fmtp(opus_codec_settings_t *settings, switch_memory_pool_t *poo if (settings->cbr) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "cbr=1; "); } - + if (settings->maxaveragebitrate) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "maxaveragebitrate=%d; ", settings->maxaveragebitrate); } - + if (settings->maxplaybackrate) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "maxplaybackrate=%d; ", settings->maxplaybackrate); } @@ -238,7 +239,7 @@ static char *gen_fmtp(opus_codec_settings_t *settings, switch_memory_pool_t *poo if (settings->ptime) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "ptime=%d; ", settings->ptime); } - + if (settings->minptime) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "minptime=%d; ", settings->minptime); } @@ -246,12 +247,13 @@ static char *gen_fmtp(opus_codec_settings_t *settings, switch_memory_pool_t *poo if (settings->maxptime) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "maxptime=%d; ", settings->maxptime); } - + if (settings->samplerate) { snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "samplerate=%d; ", settings->samplerate); } if (settings->stereo) { + settings->sprop_stereo = settings->stereo; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "stereo=%d; ", settings->stereo); } @@ -262,9 +264,50 @@ static char *gen_fmtp(opus_codec_settings_t *settings, switch_memory_pool_t *poo if (end_of(buf) == ' ') { *(end_of_p(buf) - 1) = '\0'; } - + return switch_core_strdup(pool, buf); - + +} + +static switch_bool_t switch_opus_has_fec(const uint8_t* payload,int payload_length_bytes) +{ + int frames, payload_length_ms; + int n; + opus_int16 frame_sizes[48]; + const unsigned char *frame_data[48]; + + if (payload == NULL || payload_length_bytes <= 0){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "corrupted packet\n"); + return SWITCH_FALSE; + } + + if (payload[0] & 0x80){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FEC in CELT_ONLY mode ?!\n"); + return SWITCH_FALSE; + } + + payload_length_ms = opus_packet_get_samples_per_frame(payload, 48000) / 48; + if (10 > payload_length_ms) { + payload_length_ms = 10; + } + + frames = opus_packet_parse(payload, payload_length_bytes, NULL, frame_data, frame_sizes, NULL); + + if (frames < 0) { + return SWITCH_FALSE; + } + + if (frame_sizes[0] <= 1) { + return SWITCH_FALSE; + } + + for (n = 0; n <= (payload[0]&0x4);n++) { + if (frame_data[0][0] & (0x80 >> ((n + 1) * (frames + 1) - 1))) { + return SWITCH_TRUE; /*this works only for 20 ms frames now, it will return VAD for 40 ms or 60 ms*/ + } + } + + return SWITCH_FALSE; } static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text) @@ -299,15 +342,15 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text); } - if (opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)){ + if (opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)) { if (frame_data[0]) { /*check only 1st frame*/ has_fec = frame_data[0][0] & (0x80 >> 1); } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s]\n", - print_text, nb_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no" ); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s]\n", + print_text, nb_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no"); return SWITCH_STATUS_SUCCESS; } @@ -320,13 +363,12 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag switch_codec_fmtp_t codec_fmtp, codec_fmtp_only_remote = { 0 }; opus_codec_settings_t opus_codec_settings = { 0 }; opus_codec_settings_t opus_codec_settings_remote = { 0 }; - + if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) { return SWITCH_STATUS_FALSE; } - - context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000; + context->enc_frame_size = codec->implementation->actual_samples_per_second * (codec->implementation->microseconds_per_packet / 1000) / 1000; memset(&codec_fmtp, '\0', sizeof(struct switch_codec_fmtp)); codec_fmtp.private_info = &opus_codec_settings; @@ -339,17 +381,22 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag context->codec_settings = opus_codec_settings; /* Verify if the local or remote configuration are lowering maxaveragebitrate and/or maxplaybackrate */ - if ( opus_prefs.maxaveragebitrate && (opus_prefs.maxaveragebitrate < opus_codec_settings_remote.maxaveragebitrate || !opus_codec_settings_remote.maxaveragebitrate) ) { + if (opus_prefs.maxaveragebitrate && + (opus_prefs.maxaveragebitrate < opus_codec_settings_remote.maxaveragebitrate || !opus_codec_settings_remote.maxaveragebitrate)) { opus_codec_settings.maxaveragebitrate = opus_prefs.maxaveragebitrate; } else { opus_codec_settings.maxaveragebitrate = opus_codec_settings_remote.maxaveragebitrate; } - if ( opus_prefs.maxplaybackrate && (opus_prefs.maxplaybackrate < opus_codec_settings_remote.maxplaybackrate || !opus_codec_settings_remote.maxplaybackrate) ) { + + if (opus_prefs.maxplaybackrate && + (opus_prefs.maxplaybackrate < opus_codec_settings_remote.maxplaybackrate || !opus_codec_settings_remote.maxplaybackrate)) { opus_codec_settings.maxplaybackrate = opus_prefs.maxplaybackrate; } else { opus_codec_settings.maxplaybackrate=opus_codec_settings_remote.maxplaybackrate; } - if ( opus_prefs.sprop_maxcapturerate && (opus_prefs.sprop_maxcapturerate < opus_codec_settings_remote.sprop_maxcapturerate || !opus_codec_settings_remote.sprop_maxcapturerate) ) { + + if (opus_prefs.sprop_maxcapturerate && + (opus_prefs.sprop_maxcapturerate < opus_codec_settings_remote.sprop_maxcapturerate || !opus_codec_settings_remote.sprop_maxcapturerate)) { opus_codec_settings.sprop_maxcapturerate = opus_prefs.sprop_maxcapturerate; } else { opus_codec_settings.sprop_maxcapturerate = opus_codec_settings_remote.sprop_maxcapturerate; @@ -369,12 +416,12 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag int plpct = opus_prefs.plpct; int err; int enc_samplerate = opus_codec_settings.samplerate ? opus_codec_settings.samplerate : codec->implementation->actual_samples_per_second; - + if (opus_prefs.asymmetric_samplerates) { /* If an entity receives an fmtp: maxplaybackrate=R1,sprop-maxcapturerate=R2 and sends an fmtp with: * maxplaybackrate=R3,sprop-maxcapturerate=R4 * then it should start the encoder at sample rate: min(R1, R4) and the decoder at sample rate: min(R3, R2)*/ - if (codec_fmtp.private_info) { + if (codec_fmtp.private_info) { opus_codec_settings_t *settings = codec_fmtp_only_remote.private_info; if (opus_codec_settings.sprop_maxcapturerate || settings->maxplaybackrate) { enc_samplerate = opus_codec_settings.sprop_maxcapturerate; /*R4*/ @@ -392,15 +439,14 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag context->encoder_object = opus_encoder_create(enc_samplerate, codec->implementation->number_of_channels, codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err); - - if (err != OPUS_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err)); - return SWITCH_STATUS_GENERR; - } - + + if (err != OPUS_OK) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err)); + return SWITCH_STATUS_GENERR; + } /* Setting documented in "RTP Payload Format for Opus Speech and Audio Codec" draft-spittka-payload-rtp-opus-03 */ - if( opus_codec_settings.maxaveragebitrate ) { /* Remote codec settings found in SDP "fmtp", we accept to tune the Encoder */ + if (opus_codec_settings.maxaveragebitrate) { /* Remote codec settings found in SDP "fmtp", we accept to tune the Encoder */ opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder set bitrate based on maxaveragebitrate found in SDP [%dbps]\n", opus_codec_settings.maxaveragebitrate); } else { @@ -416,7 +462,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag } /* Another setting from "RTP Payload Format for Opus Speech and Audio Codec" */ - if ( opus_codec_settings.maxplaybackrate ) { + if (opus_codec_settings.maxplaybackrate) { if (opus_codec_settings.maxplaybackrate == 8000) { /* Audio Bandwidth: 0-4000Hz Sampling Rate: 8000Hz */ opus_encoder_ctl(context->encoder_object, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); } else if (opus_codec_settings.maxplaybackrate == 12000) { /* Audio Bandwidth: 0-6000Hz Sampling Rate: 12000Hz */ @@ -438,33 +484,34 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n"); opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0)); } + if (complexity) { opus_encoder_ctl(context->encoder_object, OPUS_SET_COMPLEXITY(complexity)); - } + } if (plpct) { opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct)); } - + if (opus_codec_settings.useinbandfec) { opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(opus_codec_settings.useinbandfec)); } - + if (opus_codec_settings.usedtx) { opus_encoder_ctl(context->encoder_object, OPUS_SET_DTX(opus_codec_settings.usedtx)); } } - + if (decoding) { int err; int dec_samplerate = codec->implementation->actual_samples_per_second; - + if (opus_prefs.asymmetric_samplerates) { if (codec_fmtp.private_info) { opus_codec_settings_t *settings = codec_fmtp_only_remote.private_info; - if (opus_codec_settings.maxplaybackrate || settings->sprop_maxcapturerate ) { + if (opus_codec_settings.maxplaybackrate || settings->sprop_maxcapturerate) { dec_samplerate = opus_codec_settings.maxplaybackrate; /* R3 */ - if (dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate){ + if (dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate) { dec_samplerate = settings->sprop_maxcapturerate; /* R2 */ context->dec_frame_size = dec_samplerate*(codec->implementation->microseconds_per_packet / 1000) / 1000; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate); @@ -476,30 +523,30 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag } context->decoder_object = opus_decoder_create(dec_samplerate, (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2), &err); - + switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC); - + if (err != OPUS_OK) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err)); - + if (context->encoder_object) { opus_encoder_destroy(context->encoder_object); context->encoder_object = NULL; } - + return SWITCH_STATUS_GENERR; } } - + codec->private_info = context; - + return SWITCH_STATUS_SUCCESS; } static switch_status_t switch_opus_destroy(switch_codec_t *codec) { struct opus_context *context = codec->private_info; - + if (context) { if (context->decoder_object) { opus_decoder_destroy(context->decoder_object); @@ -510,7 +557,7 @@ static switch_status_t switch_opus_destroy(switch_codec_t *codec) context->encoder_object = NULL; } } - + codec->private_info = NULL; return SWITCH_STATUS_SUCCESS; } @@ -529,10 +576,10 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec, if (!context) { return SWITCH_STATUS_FALSE; } - + bytes = opus_encode(context->encoder_object, (void *) decoded_data, context->enc_frame_size, (unsigned char *) encoded_data, len); - if (globals.debug) { + if (globals.debug || context->debug > 1) { int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); switch_opus_info(encoded_data, bytes, samplerate, "encode"); } @@ -542,11 +589,15 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec, return SWITCH_STATUS_SUCCESS; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n", opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data,(void *) encoded_data,(void *) context->encoder_object); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n", + opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data, + (void *) encoded_data,(void *) context->encoder_object); return SWITCH_STATUS_GENERR; } + static switch_status_t switch_opus_decode(switch_codec_t *codec, switch_codec_t *other_codec, void *encoded_data, @@ -568,36 +619,75 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec, frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); if (*flag & SFF_PLC) { + switch_core_session_t *session = codec->session; + switch_jb_t *jb = NULL; + int got_frame = 0; + plc = 1; + encoded_data = NULL; - opus_decoder_ctl(context->decoder_object, OPUS_GET_LAST_PACKET_DURATION(&frame_size)); - if (!frame_size) { - frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); + + if ((opus_prefs.use_jb_lookahead || context->use_jb_lookahead) && context->codec_settings.useinbandfec && session) { + if (opus_packet_get_bandwidth(codec->cur_frame->data) != OPUS_BANDWIDTH_FULLBAND && + codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) { + switch_frame_t frame = { 0 }; + uint8_t buf[SWITCH_RTP_MAX_BUF_LEN]; + frame.data = buf; + frame.buflen = sizeof(buf); + + if (switch_jb_peek_frame(jb, codec->cur_frame->timestamp, 0, 1, &frame)) { + got_frame = 1; + fec = 1; + encoded_data = frame.data; + encoded_data_len = frame.datalen; + if (globals.debug || context->debug) { + if (switch_opus_has_fec(frame.data, frame.datalen)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ[%d] encoded_data_len: %d\n", + codec->cur_frame->seq, encoded_data_len); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ[%d] encoded_data_len: %d\n", + codec->cur_frame->seq, encoded_data_len ); + } + } + } + } + } + + if (!got_frame) { + opus_decoder_ctl(context->decoder_object, OPUS_GET_LAST_PACKET_DURATION(&frame_size)); + + if (!frame_size) { + frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400)); + } } - if (context->codec_settings.useinbandfec) { - fec = 1; + if (globals.debug || context->debug) { + if (opus_prefs.use_jb_lookahead || context->use_jb_lookahead) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n"); + } } *flag &= ~SFF_PLC; } - if (globals.debug) { + if (globals.debug || context->debug > 1) { int samplerate = context->dec_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); - switch_opus_info((*flag & SFF_PLC) ? NULL : encoded_data, encoded_data_len, + switch_opus_info(encoded_data, encoded_data_len, samplerate ? samplerate : codec->implementation->actual_samples_per_second, "decode"); } samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, frame_size, fec); - + if (samples < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n", opus_strerror(samples), frame_size, plc ? "true" : "false"); return SWITCH_STATUS_GENERR; } - + *decoded_data_len = samples * 2 * (!context->codec_settings.sprop_stereo ? codec->implementation->number_of_channels : 2); - + return SWITCH_STATUS_SUCCESS; } @@ -612,60 +702,84 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec, int len = (int) *encoded_data_len; OpusRepacketizer *rp = opus_repacketizer_create(); int16_t *dec_ptr_buf = decoded_data; - /*work inside the available buffer to avoid other buffer allocations. *encoded_data_len will be SWITCH_RECOMMENDED_BUFFER_SIZE */ - unsigned char *enc_ptr_buf = (unsigned char *)encoded_data + (len / 2); + /* work inside the available buffer to avoid other buffer allocations. *encoded_data_len will be SWITCH_RECOMMENDED_BUFFER_SIZE */ + unsigned char *enc_ptr_buf = (unsigned char *)encoded_data + (len / 2); int nb_frames = codec->implementation->microseconds_per_packet / 20000 ; /* requested ptime: 20 ms * nb_frames */ - int i, bytes = 0; + int frame_size, i, bytes = 0, want_fec = 0, toggle_fec = 0; opus_int32 ret = 0; opus_int32 total_len = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; - + if (!context) { switch_goto_status(SWITCH_STATUS_FALSE, end); } + opus_encoder_ctl(context->encoder_object, OPUS_GET_INBAND_FEC(&want_fec)); + if (want_fec && context->codec_settings.useinbandfec) { + /* if FEC might be used , pack only 2 frames like: 80 ms = 2 x 40 ms , 120 ms = 2 x 60 ms */ + /* the first frame in the resulting payload must have FEC, the other must not ( avoid redundant FEC payload ) */ + nb_frames = 2; + if (codec->implementation->microseconds_per_packet / 1000 == 100) { /* 100 ms = 20 ms * 5 . because there is no 50 ms frame in Opus */ + nb_frames = 5; + } + toggle_fec = 1; + } + frame_size = (decoded_data_len / 2) / nb_frames; + if((frame_size * nb_frames) != context->enc_frame_size) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %d Encoder frame size: %d\n",decoded_data_len,nb_frames,context->enc_frame_size); + switch_goto_status(SWITCH_STATUS_GENERR, end); + } opus_repacketizer_init(rp); + dec_ptr_buf = (int16_t *)decoded_data; for (i = 0; i < nb_frames; i++) { - dec_ptr_buf = (int16_t *)decoded_data + i * (decoded_data_len / 2 / nb_frames); - bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, context->enc_frame_size / nb_frames, enc_ptr_buf, len); + bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, frame_size, enc_ptr_buf, len); + /* set inband FEC off for the next frame to be packed, the current frame may contain FEC */ + if (toggle_fec == 1) { + toggle_fec = 0; + opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(toggle_fec)); + } if (bytes < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \ - "Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n",opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len, - (void *) decoded_data,(void *) encoded_data,(void *) context->encoder_object,context->enc_frame_size); + "Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n", + opus_strerror(bytes), decoded_data_len, codec->implementation->number_of_channels, len, + (void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size); switch_goto_status(SWITCH_STATUS_GENERR, end); } - /* enc_ptr_buf : Opus API manual: "The application must ensure this pointer remains valid until the next call to opus_repacketizer_init() or opus_repacketizer_destroy()." */ ret = opus_repacketizer_cat(rp, enc_ptr_buf, bytes); if (ret != OPUS_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret)); switch_goto_status(SWITCH_STATUS_GENERR, end); - } - + } enc_ptr_buf += bytes; total_len += bytes; + dec_ptr_buf += frame_size ; } /* this will never happen, unless there is a huge and unsupported number of frames */ if (total_len + opus_repacketizer_get_nb_frames(rp) > len / 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Opus encoder: error while repacketizing: not enough buffer space\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n"); switch_goto_status(SWITCH_STATUS_GENERR, end); } - ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp)); - if (globals.debug) { + + if (globals.debug || context->debug) { int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); switch_opus_info(encoded_data, ret, samplerate, "encode_repacketize"); } + if (ret <= 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Opus encoder: error while repacketizing (out) : %s !\n",opus_strerror(ret)); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp)); switch_goto_status(SWITCH_STATUS_GENERR, end); } - + if (want_fec) { + opus_encoder_ctl(context->encoder_object, OPUS_SET_INBAND_FEC(want_fec)); /*restore FEC state*/ + } *encoded_data_len = (uint32_t) ret; end: if (rp) { opus_repacketizer_destroy(rp); } + return status; } @@ -674,17 +788,17 @@ static switch_status_t opus_load_config(switch_bool_t reload) char *cf = "opus.conf"; switch_xml_t cfg, xml = NULL, param, settings; switch_status_t status = SWITCH_STATUS_SUCCESS; - + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opening of %s failed\n", cf); return status; } - + if ((settings = switch_xml_child(cfg, "settings"))) { for (param = switch_xml_child(settings, "param"); param; param = param->next) { char *key = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); - + if (!strcasecmp(key, "use-vbr") && !zstr(val)) { opus_prefs.use_vbr = atoi(val); } else if (!strcasecmp(key, "use-dtx")) { @@ -695,11 +809,13 @@ static switch_status_t opus_load_config(switch_bool_t reload) opus_prefs.plpct = atoi(val); } else if (!strcasecmp(key, "asymmetric-sample-rates")) { opus_prefs.asymmetric_samplerates = atoi(val); + } else if (!strcasecmp(key, "use-jb-lookahead")) { + opus_prefs.use_jb_lookahead = switch_true(val); } else if (!strcasecmp(key, "keep-fec-enabled")) { opus_prefs.keep_fec = atoi(val); } else if (!strcasecmp(key, "maxaveragebitrate")) { opus_prefs.maxaveragebitrate = atoi(val); - if ( opus_prefs.maxaveragebitrate < 6000 || opus_prefs.maxaveragebitrate > 510000 ) { + if (opus_prefs.maxaveragebitrate < 6000 || opus_prefs.maxaveragebitrate > 510000) { opus_prefs.maxaveragebitrate = 0; /* values outside the range between 6000 and 510000 SHOULD be ignored */ } } else if (!strcasecmp(key, "maxplaybackrate")) { @@ -715,12 +831,12 @@ static switch_status_t opus_load_config(switch_bool_t reload) } } } - - if (xml) { - switch_xml_free(xml); - } - - return status; + + if (xml) { + switch_xml_free(xml); + } + + return status; } static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) @@ -728,23 +844,26 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) struct opus_context *context = codec->private_info; opus_int32 current_bitrate; opus_int32 current_loss; - uint32_t LBRR_threshold_bitrate,LBRR_rate_thres_bps,real_target_bitrate ; - opus_int32 a32,b32; + uint32_t LBRR_threshold_bitrate,LBRR_rate_thres_bps,real_target_bitrate ; + opus_int32 a32,b32; uint32_t fs = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000); float frame_rate =(float)(1000 / (codec->implementation->microseconds_per_packet / 1000)); uint32_t step = (codec->implementation->microseconds_per_packet / 1000) != 60 ? 8000 / (codec->implementation->microseconds_per_packet / 1000 ) : 134 ; opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(¤t_bitrate)); opus_encoder_ctl(context->encoder_object, OPUS_GET_PACKET_LOSS_PERC(¤t_loss)); - if ( current_loss == 0 ){ + + if (current_loss == 0) { opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_prefs.maxaveragebitrate)); + return SWITCH_STATUS_SUCCESS; } - if( fs == 8000 ) { + + if (fs == 8000) { LBRR_rate_thres_bps = 12000; /*LBRR_NB_MIN_RATE_BPS*/ - } else if( fs == 12000 ) { + } else if (fs == 12000) { LBRR_rate_thres_bps = 14000; /*LBRR_MB_MIN_RATE_BPS*/ - } else { + } else { LBRR_rate_thres_bps = 16000; /*LBRR_WB_MIN_RATE_BPS*/ } /*see opus-1.1/src/opus_encoder.c , opus_encode_native() */ @@ -753,25 +872,32 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec) a32 = LBRR_rate_thres_bps * (125 -(((current_loss) < (25)) ? (current_loss) : (25))); b32 = ((opus_int32)((0.01) * ((opus_int64)1 << (16)) + 0.5)); LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); - if ((!real_target_bitrate || !LBRR_threshold_bitrate)){ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Opus encoder: error while controlling FEC params\n"); + + if ((!real_target_bitrate || !LBRR_threshold_bitrate)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n"); + return SWITCH_STATUS_FALSE; } - /* Is there any FEC at the current bitrate and requested packet loss ? + /* Is there any FEC at the current bitrate and requested packet loss ? * If yes, then keep the current bitrate. If not, modify bitrate to keep FEC on. */ if (real_target_bitrate > LBRR_threshold_bitrate) { /*FEC is already enabled, do nothing*/ - if (globals.debug) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"Opus encoder: FEC is enabled\n"); + if (globals.debug || context->debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n"); + } return SWITCH_STATUS_SUCCESS; } else { while (real_target_bitrate <= LBRR_threshold_bitrate) { current_bitrate += step; real_target_bitrate = (uint32_t)(8 * (current_bitrate * context->enc_frame_size / ( fs * 8 ) - 1) * frame_rate); } + opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate)); - if (globals.debug) - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"Opus encoder: increased bitrate to [%d] to keep FEC enabled\n",current_bitrate); + + if (globals.debug || context->debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate); + } + return SWITCH_STATUS_SUCCESS; } } @@ -780,12 +906,46 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data) { struct opus_context *context = codec->private_info; switch(cmd) { + case SCC_CODEC_SPECIFIC: + { + const char *cmd = (const char *)cmd_data; + const char *arg = (const char *)cmd_arg; + switch_codec_control_type_t reply_type = SCCT_STRING; + const char *reply = "ERROR INVALID COMMAND"; + + if (!zstr(cmd)) { + if (!strcasecmp(cmd, "jb_lookahead")) { + if (!zstr(arg)) { + context->use_jb_lookahead = switch_true(arg); + } + reply = context->use_jb_lookahead ? "LOOKAHEAD ON" : "LOOKAHEAD OFF"; + } + } + + if (rtype) { + *rtype = reply_type; + + if (reply) { + *ret_data = (void *)reply; + } + } + + } + break; + case SCC_DEBUG: + { + int32_t level = *((uint32_t *) cmd_data); + context->debug = level; + } + break; case SCC_AUDIO_PACKET_LOSS: { uint32_t plpct = *((uint32_t *) cmd_data); @@ -798,10 +958,21 @@ static switch_status_t switch_opus_control(switch_codec_t *codec, calc = plpct % 10; plpct = plpct - calc + ( calc ? 10 : 0); + if (opus_prefs.plpct > 0 && plpct < opus_prefs.plpct) { + plpct = opus_prefs.plpct; + } + if (plpct != context->old_plpct) { opus_encoder_ctl(context->encoder_object, OPUS_SET_PACKET_LOSS_PERC(plpct)); - if (opus_prefs.keep_fec) + + if (opus_prefs.keep_fec) { switch_opus_keep_fec_enabled(codec); + } + + if (globals.debug || context->debug) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus Adjusting packet loss percent from %d%% to %d%%!\n", + context->old_plpct, plpct); + } } context->old_plpct = plpct; } @@ -845,37 +1016,39 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) int bits = 0; char *dft_fmtp = NULL; opus_codec_settings_t settings = { 0 }; - switch_status_t status = SWITCH_STATUS_SUCCESS; - + switch_status_t status = SWITCH_STATUS_SUCCESS; + if ((status = opus_load_config(SWITCH_FALSE)) != SWITCH_STATUS_SUCCESS) { return status; } - + /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); - + SWITCH_ADD_CODEC(codec_interface, "OPUS (STANDARD)"); SWITCH_ADD_API(commands_api_interface, "opus_debug", "Set OPUS Debug", mod_opus_debug, OPUS_DEBUG_SYNTAX); - + switch_console_set_complete("add opus_debug on"); switch_console_set_complete("add opus_debug off"); codec_interface->parse_fmtp = switch_opus_fmtp_parse; - + settings = default_codec_settings; - - if (opus_prefs.maxaveragebitrate){ - settings.maxaveragebitrate = opus_prefs.maxaveragebitrate; - } - if (opus_prefs.maxplaybackrate) { - settings.maxplaybackrate = opus_prefs.maxplaybackrate; - } + + if (opus_prefs.maxaveragebitrate) { + settings.maxaveragebitrate = opus_prefs.maxaveragebitrate; + } + + if (opus_prefs.maxplaybackrate) { + settings.maxplaybackrate = opus_prefs.maxplaybackrate; + } + if (opus_prefs.sprop_maxcapturerate) { settings.sprop_maxcapturerate = opus_prefs.sprop_maxcapturerate; } for (x = 0; x < 3; x++) { - + settings.ptime = mss / 1000; settings.maxptime = settings.ptime; settings.minptime = settings.ptime; @@ -902,49 +1075,48 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) switch_opus_destroy); /* deinitalize a codec handle using this implementation */ 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; - } - - + + samples = 480; bytes = 160; mss = 10000; rate = 8000; for (x = 0; x < 3; x++) { - settings.stereo = 0; + settings.stereo = 0; settings.ptime = mss / 1000; settings.maxptime = settings.ptime; settings.minptime = settings.ptime; settings.samplerate = rate; 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 */ @@ -983,7 +1155,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) 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; - if (x == 1){ /*20 ms * 3 = 60 ms */ + if (x == 1) { /*20 ms * 3 = 60 ms */ int nb_frames; settings.stereo = 0; dft_fmtp = gen_fmtp(&settings, pool); @@ -1028,25 +1200,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load) 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; - } - + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } - - /* For Emacs: * Local Variables: * mode:c diff --git a/src/mod/codecs/mod_silk/mod_silk.c b/src/mod/codecs/mod_silk/mod_silk.c index ba867cc3e9..8da1c541c7 100644 --- a/src/mod/codecs/mod_silk/mod_silk.c +++ b/src/mod/codecs/mod_silk/mod_silk.c @@ -62,7 +62,7 @@ struct silk_context { SKP_SILK_SDK_DecControlStruct decoder_object; void *enc_state; void *dec_state; - SKP_uint8 recbuff[STFU_DATALEN]; + SKP_uint8 recbuff[SWITCH_RTP_MAX_BUF_LEN]; SKP_int16 reclen; }; @@ -326,12 +326,8 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, SKP_int16 ret, len; int16_t *target = decoded_data; switch_core_session_t *session = codec->session; - stfu_instance_t *jb = NULL; - + switch_jb_t *jb = NULL; SKP_int lost_flag = (*flag & SFF_PLC); - stfu_frame_t *next_frame = NULL; - - int32_t found_frame; switch_bool_t did_lbrr = SWITCH_FALSE; int i; @@ -345,11 +341,14 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec, } if (jb && codec->cur_frame) { - for (i = 1; i <= MAX_LBRR_DELAY; i++) { - found_frame = stfu_n_peek_frame(jb, (uint32_t)codec->cur_frame->timestamp, codec->cur_frame->seq, (uint16_t)i, &next_frame); + switch_frame_t frame = { 0 }; + uint8_t buf[SWITCH_RTP_MAX_BUF_LEN]; + frame.data = buf; + frame.buflen = sizeof(buf); - if (found_frame) { - SKP_Silk_SDK_search_for_LBRR(next_frame->data, (const int)next_frame->dlen, i, (SKP_uint8*) &context->recbuff, &context->reclen); + for (i = 1; i <= MAX_LBRR_DELAY; i++) { + if (switch_jb_peek_frame(jb, codec->cur_frame->timestamp, 0, (uint16_t)i, &frame)) { + SKP_Silk_SDK_search_for_LBRR(frame.data, (const int)frame.datalen, i, (SKP_uint8*) &context->recbuff, &context->reclen); if (context->reclen) { encoded_data = &context->recbuff; diff --git a/src/mod/codecs/mod_vpx/mod_vpx.c b/src/mod/codecs/mod_vpx/mod_vpx.c index bb24544ba0..e1311b8f84 100644 --- a/src/mod/codecs/mod_vpx/mod_vpx.c +++ b/src/mod/codecs/mod_vpx/mod_vpx.c @@ -940,6 +940,8 @@ static switch_status_t switch_vpx_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data) { @@ -958,7 +960,7 @@ static switch_status_t switch_vpx_control(switch_codec_t *codec, } } break; - case SCC_VIDEO_REFRESH: + case SCC_VIDEO_GEN_KEYFRAME: context->need_key_frame = 1; break; case SCC_VIDEO_BANDWIDTH: diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 4bcd0c7d3e..99e83add97 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -1206,6 +1206,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load) { switch_application_interface_t *app_interface; + if (switch_event_reserve_subclass("loopback::bowout") != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", "loopback::bowout"); + return SWITCH_STATUS_TERM; + } + + memset(&globals, 0, sizeof(globals)); /* connect my internal structure to the blank pointer passed to me */ @@ -1223,6 +1229,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_loopback_shutdown) { + + switch_event_free_subclass("loopback::bowout"); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/endpoints/mod_rtc/mod_rtc.c b/src/mod/endpoints/mod_rtc/mod_rtc.c index 48d12706a5..4f964827c8 100644 --- a/src/mod/endpoints/mod_rtc/mod_rtc.c +++ b/src/mod/endpoints/mod_rtc/mod_rtc.c @@ -269,7 +269,7 @@ static switch_status_t rtc_receive_event(switch_core_session_t *session, switch_ return SWITCH_STATUS_SUCCESS; } -static stfu_instance_t *rtc_get_jb(switch_core_session_t *session, switch_media_type_t type) +static switch_jb_t *rtc_get_jb(switch_core_session_t *session, switch_media_type_t type) { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); diff --git a/src/mod/endpoints/mod_rtmp/mod_rtmp.c b/src/mod/endpoints/mod_rtmp/mod_rtmp.c index d4e0c218c9..9066148566 100644 --- a/src/mod/endpoints/mod_rtmp/mod_rtmp.c +++ b/src/mod/endpoints/mod_rtmp/mod_rtmp.c @@ -1979,6 +1979,46 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rtmp_load) switch_api_interface_t *api_interface; rtmp_globals.pool = pool; + if (switch_event_reserve_subclass(RTMP_EVENT_CONNECT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_CONNECT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_DISCONNECT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_DISCONNECT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_REGISTER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_UNREGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_UNREGISTER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_LOGIN) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_LOGIN); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_LOGOUT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_LOGOUT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_DETACH) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_DETACH); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(RTMP_EVENT_ATTACH) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", RTMP_EVENT_ATTACH); + return SWITCH_STATUS_TERM; + } + memset(&rtmp_globals, 0, sizeof(rtmp_globals)); switch_mutex_init(&rtmp_globals.mutex, SWITCH_MUTEX_NESTED, pool); @@ -2070,6 +2110,15 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rtmp_shutdown) { switch_hash_index_t *hi = NULL; + switch_event_free_subclass(RTMP_EVENT_CONNECT); + switch_event_free_subclass(RTMP_EVENT_DISCONNECT); + switch_event_free_subclass(RTMP_EVENT_REGISTER); + switch_event_free_subclass(RTMP_EVENT_UNREGISTER); + switch_event_free_subclass(RTMP_EVENT_LOGIN); + switch_event_free_subclass(RTMP_EVENT_LOGOUT); + switch_event_free_subclass(RTMP_EVENT_DETACH); + switch_event_free_subclass(RTMP_EVENT_ATTACH); + switch_mutex_lock(rtmp_globals.mutex); while ((hi = switch_core_hash_first_iter(rtmp_globals.profile_hash, hi))) { void *val; diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c index 597a3a6c9e..6fb88079d5 100644 --- a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c +++ b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_lib.c @@ -540,7 +540,7 @@ static inline unsigned int mul(unsigned int a, unsigned int b) static inline unsigned int muldiv32(unsigned int a, unsigned int b, unsigned int c, unsigned int *r) { - u_int64_t n = (u_int64_t) a * b; + uint64_t n = (u_int64_t) a * b; if (c == 0) { snd_BUG_ON(!n); *r = 0; @@ -1094,7 +1094,7 @@ EXPORT_SYMBOL(snd_pcm_hw_rule_add); * Apply the constraint of the given bitmap mask to a 32-bit mask parameter. */ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, - u_int32_t mask) + uint32_t mask) { struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; struct snd_mask *maskp = constrs_mask(constrs, var); @@ -1114,12 +1114,12 @@ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param * Apply the constraint of the given bitmap mask to a 64-bit mask parameter. */ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, - u_int64_t mask) + uint64_t mask) { struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints; struct snd_mask *maskp = constrs_mask(constrs, var); - maskp->bits[0] &= (u_int32_t)mask; - maskp->bits[1] &= (u_int32_t)(mask >> 32); + maskp->bits[0] &= (uint32_t)mask; + maskp->bits[1] &= (uint32_t)(mask >> 32); memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */ if (! maskp->bits[0] && ! maskp->bits[1]) return -EINVAL; diff --git a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c index fe9d42ed42..0b6a7fd20a 100644 --- a/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c +++ b/src/mod/endpoints/mod_skypopen/old-stuff/pcm_native.c @@ -369,16 +369,16 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime) static int calc_boundary(struct snd_pcm_runtime *runtime) { - u_int64_t boundary; + uint64_t boundary; - boundary = (u_int64_t)runtime->buffer_size * - (u_int64_t)runtime->period_size; + boundary = (uint64_t)runtime->buffer_size * + (uint64_t)runtime->period_size; #if BITS_PER_LONG < 64 /* try to find lowest common multiple for buffer and period */ if (boundary > LONG_MAX - runtime->buffer_size) { - u_int32_t remainder = -1; - u_int32_t divident = runtime->buffer_size; - u_int32_t divisor = runtime->period_size; + uint32_t remainder = -1; + uint32_t divident = runtime->buffer_size; + uint32_t divisor = runtime->period_size; while (remainder) { remainder = divident % divisor; if (remainder) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index b2f37b3815..d74688c70c 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -264,7 +264,7 @@ char *generate_pai_str(private_object_t *tech_pvt) return pai; } -static stfu_instance_t *sofia_get_jb(switch_core_session_t *session, switch_media_type_t type) +static switch_jb_t *sofia_get_jb(switch_core_session_t *session, switch_media_type_t type) { private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session); @@ -1450,12 +1450,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_3P_NOMEDIA: { - nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(msg->string_arg), TAG_END()); + char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX); + + nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(msg->string_arg), + TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); + + switch_safe_free(extra_headers); } break; case SWITCH_MESSAGE_INDICATE_3P_MEDIA: { - nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(""), TAG_END()); + char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX); + nua_invite(tech_pvt->nh, NUTAG_MEDIA_ENABLE(0), SIPTAG_PAYLOAD_STR(""), + TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); + + switch_safe_free(extra_headers); } break; @@ -1532,7 +1541,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_MESSAGE: { - char *ct = "text/plain"; + char ct[256] = "text/plain"; int ok = 0; if (!zstr(msg->string_array_arg[3]) && !strcmp(msg->string_array_arg[3], tech_pvt->caller_profile->uuid)) { @@ -1540,11 +1549,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; } - if (!zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { - ct = switch_core_session_sprintf(session, "%s/%s", msg->string_array_arg[0], msg->string_array_arg[1]); - ok = 1; - } - if (switch_stristr("send_message", tech_pvt->x_freeswitch_support_remote)) { ok = 1; } @@ -1556,6 +1560,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi if (ok) { const char *pl = NULL; + if (!zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { + switch_snprintf(ct, sizeof(ct), "%s/%s", msg->string_array_arg[0], msg->string_array_arg[1]); + } + if (!zstr(msg->string_array_arg[2])) { pl = msg->string_array_arg[2]; } @@ -1573,26 +1581,14 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi break; case SWITCH_MESSAGE_INDICATE_INFO: { - char *ct = "freeswitch/data"; + char ct[256] = "freeswitch/data"; int ok = 0; - if (!zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { - ct = switch_core_session_sprintf(session, "%s/%s", msg->string_array_arg[0], msg->string_array_arg[1]); - ok = 1; - } - if (switch_stristr("send_info", tech_pvt->x_freeswitch_support_remote)) { ok = 1; } - /* TODO: 1.4 remove this stanza */ - if (switch_true(switch_channel_get_variable(channel, "fs_send_unspported_info"))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "fs_send_unspported_info is deprecated in favor of correctly spelled fs_send_unsupported_info\n"); - ok = 1; - } - - if (switch_true(switch_channel_get_variable(channel, "fs_send_unsupported_info"))) { + if (switch_true(switch_channel_get_variable_dup(channel, "fs_send_unsupported_info", SWITCH_FALSE, -1))) { ok = 1; } @@ -1600,6 +1596,10 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi char *headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX); const char *pl = NULL; + if (!zstr(msg->string_array_arg[0]) && !zstr(msg->string_array_arg[1])) { + switch_snprintf(ct, sizeof(ct), "%s/%s", msg->string_array_arg[0], msg->string_array_arg[1]); + } + if (!zstr(msg->string_array_arg[2])) { pl = msg->string_array_arg[2]; } @@ -2489,6 +2489,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam "Agent: \t%s\n" "Status: \t%s(%s) EXP(%s) EXPSECS(%d)\n" "Ping-Status:\t%s\n" + "Ping-Time:\t%0.2f\n" "Host: \t%s\n" "IP: \t%s\n" "Port: \t%s\n" @@ -2497,7 +2498,8 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam "MWI-Account:\t%s@%s\n\n", switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_str_nil(argv[3]), switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[18]), - switch_str_nil(argv[11]), switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), + (float)atoll(switch_str_nil(argv[19]))/1000, switch_str_nil(argv[11]), switch_str_nil(argv[12]), + switch_str_nil(argv[13]), switch_str_nil(argv[14]), switch_str_nil(argv[15]), switch_str_nil(argv[16]), switch_str_nil(argv[17])); return 0; } @@ -2531,6 +2533,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum cb->stream->write_function(cb->stream, " %s(%s) exp(%s) expsecs(%d)\n", switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[18])); + cb->stream->write_function(cb->stream, " %0.2f\n", (float)atoll(switch_str_nil(argv[19]))/1000); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[11])); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[12])); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[13])); @@ -2761,19 +2764,19 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if (!sql && argv[2] && !strcasecmp(argv[2], "pres") && argv[3]) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host, ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host, ping_status,ping_time" " from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q'", profile->name); } if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) { @@ -2800,7 +2803,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra); switch_safe_free(dup); switch_safe_free(sqlextra); @@ -3068,21 +3071,21 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q'", profile->name); } if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) { @@ -3109,7 +3112,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time" " from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra); switch_safe_free(dup); switch_safe_free(sqlextra); @@ -5737,6 +5740,102 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) switch_application_interface_t *app_interface; struct in_addr in; + + if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_REFER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_REFER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_WATCHED_HEADER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_UNREGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_UNREGISTER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_PROFILE_START) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_START); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_REINVITE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REINVITE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_REPLACED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REPLACED); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_TRANSFEROR) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEROR); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_TRANSFEREE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEREE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_ERROR) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_ERROR); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_INTERCEPTED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_INTERCEPTED); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_STATE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_STATE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_SIP_USER_STATE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_SIP_USER_STATE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_DEL) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_DEL); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_EXPIRE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_EXPIRE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_REGISTER_ATTEMPT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_ATTEMPT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_REGISTER_FAILURE) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_FAILURE); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_PRE_REGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PRE_REGISTER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_ADD) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_ADD); + return SWITCH_STATUS_TERM; + } + memset(&mod_sofia_globals, 0, sizeof(mod_sofia_globals)); mod_sofia_globals.destroy_private.destroy_nh = 1; mod_sofia_globals.destroy_private.is_static = 1; @@ -5945,6 +6044,26 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) int i; switch_status_t st; + switch_event_free_subclass(MY_EVENT_NOTIFY_REFER); + switch_event_free_subclass(MY_EVENT_NOTIFY_WATCHED_HEADER); + switch_event_free_subclass(MY_EVENT_UNREGISTER); + switch_event_free_subclass(MY_EVENT_PROFILE_START); + switch_event_free_subclass(MY_EVENT_REINVITE); + switch_event_free_subclass(MY_EVENT_REPLACED); + switch_event_free_subclass(MY_EVENT_TRANSFEROR); + switch_event_free_subclass(MY_EVENT_TRANSFEREE); + switch_event_free_subclass(MY_EVENT_ERROR); + switch_event_free_subclass(MY_EVENT_INTERCEPTED); + switch_event_free_subclass(MY_EVENT_GATEWAY_STATE); + switch_event_free_subclass(MY_EVENT_SIP_USER_STATE); + switch_event_free_subclass(MY_EVENT_GATEWAY_DEL); + switch_event_free_subclass(MY_EVENT_EXPIRE); + switch_event_free_subclass(MY_EVENT_REGISTER_ATTEMPT); + switch_event_free_subclass(MY_EVENT_REGISTER_FAILURE); + switch_event_free_subclass(MY_EVENT_PRE_REGISTER); + switch_event_free_subclass(MY_EVENT_REGISTER); + switch_event_free_subclass(MY_EVENT_GATEWAY_ADD); + switch_console_del_complete_func("::sofia::list_profiles"); switch_console_set_complete("del sofia"); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 13fb98f639..9038b8cf3f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -181,6 +181,7 @@ struct sofia_private { int destroy_me; int is_call; int is_static; + switch_time_t ping_sent; }; #define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);} diff --git a/src/mod/endpoints/mod_sofia/rtp.c b/src/mod/endpoints/mod_sofia/rtp.c index b6a14974b0..ce42dc1875 100644 --- a/src/mod/endpoints/mod_sofia/rtp.c +++ b/src/mod/endpoints/mod_sofia/rtp.c @@ -591,10 +591,10 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s case SWITCH_MESSAGE_INDICATE_JITTER_BUFFER: { if (switch_rtp_ready(tech_pvt->rtp_session)) { - int len = 0, maxlen = 0, qlen = 0, maxqlen = 50, max_drift = 0; + int len = 0, maxlen = 0, qlen = 0, maxqlen = 50; if (msg->string_arg) { - char *p, *q; + char *p; const char *s; if (!strcasecmp(msg->string_arg, "pause")) { @@ -624,10 +624,6 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s if ((p = strchr(msg->string_arg, ':'))) { p++; maxlen = atol(p); - if ((q = strchr(p, ':'))) { - q++; - max_drift = abs(atoi(q)); - } } } @@ -643,10 +639,10 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s } if (switch_rtp_activate_jitter_buffer(tech_pvt->rtp_session, qlen, maxqlen, tech_pvt->read_codec.implementation->samples_per_packet, - tech_pvt->read_codec.implementation->samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) { + tech_pvt->read_codec.implementation->samples_per_second) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), - SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames) (%d max drift)\n", - len, qlen, maxqlen, max_drift); + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", + len, qlen, maxqlen); switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER); if (!switch_false(switch_channel_get_variable(tech_pvt->channel, "rtp_jitter_buffer_plc"))) { switch_channel_set_flag(tech_pvt->channel, CF_JITTERBUFFER_PLC); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 35038c4645..e979618a8a 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -5847,6 +5847,11 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu int sip_user_ping_max = profile->sip_user_ping_max; char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); + int ping_time = 0; + + if (sofia_private && sofia_private->ping_sent) { + ping_time = switch_time_now() - sofia_private->ping_sent; + } sip_user_status.status = ping_status; sip_user_status.status_len = sizeof(ping_status); @@ -5862,8 +5867,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu if (sip_user_status.count >= 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status); - sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count, - sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", + sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); switch_safe_free(sql); } @@ -5871,8 +5876,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu if (strcmp(sip_user_status.status, "Unreachable")) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); - sql = switch_mprintf("update sip_registrations set ping_status='Unreachable' where sip_user='%s' and sip_host='%s' and call_id='%q'", - sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sql = switch_mprintf("update sip_registrations set ping_status='Unreachable', ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", + ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); switch_safe_free(sql); sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user, @@ -5883,8 +5888,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); - sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'", - (long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sql = switch_mprintf("update sip_registrations set expires=%ld, ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", + (long) now, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); switch_safe_free(sql); } @@ -5895,8 +5900,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu if (sip_user_status.count <= sip_user_ping_max) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status); - sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count, - sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", + sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); switch_safe_free(sql); } @@ -5972,14 +5977,24 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_channel_set_variable_printf(channel, "sip_network_ip", "%s", network_ip); switch_channel_set_variable_printf(channel, "sip_network_port", "%d", network_port); - if ((caller_profile = switch_channel_get_caller_profile(channel))) { + if ((caller_profile = switch_channel_get_caller_profile(channel)) && !zstr(network_ip) && + (zstr(caller_profile->network_addr) || strcmp(caller_profile->network_addr, network_ip))) { caller_profile->network_addr = switch_core_strdup(caller_profile->pool, network_ip); } + if (tech_pvt->mparams.last_sdp_response) { + tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response; + } tech_pvt->mparams.last_sdp_response = NULL; + if (sip->sip_payload && sip->sip_payload->pl_data) { switch_core_media_set_sdp_codec_string(session, sip->sip_payload->pl_data, SDP_TYPE_RESPONSE); - tech_pvt->mparams.last_sdp_response = switch_core_session_strdup(session, sip->sip_payload->pl_data); + + if (!zstr(tech_pvt->mparams.prev_sdp_response) && !strcmp(tech_pvt->mparams.prev_sdp_response, sip->sip_payload->pl_data)) { + tech_pvt->mparams.last_sdp_response = tech_pvt->mparams.prev_sdp_response; + } else { + tech_pvt->mparams.last_sdp_response = switch_core_session_strdup(session, sip->sip_payload->pl_data); + } } if (status > 299 && switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_REQ)) { @@ -6657,6 +6672,15 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } } + + if (tech_pvt->mparams.last_sdp_str) { + tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str; + } + + if (tech_pvt->mparams.last_sdp_response) { + tech_pvt->mparams.prev_sdp_response = tech_pvt->mparams.last_sdp_response; + } + tech_pvt->mparams.last_sdp_str = NULL; tech_pvt->mparams.last_sdp_response = NULL; @@ -7510,6 +7534,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, sofia_clear_flag(tech_pvt, TFLAG_NEW_SDP); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); + if (tech_pvt->mparams.num_codecs) { match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE); } @@ -9089,10 +9114,18 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session, } if (channel) { + 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 (sip->sip_payload && 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); + 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; + } } switch_channel_execute_on(channel, "execute_on_sip_reinvite"); } @@ -9505,7 +9538,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia switch_channel_set_variable(channel, hp->name, hp->value); } - ruser = switch_event_get_header(v_event, "username"); + ruser = switch_event_get_header(v_event, "user_name"); rdomain = switch_event_get_header(v_event, "domain_name"); switch_channel_set_variable(channel, "requested_user_name", ruser); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index ec25e3645d..7dcdfcda79 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -636,7 +636,7 @@ void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *s sip_unknown_t *un; char name[512] = ""; switch_channel_t *channel = switch_core_session_get_channel(session); - char *pstr; + char pstr[32]; if (!sip || !channel) { @@ -652,7 +652,7 @@ void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *s } } - pstr = switch_core_session_sprintf(session, "execute_on_%sprefix", prefix); + switch_snprintf(pstr, sizeof(pstr), "execute_on_%sprefix", prefix); switch_channel_execute_on(channel, pstr); switch_channel_api_on(channel, pstr); @@ -2024,6 +2024,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) " status VARCHAR(255),\n" " ping_status VARCHAR(255),\n" " ping_count INTEGER,\n" + " ping_time BIGINT,\n" + " force_ping INTEGER,\n" " rpid VARCHAR(255),\n" " expires BIGINT,\n" " ping_expires INTEGER not null default 0,\n" @@ -2241,6 +2243,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) switch_cache_db_test_reactive(dbh, "select ping_count from sip_registrations", NULL, "alter table sip_registrations add column ping_count INTEGER default 0"); switch_cache_db_test_reactive(dbh, "select ping_status from sip_registrations", NULL, "alter table sip_registrations add column ping_status VARCHAR(255) default 'Reachable'"); switch_cache_db_test_reactive(dbh, "select ping_expires from sip_registrations", NULL, "alter table sip_registrations add column ping_expires INTEGER not null default 0"); + switch_cache_db_test_reactive(dbh, "select ping_time from sip_registrations", NULL, "alter table sip_registrations add column ping_time BIGINT not null default 0"); + switch_cache_db_test_reactive(dbh, "select force_ping from sip_registrations", NULL, "alter table sip_registrations add column force_ping INTEGER not null default 0"); test2 = switch_mprintf("%s;%s", test_sql, test_sql); diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index d6d7b87dfa..99dcf49349 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -599,6 +599,7 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames char to[512] = "", call_id[512] = ""; sofia_destination_t *dst = NULL; switch_uuid_t uuid; + sofia_private_t *pvt; switch_snprintf(to, sizeof(to), "sip:%s@%s", argv[1], argv[2]); @@ -613,7 +614,15 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url), SIPTAG_CALL_ID_STR(call_id), TAG_END()); - nua_handle_bind(nh, &mod_sofia_globals.destroy_private); + + pvt = malloc(sizeof(*pvt)); + switch_assert(pvt); + memset(pvt, 0, sizeof(*pvt)); + pvt->destroy_nh = 1; + pvt->destroy_me = 1; + pvt->ping_sent = switch_time_now(); + nua_handle_bind(nh, pvt); + nua_options(nh, NTATAG_SIP_T2(5000), NTATAG_SIP_T4(10000), @@ -869,64 +878,70 @@ void sofia_reg_check_ping_expire(sofia_profile_t *profile, time_t now, int inter char *sql; int mean = interval / 2; long next, irand; + char buf[32] = ""; + int count; if (now) { if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid," - "expires,user_agent,server_user,server_host,profile_name" - " from sip_registrations where hostname='%s' and " - "profile_name='%s' and orig_hostname='%s' and " - "ping_expires > 0 and ping_expires <= %ld", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); + "expires,user_agent,server_user,server_host,profile_name " + "from sip_registrations where hostname='%s' and " + "profile_name='%s' and orig_hostname='%s' and " + "ping_expires > 0 and ping_expires <= %ld", + mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile); switch_safe_free(sql); } else if (sofia_test_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)) { - sql = switch_mprintf( " select call_id,sip_user,sip_host,contact,status,rpid, " - " expires,user_agent,server_user,server_host,profile_name " - " from sip_registrations where status like '%%UDP-NAT%%' " - " and hostname='%s' and profile_name='%s' and ping_expires > 0 and ping_expires <= %ld ", - mod_sofia_globals.hostname, profile->name, (long) now); + sql = switch_mprintf(" select call_id,sip_user,sip_host,contact,status,rpid, " + " expires,user_agent,server_user,server_host,profile_name " + " from sip_registrations where (status like '%%UDP-NAT%%' or force_ping=1)" + " and hostname='%s' and profile_name='%s' and ping_expires > 0 and ping_expires <= %ld ", + mod_sofia_globals.hostname, profile->name, (long) now); sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile); switch_safe_free(sql); } else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid," - "expires,user_agent,server_user,server_host,profile_name" - " from sip_registrations where (status like '%%NAT%%' " - "or contact like '%%fs_nat=yes%%') and hostname='%s' " - "and profile_name='%s' and orig_hostname='%s' and " - "ping_expires > 0 and ping_expires <= %ld", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); + "expires,user_agent,server_user,server_host,profile_name " + "from sip_registrations where (status like '%%NAT%%' " + "or contact like '%%fs_nat=yes%%' or force_ping=1) and hostname='%s' " + "and profile_name='%s' and orig_hostname='%s' and " + "ping_expires > 0 and ping_expires <= %ld", + mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); + sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile); + switch_safe_free(sql); + } else { + sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid," + "expires,user_agent,server_user,server_host,profile_name " + "from sip_registrations where force_ping=1 and hostname='%s' " + "and profile_name='%s' and orig_hostname='%s' and " + "ping_expires > 0 and ping_expires <= %ld", + mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); + sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile); switch_safe_free(sql); } - if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING) || - sofia_test_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING) || - sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) { - char buf[32] = ""; - int count; + sql = switch_mprintf("select count(*) from sip_registrations where hostname='%q' and profile_name='%q' and ping_expires <= %ld", + mod_sofia_globals.hostname, profile->name, (long) now); - sql = switch_mprintf("select count(*) from sip_registrations where hostname='%q' and profile_name='%q' and ping_expires <= %ld", - mod_sofia_globals.hostname, profile->name, (long) now); + sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf)); + switch_safe_free(sql); + count = atoi(buf); - sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf)); - switch_safe_free(sql); - count = atoi(buf); + /* only update if needed */ + if (count) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Updating ping expires for profile %s\n", profile->name); + irand = mean + sofia_reg_uniform_distribution(interval); + next = (long) now + irand; - /* only update if needed */ - if (count) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Updating ping expires for profile %s\n", profile->name); - irand = mean + sofia_reg_uniform_distribution(interval); - next = (long) now + irand; - - sql = switch_mprintf("update sip_registrations set ping_expires = %ld where hostname='%q' and profile_name='%q' and ping_expires <= %ld ", - next, mod_sofia_globals.hostname, profile->name, (long) now); - sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); - } + sql = switch_mprintf("update sip_registrations set ping_expires = %ld where hostname='%q' and profile_name='%q' and ping_expires <= %ld ", + next, mod_sofia_globals.hostname, profile->name, (long) now); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); } } - } @@ -1253,6 +1268,7 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu const char *pres_on_reg = NULL; int send_pres = 0; int send_message_query = 0; + int force_ping = 0; int is_tls = 0, is_tcp = 0, is_ws = 0, is_wss = 0; char expbuf[35] = ""; time_t reg_time = switch_epoch_time_now(NULL); @@ -1797,6 +1813,15 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu } } + /* per-account enable options ping on register */ + if (v_event && *v_event && (var = switch_event_get_header(*v_event, "force_ping"))) { + if (switch_true(var)) { + force_ping = 1; + } else { + force_ping = 0; + } + } + if (regtype != REG_REGISTER) { switch_goto_int(r, 0, end); } @@ -1903,22 +1928,22 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu sql = switch_mprintf("insert into sip_registrations " "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires," "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm," - "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count) " - "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)", + "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count, force_ping) " + "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d, %d)", call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "", contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + profile->sip_expires_late_margin, agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, - mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0); + mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0, force_ping); } else { sql = switch_mprintf("update sip_registrations set call_id='%q'," "sub_host='%q', network_ip='%q',network_port='%q'," "presence_hosts='%q', server_host='%q', orig_server_host='%q'," "hostname='%q', orig_hostname='%q'," - "expires = %ld where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'", + "expires = %ld, force_ping=%d where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'", call_id, sub_host, network_ip, network_port_c, profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4, mod_sofia_globals.hostname, mod_sofia_globals.hostname, - (long) reg_time + (long) exptime + profile->sip_expires_late_margin, + (long) reg_time + (long) exptime + profile->sip_expires_late_margin, force_ping, to_user, username, reg_host, contact_str); } diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index 7d0d003103..69ef7ac767 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -1171,7 +1171,7 @@ static void tech_reattach(verto_pvt_t *tech_pvt, jsock_t *jsock) switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); switch_channel_set_flag(tech_pvt->channel, CF_RECOVERING); - switch_core_media_gen_local_sdp(tech_pvt->session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0); + switch_core_media_gen_local_sdp(tech_pvt->session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0); switch_channel_clear_flag(tech_pvt->channel, CF_REINVITE); switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING); switch_core_session_request_video_refresh(tech_pvt->session); @@ -2036,6 +2036,13 @@ static void untrack_pvt(verto_pvt_t *tech_pvt) switch_thread_rwlock_unlock(globals.tech_rwlock); } +switch_endpoint_interface_t *verto_endpoint_interface = NULL; + +static switch_status_t verto_on_destroy(switch_core_session_t *session) +{ + UNPROTECT_INTERFACE(verto_endpoint_interface); + return SWITCH_STATUS_SUCCESS; +} static switch_status_t verto_on_hangup(switch_core_session_t *session) { @@ -2244,7 +2251,7 @@ static switch_state_handler_table_t verto_state_handlers = { /*.on_reset */ NULL, /*.on_park */ NULL, /*.on_reporting */ NULL, - /*.on_destroy */ NULL, + /*.on_destroy */ verto_on_destroy, SSH_FLAG_STICKY }; @@ -2478,11 +2485,13 @@ static int verto_recover_callback(switch_core_session_t *session) const char *profile_name = NULL, *jsock_uuid_str = NULL; switch_channel_t *channel = switch_core_session_get_channel(session); + PROTECT_INTERFACE(verto_endpoint_interface); profile_name = switch_channel_get_variable(channel, "verto_profile_name"); jsock_uuid_str = switch_channel_get_variable(channel, "jsock_uuid_str"); if (!(profile_name && jsock_uuid_str && (profile = find_profile(profile_name)))) { + UNPROTECT_INTERFACE(verto_endpoint_interface); return 0; } @@ -3094,6 +3103,7 @@ static switch_bool_t verto__attach_func(const char *method, cJSON *params, jsock switch_core_media_clear_ice(tech_pvt->session); switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); + switch_channel_set_flag(tech_pvt->channel, CF_RECOVERING); //switch_channel_audio_sync(tech_pvt->channel); //switch_channel_set_flag(tech_pvt->channel, CF_VIDEO_BREAK); @@ -3296,6 +3306,8 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock } switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_uuid", call_id); + + PROTECT_INTERFACE(verto_endpoint_interface); if ((reason = switch_core_session_outgoing_channel(NULL, var_event, "rtc", NULL, &session, NULL, SOF_NONE, &cancel_cause)) != SWITCH_CAUSE_SUCCESS) { cJSON_AddItemToObject(obj, "message", cJSON_CreateString("Cannot create channel")); @@ -3455,6 +3467,8 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock return SWITCH_TRUE; } + UNPROTECT_INTERFACE(verto_endpoint_interface); + if (session) { switch_core_session_destroy(&session); } @@ -4847,7 +4861,7 @@ static void run_profiles(void) //// ENDPOINT -switch_endpoint_interface_t *verto_endpoint_interface; + static switch_call_cause_t verto_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, @@ -4934,6 +4948,8 @@ static switch_call_cause_t verto_outgoing_channel(switch_core_session_t *session switch_call_cause_t cause = SWITCH_CAUSE_CHANNEL_UNACCEPTABLE; char *dest = NULL; + PROTECT_INTERFACE(verto_endpoint_interface); + if (!zstr(outbound_profile->destination_number)) { dest = strdup(outbound_profile->destination_number); } @@ -5040,6 +5056,10 @@ static switch_call_cause_t verto_outgoing_channel(switch_core_session_t *session end: + if (cause != SWITCH_CAUSE_SUCCESS) { + UNPROTECT_INTERFACE(verto_endpoint_interface); + } + switch_safe_free(dest); return cause; @@ -5604,6 +5624,22 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_verto_load) switch_cache_db_handle_t *dbh; //switch_application_interface_t *app_interface = NULL; + + if (switch_event_reserve_subclass(MY_EVENT_LOGIN) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_LOGIN); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_CLIENT_DISCONNECT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_CLIENT_DISCONNECT); + return SWITCH_STATUS_TERM; + } + + if (switch_event_reserve_subclass(MY_EVENT_CLIENT_CONNECT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_CLIENT_CONNECT); + return SWITCH_STATUS_TERM; + } + memset(&globals, 0, sizeof(globals)); globals.pool = pool; #ifndef WIN32 @@ -5694,6 +5730,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_verto_load) Macro expands to: switch_status_t mod_verto_shutdown() */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_verto_shutdown) { + + switch_event_free_subclass(MY_EVENT_LOGIN); + switch_event_free_subclass(MY_EVENT_CLIENT_DISCONNECT); + switch_event_free_subclass(MY_EVENT_CLIENT_CONNECT); + json_cleanup(); switch_core_hash_destroy(&json_GLOBALS.store_hash); diff --git a/src/mod/event_handlers/mod_erlang_event/handle_msg.c b/src/mod/event_handlers/mod_erlang_event/handle_msg.c index f161f94e3c..5dbcd202c1 100644 --- a/src/mod/event_handlers/mod_erlang_event/handle_msg.c +++ b/src/mod/event_handlers/mod_erlang_event/handle_msg.c @@ -1224,7 +1224,7 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg, for (iter = switch_core_hash_first(listener->sessions); iter; iter = switch_core_hash_next(&iter)) { switch_core_hash_this(iter, &key, NULL, &val); se = (session_elem_t*)val; - if (se->spawn_reply && !strncmp(se->spawn_reply->hash, hash, 100)) { + if (switch_test_flag(se, LFLAG_WAITING_FOR_PID) && se->spawn_reply && !strncmp(se->spawn_reply->hash, hash, 100)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found matching session for %s : %s\n", hash, se->uuid_str); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index ce04dbcede..f3e8e7cd87 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -1582,7 +1582,6 @@ session_elem_t *attach_call_to_spawned_process(listener_t *listener, char *modul session_element->process.type = ERLANG_PID; memcpy(&session_element->process.pid, p->pid, sizeof(erlang_pid)); - session_element->spawn_reply = NULL; switch_clear_flag_locked(session_element, LFLAG_WAITING_FOR_PID); 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 8d1b1d5567..2bce7703f1 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 @@ -1650,6 +1650,35 @@ static switch_bool_t auth_api_command(listener_t *listener, const char *api_cmd, } +static void set_all_custom(listener_t *listener) +{ + switch_console_callback_match_t *events = NULL; + switch_console_callback_match_node_t *m; + + if (switch_event_get_custom_events(&events) == SWITCH_STATUS_SUCCESS) { + for (m = events->head; m; m = m->next) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "ADDING CUSTOM EVENT: %s\n", m->val); + switch_core_hash_insert(listener->event_hash, m->val, MARKER); + } + + switch_console_free_matches(&events); + } +} + +static void set_allowed_custom(listener_t *listener) +{ + switch_hash_index_t *hi = NULL; + const void *var; + void *val; + + switch_assert(listener->allowed_event_hash); + + for (hi = switch_core_hash_first(listener->allowed_event_hash); hi; hi = switch_core_hash_next(&hi)) { + switch_core_hash_this(hi, &var, NULL, &val); + switch_core_hash_insert(listener->event_hash, (char *)var, MARKER); + } +} + static switch_status_t parse_command(listener_t *listener, switch_event_t **event, char *reply, uint32_t reply_len) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -2450,6 +2479,13 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even for (x = 0; x < SWITCH_EVENT_ALL; x++) { listener->event_list[x] = 1; } + + if (!listener->allowed_event_hash) { + set_all_custom(listener); + } else { + set_allowed_custom(listener); + } + } if (type <= SWITCH_EVENT_ALL) { listener->event_list[type] = 1; @@ -2481,7 +2517,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even uint8_t custom = 0; strip_cr(cmd); - cur = cmd + 5; + cur = cmd + 8; if (cur && (cur = strchr(cur, ' '))) { for (cur++; cur; count++) { diff --git a/src/mod/event_handlers/mod_rayo/mod_rayo.c b/src/mod/event_handlers/mod_rayo/mod_rayo.c index 4a008e9b84..11828ce328 100644 --- a/src/mod/event_handlers/mod_rayo/mod_rayo.c +++ b/src/mod/event_handlers/mod_rayo/mod_rayo.c @@ -5158,6 +5158,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load) switch_api_interface_t *api_interface; switch_application_interface_t *app_interface; + + if (switch_event_reserve_subclass("rayo::cpa") != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", "rayo::cpa"); + return SWITCH_STATUS_TERM; + } + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading module\n"); @@ -5266,8 +5273,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_rayo_load) * Shutdown module. Notifies threads to stop. */ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_rayo_shutdown) -{ - switch_status_t result = do_shutdown(); +{ + switch_status_t result; + + switch_event_free_subclass("rayo::cpa"); + result = do_shutdown(); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Module shutdown\n"); return result; } diff --git a/src/mod/event_handlers/mod_rayo/xmpp_streams.c b/src/mod/event_handlers/mod_rayo/xmpp_streams.c index 7fe27e22fb..23a7387db6 100644 --- a/src/mod/event_handlers/mod_rayo/xmpp_streams.c +++ b/src/mod/event_handlers/mod_rayo/xmpp_streams.c @@ -1123,7 +1123,7 @@ static void xmpp_stream_destroy(struct xmpp_stream *stream) /* remove from available streams */ switch_mutex_lock(context->streams_mutex); - if (stream->jid && !stream->incoming) { + if (stream->jid) { switch_core_hash_delete(context->routes, stream->jid); } if (stream->id) { diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 65f8e2dfa4..31f7a0ed92 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -11885,11 +11885,11 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_jb(void * jarg1, in void * jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; switch_media_type_t arg2 ; - stfu_instance_t *result = 0 ; + switch_jb_t *result = 0 ; arg1 = (switch_core_session_t *)jarg1; arg2 = (switch_media_type_t)jarg2; - result = (stfu_instance_t *)switch_core_session_get_jb(arg1,arg2); + result = (switch_jb_t *)switch_core_session_get_jb(arg1,arg2); jresult = (void *)result; return jresult; } @@ -13518,23 +13518,27 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_encode_video(void * jarg1, v } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_control(void * jarg1, int jarg2, int jarg3, void * jarg4, void * jarg5, void * jarg6) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_codec_control(void * jarg1, int jarg2, int jarg3, void * jarg4, int jarg5, void * jarg6, void * jarg7, void * jarg8) { int jresult ; switch_codec_t *arg1 = (switch_codec_t *) 0 ; switch_codec_control_command_t arg2 ; switch_codec_control_type_t arg3 ; void *arg4 = (void *) 0 ; - switch_codec_control_type_t *arg5 = (switch_codec_control_type_t *) 0 ; - void **arg6 = (void **) 0 ; + switch_codec_control_type_t arg5 ; + void *arg6 = (void *) 0 ; + switch_codec_control_type_t *arg7 = (switch_codec_control_type_t *) 0 ; + void **arg8 = (void **) 0 ; switch_status_t result; arg1 = (switch_codec_t *)jarg1; arg2 = (switch_codec_control_command_t)jarg2; arg3 = (switch_codec_control_type_t)jarg3; arg4 = (void *)jarg4; - arg5 = (switch_codec_control_type_t *)jarg5; - arg6 = (void **)jarg6; - result = (switch_status_t)switch_core_codec_control(arg1,arg2,arg3,arg4,arg5,arg6); + arg5 = (switch_codec_control_type_t)jarg5; + arg6 = (void *)jarg6; + arg7 = (switch_codec_control_type_t *)jarg7; + arg8 = (void **)jarg8; + result = (switch_status_t)switch_core_codec_control(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8); jresult = result; return jresult; } @@ -25139,6 +25143,28 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_mm_t_vbuf_get(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_mm_t_vencspd_set(void * jarg1, int jarg2) { + switch_mm_s *arg1 = (switch_mm_s *) 0 ; + switch_video_encode_speed_t arg2 ; + + arg1 = (switch_mm_s *)jarg1; + arg2 = (switch_video_encode_speed_t)jarg2; + if (arg1) (arg1)->vencspd = arg2; +} + + +SWIGEXPORT int SWIGSTDCALL CSharp_switch_mm_t_vencspd_get(void * jarg1) { + int jresult ; + switch_mm_s *arg1 = (switch_mm_s *) 0 ; + switch_video_encode_speed_t result; + + arg1 = (switch_mm_s *)jarg1; + result = (switch_video_encode_speed_t) ((arg1)->vencspd); + jresult = result; + return jresult; +} + + SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_mm_t() { void * jresult ; switch_mm_s *result = 0 ; @@ -37404,6 +37430,18 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_parse_all_signal_data(void * jarg1) } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_parse_next_signal_data(void * jarg1) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + result = (switch_status_t)switch_ivr_parse_next_signal_data(arg1); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_process_indications(void * jarg1, void * jarg2) { int jresult ; switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; @@ -38362,6 +38400,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_media(char * jarg1, unsigned long j } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_3p_media(char * jarg1, unsigned long jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_media_flag_t arg2 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_media_flag_t)jarg2; + result = (switch_status_t)switch_ivr_3p_media((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_nomedia(char * jarg1, unsigned long jarg2) { int jresult ; char *arg1 = (char *) 0 ; @@ -38376,6 +38428,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_nomedia(char * jarg1, unsigned long } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_3p_nomedia(char * jarg1, unsigned long jarg2) { + int jresult ; + char *arg1 = (char *) 0 ; + switch_media_flag_t arg2 ; + switch_status_t result; + + arg1 = (char *)jarg1; + arg2 = (switch_media_flag_t)jarg2; + result = (switch_status_t)switch_ivr_3p_nomedia((char const *)arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_ivr_hold_uuid(char * jarg1, char * jarg2, int jarg3) { int jresult ; char *arg1 = (char *) 0 ; @@ -40930,40 +40996,49 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_media_timer(void * jarg1) { } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_video_buffer_size(void * jarg1, unsigned long jarg2) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_video_buffer_size(void * jarg1, unsigned long jarg2, unsigned long jarg3) { int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; uint32_t arg2 ; + uint32_t arg3 ; switch_status_t result; arg1 = (switch_rtp_t *)jarg1; arg2 = (uint32_t)jarg2; - result = (switch_status_t)switch_rtp_set_video_buffer_size(arg1,arg2); + arg3 = (uint32_t)jarg3; + result = (switch_status_t)switch_rtp_set_video_buffer_size(arg1,arg2,arg3); jresult = result; return jresult; } -SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_rtp_get_video_buffer_size(void * jarg1) { - unsigned long jresult ; +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_get_video_buffer_size(void * jarg1, void * jarg2, void * jarg3, void * jarg4, void * jarg5) { + int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; - uint32_t result; + uint32_t *arg2 = (uint32_t *) 0 ; + uint32_t *arg3 = (uint32_t *) 0 ; + uint32_t *arg4 = (uint32_t *) 0 ; + uint32_t *arg5 = (uint32_t *) 0 ; + switch_status_t result; arg1 = (switch_rtp_t *)jarg1; - result = (uint32_t)switch_rtp_get_video_buffer_size(arg1); - jresult = (unsigned long)result; + arg2 = (uint32_t *)jarg2; + arg3 = (uint32_t *)jarg3; + arg4 = (uint32_t *)jarg4; + arg5 = (uint32_t *)jarg5; + result = (switch_status_t)switch_rtp_get_video_buffer_size(arg1,arg2,arg3,arg4,arg5); + jresult = result; return jresult; } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5, unsigned long jarg6) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2, unsigned long jarg3, unsigned long jarg4, unsigned long jarg5) { int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; uint32_t arg2 ; uint32_t arg3 ; uint32_t arg4 ; uint32_t arg5 ; - uint32_t arg6 ; switch_status_t result; arg1 = (switch_rtp_t *)jarg1; @@ -40971,8 +41046,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1 arg3 = (uint32_t)jarg3; arg4 = (uint32_t)jarg4; arg5 = (uint32_t)jarg5; - arg6 = (uint32_t)jarg6; - result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2,arg3,arg4,arg5,arg6); + result = (switch_status_t)switch_rtp_activate_jitter_buffer(arg1,arg2,arg3,arg4,arg5); jresult = result; return jresult; } @@ -41021,10 +41095,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_pause_jitter_buffer(void * jarg1, i SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_get_jitter_buffer(void * jarg1) { void * jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; - stfu_instance_t *result = 0 ; + switch_jb_t *result = 0 ; arg1 = (switch_rtp_t *)jarg1; - result = (stfu_instance_t *)switch_rtp_get_jitter_buffer(arg1); + result = (switch_jb_t *)switch_rtp_get_jitter_buffer(arg1); jresult = (void *)result; return jresult; } diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 7d44006c65..f94de19823 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1723,9 +1723,9 @@ public class freeswitch { return ret; } - public static SWIGTYPE_p_stfu_instance_t switch_core_session_get_jb(SWIGTYPE_p_switch_core_session session, switch_media_type_t type) { + public static SWIGTYPE_p_switch_jb_s switch_core_session_get_jb(SWIGTYPE_p_switch_core_session session, switch_media_type_t type) { IntPtr cPtr = freeswitchPINVOKE.switch_core_session_get_jb(SWIGTYPE_p_switch_core_session.getCPtr(session), (int)type); - SWIGTYPE_p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_stfu_instance_t(cPtr, false); + SWIGTYPE_p_switch_jb_s ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_jb_s(cPtr, false); return ret; } @@ -2297,8 +2297,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_core_codec_control(switch_codec codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, SWIGTYPE_p_void cmd_data, SWIGTYPE_p_switch_codec_control_type_t rtype, SWIGTYPE_p_p_void ret_data) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_control(switch_codec.getCPtr(codec), (int)cmd, (int)ctype, SWIGTYPE_p_void.getCPtr(cmd_data), SWIGTYPE_p_switch_codec_control_type_t.getCPtr(rtype), SWIGTYPE_p_p_void.getCPtr(ret_data)); + public static switch_status_t switch_core_codec_control(switch_codec codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, SWIGTYPE_p_void cmd_data, switch_codec_control_type_t atype, SWIGTYPE_p_void cmd_arg, SWIGTYPE_p_switch_codec_control_type_t rtype, SWIGTYPE_p_p_void ret_data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_codec_control(switch_codec.getCPtr(codec), (int)cmd, (int)ctype, SWIGTYPE_p_void.getCPtr(cmd_data), (int)atype, SWIGTYPE_p_void.getCPtr(cmd_arg), SWIGTYPE_p_switch_codec_control_type_t.getCPtr(rtype), SWIGTYPE_p_p_void.getCPtr(ret_data)); return ret; } @@ -3514,8 +3514,8 @@ public class freeswitch { freeswitchPINVOKE.switch_core_codec_add_implementation(SWIGTYPE_p_apr_pool_t.getCPtr(pool), switch_codec_interface.getCPtr(codec_interface), (int)codec_type, ianacode, iananame, fmtp, samples_per_second, actual_samples_per_second, bits_per_second, microseconds_per_packet, samples_per_packet, decoded_bytes_per_packet, encoded_bytes_per_packet, number_of_channels, codec_frames_per_packet, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t.getCPtr(init), SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t.getCPtr(encode), SWIGTYPE_p_f_p_switch_codec_p_switch_codec_p_void_unsigned_long_unsigned_long_p_void_p_unsigned_long_p_unsigned_long_p_unsigned_int__switch_status_t.getCPtr(decode), SWIGTYPE_p_f_p_switch_codec__switch_status_t.getCPtr(destroy)); } - public static void switch_core_codec_add_video_implementation(SWIGTYPE_p_apr_pool_t pool, switch_codec_interface codec_interface, byte ianacode, string iananame, string fmtp, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t init, SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t encode, SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t decode, SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t control, SWIGTYPE_p_f_p_switch_codec__switch_status_t destroy) { - freeswitchPINVOKE.switch_core_codec_add_video_implementation(SWIGTYPE_p_apr_pool_t.getCPtr(pool), switch_codec_interface.getCPtr(codec_interface), ianacode, iananame, fmtp, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t.getCPtr(init), SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t.getCPtr(encode), SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t.getCPtr(decode), SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t.getCPtr(control), SWIGTYPE_p_f_p_switch_codec__switch_status_t.getCPtr(destroy)); + public static void switch_core_codec_add_video_implementation(SWIGTYPE_p_apr_pool_t pool, switch_codec_interface codec_interface, byte ianacode, string iananame, string fmtp, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t init, SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t encode, SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t decode, SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t control, SWIGTYPE_p_f_p_switch_codec__switch_status_t destroy) { + freeswitchPINVOKE.switch_core_codec_add_video_implementation(SWIGTYPE_p_apr_pool_t.getCPtr(pool), switch_codec_interface.getCPtr(codec_interface), ianacode, iananame, fmtp, SWIGTYPE_p_f_p_switch_codec_unsigned_long_p_q_const__switch_codec_settings__switch_status_t.getCPtr(init), SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t.getCPtr(encode), SWIGTYPE_p_f_p_switch_codec_p_switch_frame__switch_status_t.getCPtr(decode), SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t.getCPtr(control), SWIGTYPE_p_f_p_switch_codec__switch_status_t.getCPtr(destroy)); } public static switch_bool_t switch_core_codec_ready(switch_codec codec) { @@ -5615,6 +5615,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_parse_next_signal_data(SWIGTYPE_p_switch_core_session session) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_parse_next_signal_data(SWIGTYPE_p_switch_core_session.getCPtr(session)); + return ret; + } + public static switch_status_t switch_ivr_process_indications(SWIGTYPE_p_switch_core_session session, switch_core_session_message message) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_process_indications(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_core_session_message.getCPtr(message)); return ret; @@ -5887,11 +5892,21 @@ public class freeswitch { return ret; } + public static switch_status_t switch_ivr_3p_media(string uuid, uint flags) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_3p_media(uuid, flags); + return ret; + } + public static switch_status_t switch_ivr_nomedia(string uuid, uint flags) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_nomedia(uuid, flags); return ret; } + public static switch_status_t switch_ivr_3p_nomedia(string uuid, uint flags) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_3p_nomedia(uuid, flags); + return ret; + } + public static switch_status_t switch_ivr_hold_uuid(string uuid, string message, switch_bool_t moh) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_ivr_hold_uuid(uuid, message, (int)moh); return ret; @@ -6431,18 +6446,18 @@ public class freeswitch { return ret; } - public static switch_status_t switch_rtp_set_video_buffer_size(SWIGTYPE_p_switch_rtp rtp_session, uint frames) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_video_buffer_size(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), frames); + public static switch_status_t switch_rtp_set_video_buffer_size(SWIGTYPE_p_switch_rtp rtp_session, uint frames, uint max_frames) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_video_buffer_size(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), frames, max_frames); return ret; } - public static uint switch_rtp_get_video_buffer_size(SWIGTYPE_p_switch_rtp rtp_session) { - uint ret = freeswitchPINVOKE.switch_rtp_get_video_buffer_size(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); + public static switch_status_t switch_rtp_get_video_buffer_size(SWIGTYPE_p_switch_rtp rtp_session, SWIGTYPE_p_unsigned_long min_frame_len, SWIGTYPE_p_unsigned_long max_frame_len, SWIGTYPE_p_unsigned_long cur_frame_len, SWIGTYPE_p_unsigned_long highest_frame_len) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_get_video_buffer_size(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), SWIGTYPE_p_unsigned_long.getCPtr(min_frame_len), SWIGTYPE_p_unsigned_long.getCPtr(max_frame_len), SWIGTYPE_p_unsigned_long.getCPtr(cur_frame_len), SWIGTYPE_p_unsigned_long.getCPtr(highest_frame_len)); return ret; } - public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames, uint max_queue_frames, uint samples_per_packet, uint samples_per_second, uint max_drift) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames, max_queue_frames, samples_per_packet, samples_per_second, max_drift); + public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames, uint max_queue_frames, uint samples_per_packet, uint samples_per_second) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames, max_queue_frames, samples_per_packet, samples_per_second); return ret; } @@ -6461,9 +6476,9 @@ public class freeswitch { return ret; } - public static SWIGTYPE_p_stfu_instance_t switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) { + public static SWIGTYPE_p_switch_jb_s switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session) { IntPtr cPtr = freeswitchPINVOKE.switch_rtp_get_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session)); - SWIGTYPE_p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_stfu_instance_t(cPtr, false); + SWIGTYPE_p_switch_jb_s ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_jb_s(cPtr, false); return ret; } @@ -11008,7 +11023,7 @@ class freeswitchPINVOKE { public static extern int switch_core_codec_encode_video(HandleRef jarg1, HandleRef jarg2); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_control")] - public static extern int switch_core_codec_control(HandleRef jarg1, int jarg2, int jarg3, HandleRef jarg4, HandleRef jarg5, HandleRef jarg6); + public static extern int switch_core_codec_control(HandleRef jarg1, int jarg2, int jarg3, HandleRef jarg4, int jarg5, HandleRef jarg6, HandleRef jarg7, HandleRef jarg8); [DllImport("mod_managed", EntryPoint="CSharp_switch_core_codec_decode_video")] public static extern int switch_core_codec_decode_video(HandleRef jarg1, HandleRef jarg2); @@ -13779,6 +13794,12 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_mm_t_vbuf_get")] public static extern int switch_mm_t_vbuf_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_mm_t_vencspd_set")] + public static extern void switch_mm_t_vencspd_set(HandleRef jarg1, int jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_mm_t_vencspd_get")] + public static extern int switch_mm_t_vencspd_get(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_mm_t")] public static extern IntPtr new_switch_mm_t(); @@ -16800,6 +16821,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_parse_all_signal_data")] public static extern int switch_ivr_parse_all_signal_data(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_parse_next_signal_data")] + public static extern int switch_ivr_parse_next_signal_data(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_process_indications")] public static extern int switch_ivr_process_indications(HandleRef jarg1, HandleRef jarg2); @@ -16962,9 +16986,15 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_media")] public static extern int switch_ivr_media(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_3p_media")] + public static extern int switch_ivr_3p_media(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_nomedia")] public static extern int switch_ivr_nomedia(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_3p_nomedia")] + public static extern int switch_ivr_3p_nomedia(string jarg1, uint jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_ivr_hold_uuid")] public static extern int switch_ivr_hold_uuid(string jarg1, string jarg2, int jarg3); @@ -17512,13 +17542,13 @@ class freeswitchPINVOKE { public static extern IntPtr switch_rtp_get_media_timer(HandleRef jarg1); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_video_buffer_size")] - public static extern int switch_rtp_set_video_buffer_size(HandleRef jarg1, uint jarg2); + public static extern int switch_rtp_set_video_buffer_size(HandleRef jarg1, uint jarg2, uint jarg3); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_video_buffer_size")] - public static extern uint switch_rtp_get_video_buffer_size(HandleRef jarg1); + public static extern int switch_rtp_get_video_buffer_size(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3, HandleRef jarg4, HandleRef jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_jitter_buffer")] - public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5, uint jarg6); + public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2, uint jarg3, uint jarg4, uint jarg5); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_debug_jitter_buffer")] public static extern int switch_rtp_debug_jitter_buffer(HandleRef jarg1, string jarg2); @@ -21032,18 +21062,18 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; -public class SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t { +public class SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t { private HandleRef swigCPtr; - internal SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t(IntPtr cPtr, bool futureUse) { + internal SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t(IntPtr cPtr, bool futureUse) { swigCPtr = new HandleRef(this, cPtr); } - protected SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t() { + protected SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t() { swigCPtr = new HandleRef(null, IntPtr.Zero); } - internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t obj) { + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; } } @@ -21212,36 +21242,6 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; -public class SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t { - private HandleRef swigCPtr; - - internal SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t(IntPtr cPtr, bool futureUse) { - swigCPtr = new HandleRef(this, cPtr); - } - - protected SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t() { - swigCPtr = new HandleRef(null, IntPtr.Zero); - } - - internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t 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_f_p_switch_core_session__int { private HandleRef swigCPtr; @@ -21872,6 +21872,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s 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_f_p_switch_directory_handle_p_char_p_char_p_char__switch_status_t { private HandleRef swigCPtr; @@ -24812,36 +24842,6 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; -public class SWIGTYPE_p_stfu_instance_t { - private HandleRef swigCPtr; - - internal SWIGTYPE_p_stfu_instance_t(IntPtr cPtr, bool futureUse) { - swigCPtr = new HandleRef(this, cPtr); - } - - protected SWIGTYPE_p_stfu_instance_t() { - swigCPtr = new HandleRef(null, IntPtr.Zero); - } - - internal static HandleRef getCPtr(SWIGTYPE_p_stfu_instance_t 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_switch_buffer { private HandleRef swigCPtr; @@ -25472,6 +25472,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_jb_s { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_jb_s(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_jb_s() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_jb_s 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_switch_live_array_s { private HandleRef swigCPtr; @@ -29148,6 +29178,7 @@ public enum switch_channel_flag_t { CF_3PCC, CF_VIDEO_PASSIVE, CF_NOVIDEO, + CF_VIDEO_BITRATE_UNMANAGABLE, CF_VIDEO_ECHO, CF_VIDEO_BLANK, CF_SLA_INTERCEPT, @@ -29166,6 +29197,10 @@ public enum switch_channel_flag_t { CF_VIDEO_MIRROR_INPUT, CF_VIDEO_READ_FILE_ATTACHED, CF_VIDEO_WRITE_FILE_ATTACHED, + CF_3P_MEDIA_REQUESTED, + CF_3P_NOMEDIA_REQUESTED, + CF_3P_NOMEDIA_REQUESTED_BLEG, + CF_VIDEO_SDP_RECVD, CF_FLAG_MAX } @@ -29704,10 +29739,12 @@ public class switch_chat_interface : IDisposable { namespace FreeSWITCH.Native { public enum switch_codec_control_command_t { - SCC_VIDEO_REFRESH = 0, + SCC_VIDEO_GEN_KEYFRAME = 0, SCC_VIDEO_BANDWIDTH, SCC_VIDEO_RESET, - SCC_AUDIO_PACKET_LOSS + SCC_AUDIO_PACKET_LOSS, + SCC_DEBUG, + SCC_CODEC_SPECIFIC } } @@ -30257,13 +30294,13 @@ public class switch_codec_implementation : IDisposable { } } - public SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t codec_control { + public SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t codec_control { set { - freeswitchPINVOKE.switch_codec_implementation_codec_control_set(swigCPtr, SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t.getCPtr(value)); + freeswitchPINVOKE.switch_codec_implementation_codec_control_set(swigCPtr, SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_codec_implementation_codec_control_get(swigCPtr); - SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t(cPtr, false); + SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_codec_enum_switch_codec_control_command_t_enum_switch_codec_control_type_t_p_void_enum_switch_codec_control_type_t_p_void_p_enum_switch_codec_control_type_t_p_p_void__switch_status_t(cPtr, false); return ret; } } @@ -31208,7 +31245,9 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_TRANSFER, SWITCH_MESSAGE_INDICATE_RINGING, SWITCH_MESSAGE_INDICATE_MEDIA, + SWITCH_MESSAGE_INDICATE_3P_MEDIA, SWITCH_MESSAGE_INDICATE_NOMEDIA, + SWITCH_MESSAGE_INDICATE_3P_NOMEDIA, SWITCH_MESSAGE_INDICATE_HOLD, SWITCH_MESSAGE_INDICATE_UNHOLD, SWITCH_MESSAGE_INDICATE_REDIRECT, @@ -31245,6 +31284,8 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_HARD_MUTE, SWITCH_MESSAGE_INDICATE_BITRATE_REQ, SWITCH_MESSAGE_INDICATE_BITRATE_ACK, + SWITCH_MESSAGE_INDICATE_CODEC_DEBUG_REQ, + SWITCH_MESSAGE_INDICATE_CODEC_SPECIFIC_REQ, SWITCH_MESSAGE_REFER_EVENT, SWITCH_MESSAGE_ANSWER_EVENT, SWITCH_MESSAGE_PROGRESS_EVENT, @@ -36550,13 +36591,13 @@ public class switch_io_routines : IDisposable { } } - public SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t get_jb { + public SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s get_jb { set { - freeswitchPINVOKE.switch_io_routines_get_jb_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t.getCPtr(value)); + freeswitchPINVOKE.switch_io_routines_get_jb_set(swigCPtr, SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s.getCPtr(value)); } get { IntPtr cPtr = freeswitchPINVOKE.switch_io_routines_get_jb_get(swigCPtr); - SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_enum_switch_media_type_t__p_stfu_instance_t(cPtr, false); + SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_f_p_switch_core_session_t_switch_media_type_t__p_switch_jb_s(cPtr, false); return ret; } } @@ -38000,6 +38041,16 @@ public class switch_mm_t : IDisposable { } } + public switch_video_encode_speed_t vencspd { + set { + freeswitchPINVOKE.switch_mm_t_vencspd_set(swigCPtr, (int)value); + } + get { + switch_video_encode_speed_t ret = (switch_video_encode_speed_t)freeswitchPINVOKE.switch_mm_t_vencspd_get(swigCPtr); + return ret; + } + } + public switch_mm_t() : this(freeswitchPINVOKE.new_switch_mm_t(), true) { } @@ -42597,6 +42648,24 @@ public class switch_video_codec_settings : IDisposable { namespace FreeSWITCH.Native { +public enum switch_video_encode_speed_t { + SWITCH_VIDEO_ENCODE_SPEED_DEFAULT, + SWITCH_VIDEO_ENCODE_SPEED_SLOW, + SWITCH_VIDEO_ENCODE_SPEED_MEDIUM, + SWITCH_VIDEO_ENCODE_SPEED_FAST +} + +} +/* ---------------------------------------------------------------------------- + * 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 { + public enum switch_video_read_flag_t { SVR_BLOCK = (1 << 0), SVR_FLUSH = (1 << 1), diff --git a/src/mod/languages/mod_v8/src/fsodbc.cpp b/src/mod/languages/mod_v8/src/fsodbc.cpp index 79cf57a906..80bc90ebd7 100644 --- a/src/mod/languages/mod_v8/src/fsodbc.cpp +++ b/src/mod/languages/mod_v8/src/fsodbc.cpp @@ -315,12 +315,17 @@ JS_ODBC_FUNCTION_IMPL(GetData) SQLULEN ColumnSize; SQLCHAR name[1024] = ""; SQLCHAR *data = _colbuf; - + SQLLEN pcbValue; + SQLDescribeCol(_stmt, x, name, sizeof(name), &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable); - SQLGetData(_stmt, x, SQL_C_CHAR, _colbuf, _cblen, NULL); + SQLGetData(_stmt, x, SQL_C_CHAR, _colbuf, _cblen, &pcbValue); if (name) { - arg->Set(String::NewFromUtf8(GetIsolate(), (const char *)name), String::NewFromUtf8(GetIsolate(), data ? (const char *)data : "")); + if (SQL_NULL_DATA == pcbValue) { + arg->Set(String::NewFromUtf8(GetIsolate(), (const char *)name), Null(info.GetIsolate())); + } else { + arg->Set(String::NewFromUtf8(GetIsolate(), (const char *)name), String::NewFromUtf8(GetIsolate(), data ? (const char *)data : "")); + } } } diff --git a/src/mod/xml_int/mod_xml_cdr/Makefile.am b/src/mod/xml_int/mod_xml_cdr/Makefile.am index cd8cf88f53..f66f0afa74 100644 --- a/src/mod/xml_int/mod_xml_cdr/Makefile.am +++ b/src/mod/xml_int/mod_xml_cdr/Makefile.am @@ -3,6 +3,6 @@ MODNAME=mod_xml_cdr mod_LTLIBRARIES = mod_xml_cdr.la mod_xml_cdr_la_SOURCES = mod_xml_cdr.c -mod_xml_cdr_la_CFLAGS = $(AM_CFLAGS) +mod_xml_cdr_la_CFLAGS = $(CURL_CFLAGS) $(AM_CFLAGS) mod_xml_cdr_la_LIBADD = $(switch_builddir)/libfreeswitch.la -mod_xml_cdr_la_LDFLAGS = -avoid-version -module -no-undefined -shared +mod_xml_cdr_la_LDFLAGS = $(CURL_LIBS) -avoid-version -module -no-undefined -shared diff --git a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c index 3871993078..a71726c357 100644 --- a/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c +++ b/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c @@ -160,6 +160,12 @@ static switch_status_t do_config(void) SWITCH_MODULE_LOAD_FUNCTION(mod_xml_rpc_load) { + + if (switch_event_reserve_subclass("websocket::stophook") != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", "websocket::stophook"); + 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); @@ -1268,6 +1274,8 @@ void stop_all_websockets() SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_rpc_shutdown) { + switch_event_free_subclass("websocket::stophook"); + /* Cann't find a way to stop the websockets, use this for a workaround before finding the real one that works */ stop_all_websockets(); diff --git a/src/switch_apr.c b/src/switch_apr.c index 81b448eba5..8407d42713 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -1119,7 +1119,6 @@ SWITCH_DECLARE(switch_status_t) switch_queue_pop_timeout(switch_queue_t *queue, return apr_queue_pop_timeout(queue, data, timeout); } - SWITCH_DECLARE(switch_status_t) switch_queue_push(switch_queue_t *queue, void *data) { apr_status_t s; @@ -1141,6 +1140,11 @@ SWITCH_DECLARE(switch_status_t) switch_queue_interrupt_all(switch_queue_t *queue return apr_queue_interrupt_all(queue); } +SWITCH_DECLARE(switch_status_t) switch_queue_term(switch_queue_t *queue) +{ + return apr_queue_term(queue); +} + SWITCH_DECLARE(switch_status_t) switch_queue_trypush(switch_queue_t *queue, void *data) { apr_status_t s; diff --git a/src/switch_channel.c b/src/switch_channel.c index 47eadef2e6..f528f84a9d 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2100,10 +2100,8 @@ SWITCH_DECLARE(int) switch_channel_state_change_pending(switch_channel_t *channe SWITCH_DECLARE(int) switch_channel_check_signal(switch_channel_t *channel, switch_bool_t in_thread_only) { - if (!in_thread_only || switch_core_session_in_thread(channel->session)) { - switch_ivr_parse_all_signal_data(channel->session); - } - + (void)in_thread_only; + switch_ivr_parse_next_signal_data(channel->session); return 0; } @@ -2525,21 +2523,21 @@ SWITCH_DECLARE(void) switch_channel_event_set_basic_data(switch_channel_t *chann switch_channel_test_flag(channel, CF_DIALPLAN) ? "true" : "false"); - if ((v = switch_channel_get_variable(channel, "presence_id"))) { + if ((v = switch_channel_get_variable_dup(channel, "presence_id", SWITCH_FALSE, -1))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-ID", v); } - if ((v = switch_channel_get_variable(channel, "presence_data"))) { + if ((v = switch_channel_get_variable_dup(channel, "presence_data", SWITCH_FALSE, -1))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-Data", v); } - if ((v = switch_channel_get_variable(channel, "presence_data_cols"))) { + if ((v = switch_channel_get_variable_dup(channel, "presence_data_cols", SWITCH_FALSE, -1))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Data-Cols", v); switch_event_add_presence_data_cols(channel, event, "PD-"); } - if ((v = switch_channel_get_variable(channel, "call_uuid"))) { + if ((v = switch_channel_get_variable_dup(channel, "call_uuid", SWITCH_FALSE, -1))) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", v); } else { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", switch_core_session_get_uuid(channel->session)); diff --git a/src/switch_core_codec.c b/src/switch_core_codec.c index 5d51a3e62a..59ca4e494f 100644 --- a/src/switch_core_codec.c +++ b/src/switch_core_codec.c @@ -878,6 +878,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_control(switch_codec_t *codec, switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data) { @@ -898,7 +900,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_control(switch_codec_t *codec, if (codec->mutex) switch_mutex_lock(codec->mutex); if (codec->implementation->codec_control) { - status = codec->implementation->codec_control(codec, cmd, ctype, cmd_data, rtype, ret_data); + status = codec->implementation->codec_control(codec, cmd, ctype, cmd_data, atype, cmd_arg, rtype, ret_data); } if (codec->mutex) switch_mutex_unlock(codec->mutex); diff --git a/src/switch_core_media.c b/src/switch_core_media.c index d776e77f47..c0163f07e6 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -157,10 +157,13 @@ typedef struct switch_rtp_engine_s { uint8_t nack; uint8_t tmmbr; uint8_t no_crypto; + uint8_t dtls_controller; switch_codec_settings_t codec_settings; switch_media_flow_t rmode; switch_media_flow_t smode; switch_thread_id_t thread_id; + uint8_t new_ice; + uint8_t new_dtls; } switch_rtp_engine_t; struct switch_media_handle_s { @@ -1851,12 +1854,17 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t if (v_engine->rtp_session) { if (!strncasecmp(input, "vbsize:", 7)) { - int frames = 0; + int frames = 0, max_frames = 0; s = input + 7; frames = atoi(s); + + if ((s = strchr(s, ':')) && *(s+1) != '\0') { + max_frames = atoi(s+1); + } + if (frames > 0) { - switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames); + switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, max_frames); } return; } else if (!strncasecmp(input, "vdebug:", 7)) { @@ -1873,27 +1881,30 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t if (jb_msec || (val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) { - int max_drift = 0; - char *p, *q; + char *p; if (!jb_msec) { jb_msec = atoi(val); + + if (strchr(val, 'p') && jb_msec > 0) { + jb_msec *= -1; + } if ((p = strchr(val, ':'))) { p++; maxlen = atoi(p); - if ((q = strchr(p, ':'))) { - q++; - max_drift = abs(atoi(q)); + + if (strchr(p, 'p') && maxlen > 0) { + maxlen *= -1; } } } - if (jb_msec < 0 && jb_msec > -20) { + if (jb_msec < 0 && jb_msec > -1000) { jb_msec = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(jb_msec); } - if (maxlen < 0 && maxlen > -20) { + if (maxlen < 0 && maxlen > -1000) { maxlen = (a_engine->read_codec.implementation->microseconds_per_packet / 1000) * abs(maxlen); } @@ -1901,7 +1912,7 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec); } else { - int qlen, maxqlen = 10; + int qlen, maxqlen = 30; qlen = jb_msec / (a_engine->read_impl.microseconds_per_packet / 1000); @@ -1914,11 +1925,11 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t } if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen, a_engine->read_impl.samples_per_packet, - a_engine->read_impl.samples_per_second, max_drift) == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames) (%d max drift)\n", - jb_msec, qlen, maxqlen, max_drift); - switch_channel_set_flag(session->channel, CF_JITTERBUFFER); + a_engine->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_DEBUG, "Setting Jitterbuffer to %dms (%d frames) (%d max frames)\n", + jb_msec, qlen, maxqlen); + switch_channel_set_flag(session->channel, CF_JITTERBUFFER); if (!switch_false(switch_channel_get_variable(session->channel, "rtp_jitter_buffer_plc"))) { switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC); } @@ -1936,8 +1947,13 @@ static void check_jb_sync(switch_core_session_t *session) { int32_t jb_sync_msec = 0; uint32_t fps, frames = 0; + uint32_t min_frames = 0; + uint32_t max_frames = 0; + uint32_t cur_frames = 0; switch_media_handle_t *smh; switch_rtp_engine_t *v_engine = NULL; + int sync_audio = 0, sync_video = 0; + const char *var; switch_assert(session); @@ -1952,7 +1968,7 @@ static void check_jb_sync(switch_core_session_t *session) v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; - if ((var = switch_channel_get_variable_dup(session->channel, "jb_sync_msec", SWITCH_FALSE, -1))) { + if ((var = switch_channel_get_variable_dup(session->channel, "jb_av_sync_msec", SWITCH_FALSE, -1))) { int tmp; char *p; @@ -1978,43 +1994,40 @@ static void check_jb_sync(switch_core_session_t *session) fps = switch_core_media_get_video_fps(session); } - if (!fps) return; + if (fps < 15) return; + + switch_rtp_get_video_buffer_size(v_engine->rtp_session, &min_frames, &max_frames, &cur_frames, NULL); if (!frames) { - frames = fps / 7.5; - if (frames < 1) frames = 1; + if (cur_frames != min_frames) { + frames = cur_frames; + } else { + frames = fps / 7.5; + if (frames < 1) frames = 1; + sync_audio = 1; + } } if (!jb_sync_msec) { jb_sync_msec = frames * 75; } - //if (!frames) { - // if (jb_sync_msec < 0) { - // frames = abs(jb_sync_msec); - // jb_sync_msec = 1000 / (fps / frames); - // } else { - // frames = fps / (1000 / jb_sync_msec); - // } - //} - if (frames == switch_rtp_get_video_buffer_size(v_engine->rtp_session)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_DEBUG1, "%s %s \"%s\" A/V JB not changed %dms %u VFrames FPS %u\n", - switch_core_session_get_uuid(session), - switch_channel_get_name(session->channel), - switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1), - jb_sync_msec, frames, fps); - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), - SWITCH_LOG_DEBUG, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u\n", - switch_core_session_get_uuid(session), - switch_channel_get_name(session->channel), - switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1), - jb_sync_msec, frames, fps); - - switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames); - check_jb(session, NULL, jb_sync_msec, jb_sync_msec); + if (frames != cur_frames) { + switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, 0); + sync_audio = 1; + sync_video = 1; + } + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), + SWITCH_LOG_DEBUG, "%s %s \"%s\" Sync A/V JB to %dms %u VFrames FPS %u a:%s v:%s\n", + switch_core_session_get_uuid(session), + switch_channel_get_name(session->channel), + switch_channel_get_variable_dup(session->channel, "caller_id_name", SWITCH_FALSE, -1), + jb_sync_msec, frames, fps, sync_audio ? "yes" : "no", sync_video ? "yes" : "no"); + + if (sync_audio) { + check_jb(session, NULL, jb_sync_msec, 0); } } @@ -3072,7 +3085,7 @@ SWITCH_DECLARE(switch_call_direction_t) switch_ice_direction(switch_core_session r = (r == SWITCH_CALL_DIRECTION_INBOUND) ? SWITCH_CALL_DIRECTION_OUTBOUND : SWITCH_CALL_DIRECTION_INBOUND; } - if ((switch_channel_test_flag(session->channel, CF_REINVITE) || switch_channel_test_flag(session->channel, CF_RECOVERING)) + if ((switch_channel_test_flag(session->channel, CF_REINVITE) || switch_channel_test_flag(session->channel, CF_RECOVERING)) && switch_channel_test_flag(session->channel, CF_AVPF)) { r = SWITCH_CALL_DIRECTION_OUTBOUND; } @@ -3080,6 +3093,7 @@ SWITCH_DECLARE(switch_call_direction_t) switch_ice_direction(switch_core_session return r; } + //? static switch_status_t ip_choose_family(switch_media_handle_t *smh, const char *ip) { @@ -3135,9 +3149,9 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t const char *val; int ice_seen = 0, cid = 0, ai = 0; - if (engine->ice_in.is_chosen[0] && engine->ice_in.is_chosen[1] && !switch_channel_test_flag(smh->session->channel, CF_REINVITE)) { - return SWITCH_STATUS_SUCCESS; - } + //if (engine->ice_in.is_chosen[0] && engine->ice_in.is_chosen[1]) { + //return SWITCH_STATUS_SUCCESS; + //} engine->ice_in.chosen[0] = 0; engine->ice_in.chosen[1] = 0; @@ -3160,14 +3174,35 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t if (zstr(attr->a_name)) { continue; } - + if (!strcasecmp(attr->a_name, "ice-ufrag")) { - engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value); + 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")) { - engine->ice_in.pwd = switch_core_session_strdup(smh->session, attr->a_value); + 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; @@ -3175,9 +3210,18 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t if ((p = strchr(engine->remote_dtls_fingerprint.type, ' '))) { *p++ = '\0'; - switch_set_string(engine->local_dtls_fingerprint.str, p); + + 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"); //engine->local_dtls_fingerprint.type = NULL; @@ -3375,7 +3419,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t if (switch_channel_test_flag(smh->session->channel, CF_REINVITE)) { - if (switch_rtp_ready(engine->rtp_session) && engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready) { + if (switch_rtp_ready(engine->rtp_session) && engine->ice_in.cands[engine->ice_in.chosen[0]][0].ready && engine->new_ice) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_INFO, "RE-Activating %s ICE\n", type2str(type)); switch_rtp_activate_ice(engine->rtp_session, @@ -3395,7 +3439,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t ); - + engine->new_ice = 0; } @@ -3575,6 +3619,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_clear_flag(smh->session->channel, CF_DTLS); } + v_engine->new_dtls = 1; + v_engine->new_ice = 1; + a_engine->new_dtls = 1; + a_engine->new_ice = 1; + switch_core_session_parse_crypto_prefs(session); clear_pmaps(a_engine); @@ -3810,7 +3859,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s a_engine->rmode = sdp_media_flow(m->m_mode); - + if (sdp_type == SDP_TYPE_REQUEST) { switch(a_engine->rmode) { case SWITCH_MEDIA_FLOW_RECVONLY: @@ -4282,7 +4331,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s } } - + if (match) { char tmp[50]; //const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload"); @@ -5804,10 +5853,10 @@ SWITCH_DECLARE(void) switch_core_session_wake_video_thread(switch_core_session_t static void check_dtls_reinvite(switch_core_session_t *session, switch_rtp_engine_t *engine) { - if (switch_channel_test_flag(session->channel, CF_REINVITE)) { + if (switch_channel_test_flag(session->channel, CF_REINVITE) && engine->new_dtls) { if (!zstr(engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(session)) { - dtls_type_t xtype, dtype = switch_ice_direction(session) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; + dtls_type_t xtype, dtype = engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "RE-SETTING %s DTLS\n", type2str(engine->type)); @@ -5822,6 +5871,7 @@ static void check_dtls_reinvite(switch_core_session_t *session, switch_rtp_engin } } + engine->new_dtls = 0; } } @@ -5925,6 +5975,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi flags[SWITCH_RTP_FLAG_BYTESWAP] = 0; } + if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta")) && switch_true(val)) { + flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1; + } + if (a_engine->rtp_session && switch_channel_test_flag(session->channel, CF_REINVITE)) { //const char *ip = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE); //const char *port = switch_channel_get_variable(session->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE); @@ -6107,9 +6161,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_core_media_parse_rtp_bugs(&a_engine->rtp_bugs, val); } - if (switch_channel_test_flag(session->channel, CF_AVPF)) { - smh->mparams->manual_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS; - } + //if (switch_channel_test_flag(session->channel, CF_AVPF)) { + // smh->mparams->manual_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS; + //} switch_rtp_intentional_bugs(a_engine->rtp_session, a_engine->rtp_bugs | smh->mparams->manual_rtp_bugs); @@ -6201,11 +6255,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } if (!zstr(a_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) { - dtls_type_t xtype, dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; + dtls_type_t xtype, dtype = a_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; - if (switch_channel_test_flag(smh->session->channel, CF_3PCC)) { - dtype = (dtype == DTLS_TYPE_CLIENT) ? DTLS_TYPE_SERVER : DTLS_TYPE_CLIENT; - } + //if (switch_channel_test_flag(smh->session->channel, CF_3PCC)) { + // dtype = (dtype == DTLS_TYPE_CLIENT) ? DTLS_TYPE_SERVER : DTLS_TYPE_CLIENT; + //} xtype = DTLS_TYPE_RTP; if (a_engine->rtcp_mux > 0 && smh->mparams->rtcp_audio_interval_msec) xtype |= DTLS_TYPE_RTCP; @@ -6572,7 +6626,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi #else switch_ice_direction(session) == SWITCH_CALL_DIRECTION_OUTBOUND ? ICE_VANILLA : (ICE_VANILLA | ICE_CONTROLLED), - &v_engine->ice_in #endif ); @@ -6586,7 +6639,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if (!zstr(v_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls() && dtls_ok(smh->session)) { dtls_type_t xtype, - dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; + dtype = v_engine->dtls_controller ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; xtype = DTLS_TYPE_RTP; if (v_engine->rtcp_mux > 0 && smh->mparams->rtcp_video_interval_msec) xtype |= DTLS_TYPE_RTCP; @@ -6661,10 +6714,18 @@ static const char *get_media_profile_name(switch_core_session_t *session, int se switch_assert(session); if (switch_channel_test_flag(session->channel, CF_AVPF)) { - if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) { - return "UDP/TLS/RTP/SAVPF"; + if (switch_channel_test_flag(session->channel, CF_DTLS)) { + if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) { + return "UDP/TLS/RTP/SAVPF"; + } else { + return "RTP/SAVPF"; + } } else { - return "RTP/SAVPF"; + if (switch_channel_test_flag(session->channel, CF_AVPF_MOZ)) { + return "UDP/AVPF"; + } else { + return "RTP/AVPF"; + } } } @@ -6676,15 +6737,20 @@ static const char *get_media_profile_name(switch_core_session_t *session, int se } -static char *get_setup(switch_core_session_t *session, switch_sdp_type_t sdp_type) +static char *get_setup(switch_rtp_engine_t *engine, switch_core_session_t *session, switch_sdp_type_t sdp_type) { - if (sdp_type == SDP_TYPE_RESPONSE && !switch_channel_test_flag(session->channel, CF_RECOVERING)) { - return "active"; - } - return "actpass"; + if (sdp_type == SDP_TYPE_REQUEST) { + engine->dtls_controller = 0; + engine->new_dtls = 1; + engine->new_ice = 1; + return "actpass"; + } else { + return engine->dtls_controller ? "active" : "passive"; + } } + //? static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, switch_port_t port, const char *family, const char *ip, @@ -6853,7 +6919,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, if (!zstr(a_engine->local_dtls_fingerprint.type) && secure) { switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\n", a_engine->local_dtls_fingerprint.type, - a_engine->local_dtls_fingerprint.str, get_setup(session, sdp_type)); + a_engine->local_dtls_fingerprint.str, get_setup(a_engine, session, sdp_type)); } if (smh->mparams->rtcp_audio_interval_msec) { @@ -7325,6 +7391,15 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess smh->dtmf_ianacodes[i] = smh->mparams->te; smh->cng_ianacodes[i] = smh->mparams->cng_pt; } else { + int j = 0; + + for (j = 0; j < smh->mparams->num_codecs; j++) { + if (smh->ianacodes[j] == smh->payload_space) { + smh->payload_space++; + break; + } + } + smh->dtmf_ianacodes[i] = (switch_payload_t)smh->payload_space++; smh->cng_ianacodes[i] = (switch_payload_t)smh->payload_space++; } @@ -7549,7 +7624,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (!zstr(a_engine->local_dtls_fingerprint.type)) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\n", a_engine->local_dtls_fingerprint.type, - a_engine->local_dtls_fingerprint.str, get_setup(session, sdp_type)); + a_engine->local_dtls_fingerprint.str, get_setup(a_engine, session, sdp_type)); } if (smh->mparams->rtcp_audio_interval_msec) { @@ -7964,7 +8039,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (!zstr(v_engine->local_dtls_fingerprint.type)) { switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\n", v_engine->local_dtls_fingerprint.type, - v_engine->local_dtls_fingerprint.str, get_setup(session, sdp_type)); + v_engine->local_dtls_fingerprint.str, get_setup(v_engine, session, sdp_type)); } @@ -8901,6 +8976,55 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } break; + case SWITCH_MESSAGE_INDICATE_CODEC_DEBUG_REQ: + { + switch_rtp_engine_t *engine = &smh->engines[msg->numeric_reply]; + uint32_t level = (uint32_t) msg->numeric_arg; + + if (engine->rtp_session) { + switch_core_codec_control(&engine->read_codec, SCC_DEBUG, SCCT_INT, (void *)&level, SCCT_NONE, NULL, NULL, NULL); + switch_core_codec_control(&engine->write_codec, SCC_DEBUG, SCCT_INT, (void *)&level, SCCT_NONE, NULL, NULL, NULL); + } + } + break; + + case SWITCH_MESSAGE_INDICATE_CODEC_SPECIFIC_REQ: + { + switch_rtp_engine_t *engine; + switch_io_type_t iotype = SWITCH_IO_READ; + switch_media_type_t type = SWITCH_MEDIA_TYPE_AUDIO; + switch_codec_control_type_t reply_type = SCCT_NONE; + void *reply = NULL; + + if (!strcasecmp(msg->string_array_arg[0], "video")) { + type = SWITCH_MEDIA_TYPE_VIDEO; + } + + if (!strcasecmp(msg->string_array_arg[1], "write")) { + iotype = SWITCH_IO_WRITE; + } + + engine = &smh->engines[type]; + + if (engine->rtp_session) { + if (iotype == SWITCH_IO_READ) { + switch_core_codec_control(&engine->read_codec, SCC_CODEC_SPECIFIC, + SCCT_STRING, (void *)msg->string_array_arg[2], + SCCT_STRING, (void *)msg->string_array_arg[3], &reply_type, &reply); + } else { + switch_core_codec_control(&engine->write_codec, SCC_CODEC_SPECIFIC, + SCCT_STRING, (void *)msg->string_array_arg[2], + SCCT_STRING, (void *)msg->string_array_arg[3], &reply_type, &reply); + } + + + if (reply_type == SCCT_STRING) { + msg->string_array_arg[4] = (char *)reply; + } + } + } + break; + case SWITCH_MESSAGE_INDICATE_DEBUG_MEDIA: { switch_rtp_t *rtp = a_engine->rtp_session; @@ -8951,7 +9075,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se const char *val; int ok = 0; - if (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val)) { + if (!switch_channel_test_flag(session->channel, CF_VIDEO) && + (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) { if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel)); @@ -9399,7 +9524,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_udptl_mode(switch_core_session } //? -SWITCH_DECLARE(stfu_instance_t *) switch_core_media_get_jb(switch_core_session_t *session, switch_media_type_t type) +SWITCH_DECLARE(switch_jb_t *) switch_core_media_get_jb(switch_core_session_t *session, switch_media_type_t type) { switch_media_handle_t *smh; @@ -9763,12 +9888,12 @@ SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *sessi if (switch_core_codec_ready(&v_engine->read_codec)) { type = 1; - switch_core_codec_control(&v_engine->read_codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, NULL, NULL); + switch_core_codec_control(&v_engine->read_codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL); } if (switch_core_codec_ready(&v_engine->write_codec)) { type = 2; - switch_core_codec_control(&v_engine->write_codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, NULL, NULL); + switch_core_codec_control(&v_engine->write_codec, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL); } if (a_engine->rtp_session) { @@ -10402,6 +10527,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess switch_codec_control_command_t cmd, switch_codec_control_type_t ctype, void *cmd_data, + switch_codec_control_type_t atype, + void *cmd_arg, switch_codec_control_type_t *rtype, void **ret_data) { @@ -10436,7 +10563,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess } if (codec) { - if (cmd == SCC_VIDEO_REFRESH) { + if (cmd == SCC_VIDEO_GEN_KEYFRAME) { switch_time_t now = switch_micro_time_now(); if (smh->last_codec_refresh && (now - smh->last_codec_refresh) < VIDEO_REFRESH_FREQ) { @@ -10447,7 +10574,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess switch_channel_set_flag(session->channel, CF_VIDEO_REFRESH_REQ); } - return switch_core_codec_control(codec, cmd, ctype, cmd_data, rtype, ret_data); + return switch_core_codec_control(codec, cmd, ctype, cmd_data, atype, cmd_arg, rtype, ret_data); } return SWITCH_STATUS_FALSE; @@ -10461,7 +10588,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_encoded_video_frame(sw switch_status_t status = SWITCH_STATUS_FALSE; if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Writing video to RECVONLY session\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY session\n"); return SWITCH_STATUS_SUCCESS; } @@ -10498,7 +10625,7 @@ SWITCH_DECLARE(void) switch_core_session_video_reinit(switch_core_session_t *ses switch_core_session_send_and_request_video_refresh(session); type = 1; - switch_core_media_codec_control(session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_READ, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, NULL, NULL); + switch_core_media_codec_control(session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_READ, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, SCCT_NONE, NULL, NULL, NULL); switch_core_session_request_video_refresh(session); } @@ -10532,7 +10659,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor } if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Writing video to RECVONLY session\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY session\n"); return SWITCH_STATUS_SUCCESS; } @@ -10585,12 +10712,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor if (session->bugs) { switch_media_bug_t *bp; - switch_bool_t ok = SWITCH_TRUE; int prune = 0; int patched = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + switch_bool_t ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -10820,12 +10948,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core if (session->bugs) { switch_media_bug_t *bp; - switch_bool_t ok = SWITCH_TRUE; int prune = 0; int patched = 0; switch_thread_rwlock_rdlock(session->bug_rwlock); for (bp = session->bugs; bp; bp = bp->next) { + switch_bool_t ok = SWITCH_TRUE; + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index c059f1cadc..9b6e28e9dd 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -65,7 +65,7 @@ SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_ } -SWITCH_DECLARE(stfu_instance_t *) switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type) +SWITCH_DECLARE(switch_jb_t *) switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type) { if (session->endpoint_interface->io_routines->get_jb) { return session->endpoint_interface->io_routines->get_jb(session, type); @@ -759,6 +759,8 @@ static const char *message_names[] = { "HARD_MUTE", "BITRATE_REQ", "BITRATE_ACK", + "CODEC_DEBUG_REQ", + "CODEC_SPECIFIC_REQ", "REFER_EVENT", "ANSWER_EVENT", "PROGRESS_EVENT", @@ -1675,45 +1677,18 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th { switch_thread_pool_node_t *node = (switch_thread_pool_node_t *) obj; switch_memory_pool_t *pool = node->pool; - void *pop; - int check = 0; - - switch_mutex_lock(session_manager.mutex); - session_manager.starting--; - session_manager.running++; - switch_mutex_unlock(session_manager.mutex); #ifdef DEBUG_THREAD_POOL switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Started\n", (long) (intptr_t) thread); #endif - while(session_manager.ready) { - switch_status_t check_status; - - pop = NULL; - - if (check) { - check_status = switch_queue_trypop(session_manager.thread_queue, &pop); - } else { - switch_mutex_lock(session_manager.mutex); - session_manager.popping++; - switch_mutex_unlock(session_manager.mutex); - - check_status = switch_queue_pop(session_manager.thread_queue, &pop); - - switch_mutex_lock(session_manager.mutex); - session_manager.popping--; - switch_mutex_unlock(session_manager.mutex); - } - - if (check_status == SWITCH_STATUS_SUCCESS && pop) { + for (;;) { + void *pop; + switch_status_t check_status = switch_queue_pop_timeout(session_manager.thread_queue, &pop, 5000000); + if (check_status == SWITCH_STATUS_SUCCESS) { switch_thread_data_t *td = (switch_thread_data_t *) pop; - switch_mutex_lock(session_manager.mutex); - session_manager.busy++; - switch_mutex_unlock(session_manager.mutex); #ifdef DEBUG_THREAD_POOL switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Processing\n", (long) (intptr_t) thread); #endif - td->func(thread, td->obj); if (td->pool) { @@ -1729,23 +1704,22 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_worker(switch_th switch_mutex_lock(session_manager.mutex); session_manager.busy--; switch_mutex_unlock(session_manager.mutex); - } else { - if (check) { + switch_mutex_lock(session_manager.mutex); + if (!switch_status_is_timeup(check_status) || session_manager.running > session_manager.busy) { + if (!--session_manager.running) { + switch_thread_cond_signal(session_manager.cond); + } + switch_mutex_unlock(session_manager.mutex); break; } - check++; + switch_mutex_unlock(session_manager.mutex); } } #ifdef DEBUG_THREAD_POOL switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Worker Thread %ld Ended\n", (long)(intptr_t) thread); #endif - switch_mutex_lock(session_manager.mutex); - session_manager.running--; - switch_mutex_unlock(session_manager.mutex); - switch_core_destroy_memory_pool(&pool); - return NULL; } @@ -1772,46 +1746,18 @@ static void thread_launch_failure(void) switch_mutex_unlock(session_manager.mutex); } -static int wake_queue(void) -{ - switch_status_t status; - int tries = 0; - - top: - - status = switch_mutex_trylock(session_manager.cond_mutex); - - if (status == SWITCH_STATUS_SUCCESS) { - switch_thread_cond_signal(session_manager.cond); - switch_mutex_unlock(session_manager.cond_mutex); - return 1; - } else { - if (switch_mutex_trylock(session_manager.cond2_mutex) == SWITCH_STATUS_SUCCESS) { - switch_mutex_unlock(session_manager.cond2_mutex); - } else { - if (++tries < 10) { - switch_cond_next(); - goto top; - } - } - } - - return 0; -} - static switch_status_t check_queue(void) { switch_status_t status = SWITCH_STATUS_FALSE; - int ttl = 0; - int x = 0; - switch_mutex_lock(session_manager.mutex); - ttl = switch_queue_size(session_manager.thread_queue); - x = ((session_manager.running + session_manager.starting) - session_manager.busy); + if (session_manager.running >= ++session_manager.busy) { + switch_mutex_unlock(session_manager.mutex); + return SWITCH_STATUS_SUCCESS; + } + ++session_manager.running; switch_mutex_unlock(session_manager.mutex); - - while (x < ttl) { + { switch_thread_t *thread; switch_threadattr_t *thd_attr; switch_memory_pool_t *pool; @@ -1827,6 +1773,11 @@ static switch_status_t check_queue(void) switch_threadattr_priority_set(thd_attr, SWITCH_PRI_LOW); if (switch_thread_create(&thread, thd_attr, switch_core_session_thread_pool_worker, node, node->pool) != SWITCH_STATUS_SUCCESS) { + switch_mutex_lock(session_manager.mutex); + if (!--session_manager.running) { + switch_thread_cond_signal(session_manager.cond); + } + switch_mutex_unlock(session_manager.mutex); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Thread Failure!\n"); switch_core_destroy_memory_pool(&pool); status = SWITCH_STATUS_GENERR; @@ -1834,76 +1785,11 @@ static switch_status_t check_queue(void) } else { status = SWITCH_STATUS_SUCCESS; } - - switch_mutex_lock(session_manager.mutex); - session_manager.starting++; - switch_mutex_unlock(session_manager.mutex); - x++; } - return status; } -static void *SWITCH_THREAD_FUNC switch_core_session_thread_pool_manager(switch_thread_t *thread, void *obj) -{ - - uint32_t sleep = 10000000; - switch_time_t next = switch_micro_time_now() + sleep; - - switch_mutex_lock(session_manager.cond_mutex); - - while(session_manager.ready) { - int check = 1; - int ttl = 0; - uint32_t xsleep = sleep; - - switch_mutex_lock(session_manager.mutex); - ttl = switch_queue_size(session_manager.thread_queue); - switch_mutex_unlock(session_manager.mutex); - - - if (!ttl) { - xsleep = 10000; - } - - if (switch_mutex_trylock(session_manager.cond2_mutex) == SWITCH_STATUS_SUCCESS) { - switch_thread_cond_timedwait(session_manager.cond, session_manager.cond_mutex, xsleep); - switch_mutex_unlock(session_manager.cond2_mutex); - } - - - if (switch_micro_time_now() >= next) { - if (session_manager.popping) { -#ifdef DEBUG_THREAD_POOL - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, - "Thread pool: running:%d busy:%d popping:%d\n", session_manager.running, session_manager.busy, session_manager.popping); -#endif - switch_queue_interrupt_all(session_manager.thread_queue); - - sleep = 100000; - check = 0; - } else { - sleep = 10000000; - } - } - - if (check) check_queue(); - - next = switch_micro_time_now() + sleep; - } - - switch_mutex_unlock(session_manager.cond_mutex); - - while(session_manager.running) { - switch_queue_interrupt_all(session_manager.thread_queue); - switch_yield(20000); - } - - - return NULL; -} - SWITCH_DECLARE(switch_status_t) switch_thread_pool_launch_thread(switch_thread_data_t **tdp) { switch_status_t status = SWITCH_STATUS_SUCCESS; @@ -1914,8 +1800,8 @@ SWITCH_DECLARE(switch_status_t) switch_thread_pool_launch_thread(switch_thread_d td = *tdp; *tdp = NULL; - switch_queue_push(session_manager.thread_queue, td); - wake_queue(); + status = switch_queue_push(session_manager.thread_queue, td); + check_queue(); return status; } @@ -1931,14 +1817,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_pool_launch(switch_co } else if (switch_test_flag(session, SSF_THREAD_STARTED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Cannot launch thread again after it has already been run!\n"); } else { - status = SWITCH_STATUS_SUCCESS; switch_set_flag(session, SSF_THREAD_RUNNING); switch_set_flag(session, SSF_THREAD_STARTED); td = switch_core_session_alloc(session, sizeof(*td)); td->obj = session; td->func = switch_core_session_thread; - switch_queue_push(session_manager.thread_queue, td); - wake_queue(); + status = switch_queue_push(session_manager.thread_queue, td); + check_queue(); } switch_mutex_unlock(session->mutex); @@ -2581,39 +2466,19 @@ void switch_core_session_init(switch_memory_pool_t *pool) session_manager.session_id = 1; session_manager.memory_pool = pool; switch_core_hash_init(&session_manager.session_table); - - if (switch_test_flag((&runtime), SCF_SESSION_THREAD_POOL)) { - switch_threadattr_t *thd_attr; - - switch_mutex_init(&session_manager.mutex, SWITCH_MUTEX_NESTED, session_manager.memory_pool); - switch_thread_cond_create(&session_manager.cond, session_manager.memory_pool); - switch_mutex_init(&session_manager.cond_mutex, SWITCH_MUTEX_NESTED, session_manager.memory_pool); - switch_mutex_init(&session_manager.cond2_mutex, SWITCH_MUTEX_NESTED, session_manager.memory_pool); - switch_queue_create(&session_manager.thread_queue, 100000, session_manager.memory_pool); - switch_threadattr_create(&thd_attr, session_manager.memory_pool); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - session_manager.ready = 1; - switch_thread_create(&session_manager.manager_thread, thd_attr, switch_core_session_thread_pool_manager, NULL, session_manager.memory_pool); - } - + switch_mutex_init(&session_manager.mutex, SWITCH_MUTEX_DEFAULT, session_manager.memory_pool); + switch_thread_cond_create(&session_manager.cond, session_manager.memory_pool); + switch_queue_create(&session_manager.thread_queue, 100000, session_manager.memory_pool); } void switch_core_session_uninit(void) { - int sanity = 100; - switch_status_t st = SWITCH_STATUS_FALSE; - - session_manager.ready = 0; - wake_queue(); - - while(session_manager.running && --sanity > 0) { - switch_queue_interrupt_all(session_manager.thread_queue); - switch_yield(100000); - } - - switch_thread_join(&st, session_manager.manager_thread); + switch_queue_term(session_manager.thread_queue); + switch_mutex_lock(session_manager.mutex); + if (session_manager.running) + switch_thread_cond_timedwait(session_manager.cond, session_manager.mutex, 10000000); + switch_mutex_unlock(session_manager.mutex); switch_core_hash_destroy(&session_manager.session_table); - } SWITCH_DECLARE(switch_app_log_t *) switch_core_session_get_app_log(switch_core_session_t *session) @@ -3062,7 +2927,7 @@ SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_ SWITCH_DECLARE(void) switch_core_session_debug_pool(switch_stream_handle_t *stream) { stream->write_function(stream, "Thread pool: running:%d busy:%d popping:%d\n", - session_manager.running, session_manager.busy, session_manager.popping); + session_manager.running, session_manager.busy, session_manager.running - session_manager.busy); } SWITCH_DECLARE(void) switch_core_session_raw_read(switch_core_session_t *session) diff --git a/src/switch_cpp.cpp b/src/switch_cpp.cpp index 335c7ab88a..df9c5dbd98 100644 --- a/src/switch_cpp.cpp +++ b/src/switch_cpp.cpp @@ -234,8 +234,16 @@ SWITCH_DECLARE(const char *) API::execute(const char *cmd, const char *arg) { switch_stream_handle_t stream = { 0 }; this_check(""); + SWITCH_STANDARD_STREAM(stream); - switch_api_execute(cmd, arg, session, &stream); + + if (zstr(cmd)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); + stream.write_function(&stream, "-ERR No application specified"); + } else { + switch_api_execute(cmd, arg, session, &stream); + } + return (char *) stream.data; } @@ -730,6 +738,11 @@ SWITCH_DECLARE(void) CoreSession::execute(const char *app, const char *data) this_check_void(); sanity_check_noreturn; + if (zstr(app)) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No application specified\n"); + return; + } + begin_allow_threads(); switch_core_session_execute_application(session, app, data); end_allow_threads(); diff --git a/src/switch_event.c b/src/switch_event.c index ae73436306..89f1b74cf2 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1993,6 +1993,22 @@ SWITCH_DECLARE(switch_status_t) switch_event_fire_detailed(const char *file, con return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status_t) switch_event_get_custom_events(switch_console_callback_match_t **matches) +{ + switch_hash_index_t *hi = NULL; + const void *var; + void *val; + int x = 0; + + for (hi = switch_core_hash_first(CUSTOM_HASH); hi; hi = switch_core_hash_next(&hi)) { + switch_core_hash_this(hi, &var, NULL, &val); + switch_console_push_match(matches, (const char *) var); + x++; + } + + return x ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; +} + SWITCH_DECLARE(switch_status_t) switch_event_bind_removable(const char *id, switch_event_types_t event, const char *subclass_name, switch_event_callback_t callback, void *user_data, switch_event_node_t **node) { diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 3e514d1e61..f1995c52ee 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -820,7 +820,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_sessio } -SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_session_t *session) +static switch_status_t switch_ivr_parse_signal_data(switch_core_session_t *session, switch_bool_t all) { void *data; switch_core_session_message_t msg = { 0 }; @@ -847,7 +847,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_ses switch_core_session_receive_message(session, &msg); data = NULL; - + if (!all) + break; } switch_channel_clear_flag(channel, CF_SIGNAL_DATA); @@ -855,6 +856,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_ses return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; } +SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_signal_data(switch_core_session_t *session) { + return switch_ivr_parse_signal_data(session, SWITCH_TRUE); +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_parse_next_signal_data(switch_core_session_t *session) { + return switch_ivr_parse_signal_data(session, SWITCH_FALSE); +} + SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_events(switch_core_session_t *session) { int x = 0; @@ -3150,59 +3159,90 @@ SWITCH_DECLARE(void) switch_ivr_park_session(switch_core_session_t *session) SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint32_t delay_ms) { - stfu_instance_t *jb; + switch_jb_t *jb; int qlen = 0; - stfu_frame_t *jb_frame; switch_frame_t *read_frame, write_frame = { 0 }; switch_status_t status; switch_channel_t *channel = switch_core_session_get_channel(session); uint32_t interval; uint32_t ts = 0; + uint16_t seq = 0; switch_codec_implementation_t read_impl = { 0 }; - switch_core_session_get_read_impl(session, &read_impl); + int is_rtp = 0; + int debug = 0; + const char *var; + switch_core_session_get_read_impl(session, &read_impl); + if (delay_ms < 1 || delay_ms > 10000) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms); return; } interval = read_impl.microseconds_per_packet / 1000; - //samples = switch_samples_per_packet(read_impl.samples_per_second, interval); if (delay_ms < interval * 2) { delay_ms = interval * 2; switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Minimum possible delay for this codec (%d) has been chosen\n", delay_ms); } - qlen = delay_ms / (interval); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen); - jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second, 0); + + switch_jb_create(&jb, SJB_AUDIO, qlen, qlen, switch_core_session_get_pool(session)); + + if ((var = switch_channel_get_variable(channel, "delay_echo_debug_level"))) { + debug = atoi(var); + } + + if (debug) { + switch_jb_debug_level(jb, debug); + } write_frame.codec = switch_core_session_get_read_codec(session); while (switch_channel_ready(channel)) { + switch_rtp_packet_t packet = { {0} }; + switch_size_t plen = sizeof(packet); + status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { break; } - stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen, 0); - ts += read_impl.samples_per_packet; + if (switch_test_flag(read_frame, SFF_CNG)) { + continue; + } + + if (read_frame->packet) { + is_rtp = 1; + switch_jb_put_packet(jb, (switch_rtp_packet_t *) read_frame->packet, read_frame->packetlen); + } else if (is_rtp) { + continue; + } else { + ts += read_impl.samples_per_packet; + memcpy(packet.body, read_frame->data, read_frame->datalen); + packet.header.ts = htonl(ts); + packet.header.seq = htons(++seq); + packet.header.version = 2; + } + + if (switch_jb_get_packet(jb, (switch_rtp_packet_t *) &packet, &plen) == SWITCH_STATUS_SUCCESS) { + write_frame.data = packet.body; + write_frame.datalen = (uint32_t) plen - 12; + write_frame.buflen = (uint32_t) plen; - if ((jb_frame = stfu_n_read_a_frame(jb))) { - write_frame.data = jb_frame->data; - write_frame.datalen = (uint32_t) jb_frame->dlen; - write_frame.buflen = (uint32_t) jb_frame->dlen; status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { break; } } } - stfu_n_destroy(&jb); + switch_jb_destroy(&jb); } SWITCH_DECLARE(switch_status_t) switch_ivr_say(switch_core_session_t *session, diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 0438930299..9f5b472b19 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -770,7 +770,7 @@ static switch_bool_t write_displace_callback(switch_media_bug_t *bug, void *user } else { st = switch_core_file_read(&dh->fh, rframe->data, &len); if (len < rframe->samples) { - memset((char *)rframe->data + len * 2 * dh->fh.channels, 0, (rframe->datalen - len) * 2 * dh->fh.channels); + memset((char *)rframe->data + (len * 2 * dh->fh.channels), 0, (rframe->samples - len) * 2 * dh->fh.channels); } } diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index ecad0171ae..e25fff1bf5 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -599,7 +599,12 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) if (!switch_channel_test_flag(chan_a, CF_ANSWERED) && answer_limit && switch_epoch_time_now(NULL) > answer_limit) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Answer timeout hit on %s.\n", switch_channel_get_name(chan_a)); - switch_channel_hangup(chan_a, SWITCH_CAUSE_ALLOTTED_TIMEOUT); + if (switch_true(switch_channel_get_variable_dup(chan_a, "continue_on_answer_timeout", SWITCH_FALSE, -1))) { + data->clean_exit = 1; + goto end_of_bridge_loop; + } else { + switch_channel_hangup(chan_a, SWITCH_CAUSE_ALLOTTED_TIMEOUT); + } } if (!switch_channel_test_flag(chan_a, CF_ANSWERED)) { @@ -1749,8 +1754,8 @@ static void cleanup_proxy_mode_b(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); - - if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && + !switch_channel_test_flag(channel, CF_MEDIA_TRANS) && !switch_channel_test_flag(channel, CF_3P_MEDIA_REQUESTED)) { switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE); } } diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c new file mode 100644 index 0000000000..cf6bf6dd69 --- /dev/null +++ b/src/switch_jitterbuffer.c @@ -0,0 +1,1278 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2014, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * switch_jitterbuffer.c -- Audio/Video Jitter Buffer + * + */ +#include +#include +#include "private/switch_hashtable_private.h" + +#define NACK_TIME 80000 +#define RENACK_TIME 100000 +#define PERIOD_LEN 250 +#define MAX_FRAME_PADDING 2 +#define MAX_MISSING_SEQ 20 +#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%d sz:%u/%u/%u/%u c:%u %u/%u/%u/%u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->visible_nodes, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__) + +//const char *TOKEN_1 = "ONE"; +//const char *TOKEN_2 = "TWO"; + +struct switch_jb_s; + +typedef struct switch_jb_node_s { + struct switch_jb_s *parent; + switch_rtp_packet_t packet; + uint32_t len; + uint8_t visible; + uint8_t bad_hits; + struct switch_jb_node_s *prev; + struct switch_jb_node_s *next; +} switch_jb_node_t; + +struct switch_jb_s { + struct switch_jb_node_s *node_list; + uint32_t last_target_seq; + uint32_t highest_read_ts; + uint32_t highest_read_seq; + uint32_t highest_wrote_ts; + uint32_t highest_wrote_seq; + uint16_t target_seq; + uint32_t target_ts; + uint32_t last_target_ts; + uint16_t psuedo_seq; + uint32_t visible_nodes; + uint32_t complete_frames; + uint32_t frame_len; + uint32_t min_frame_len; + uint32_t max_frame_len; + uint32_t highest_frame_len; + uint32_t period_miss_count; + uint32_t consec_miss_count; + uint32_t period_miss_inc; + double period_miss_pct; + uint32_t period_good_count; + uint32_t consec_good_count; + uint32_t period_count; + uint32_t dropped; + uint32_t samples_per_frame; + uint32_t samples_per_second; + uint32_t bitrate_control; + uint32_t video_low_bitrate; + uint8_t write_init; + uint8_t read_init; + uint8_t debug_level; + uint16_t next_seq; + switch_size_t last_len; + switch_inthash_t *missing_seq_hash; + switch_inthash_t *node_hash; + switch_inthash_t *node_hash_ts; + switch_mutex_t *mutex; + switch_mutex_t *list_mutex; + switch_memory_pool_t *pool; + int free_pool; + switch_jb_flag_t flags; + switch_jb_type_t type; + switch_core_session_t *session; + switch_channel_t *channel; +}; + + +static int node_cmp(const void *l, const void *r) +{ + switch_jb_node_t *a = (switch_jb_node_t *) l; + switch_jb_node_t *b = (switch_jb_node_t *) r; + + if (!a->visible) return 0; + if (!b->visible) return 1; + + return ntohs(a->packet.header.seq) - ntohs(b->packet.header.seq); +} + +//http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c +switch_jb_node_t *sort_nodes(switch_jb_node_t *list, int (*cmp)(const void *, const void *)) { + switch_jb_node_t *p, *q, *e, *tail; + int insize, nmerges, psize, qsize, i; + + if (!list) { + return NULL; + } + + insize = 1; + + while (1) { + p = list; + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = q->next; + if (!q) break; + } + + /* if q hasn't fallen off end, we have two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next switch_jb_node_t of merge comes from p or q */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; q = q->next; qsize--; + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; p = p->next; psize--; + } else if (cmp(p,q) <= 0) { + /* First switch_jb_node_t of p is lower (or same); + * e must come from p. */ + e = p; p = p->next; psize--; + } else { + /* First switch_jb_node_t of q is lower; e must come from q. */ + e = q; q = q->next; qsize--; + } + + /* add the next switch_jb_node_t to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + + /* Maintain reverse pointers in a doubly linked list. */ + e->prev = tail; + + tail = e; + } + + /* now p has stepped `insize' places along, and q has too */ + p = q; + } + + tail->next = NULL; + + /* If we have done only one merge, we're finished. */ + if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ + return list; + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } +} + + +static inline switch_jb_node_t *new_node(switch_jb_t *jb) +{ + switch_jb_node_t *np; + + switch_mutex_lock(jb->list_mutex); + + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) { + break; + } + } + + if (!np) { + + np = switch_core_alloc(jb->pool, sizeof(*np)); + + np->next = jb->node_list; + if (np->next) { + np->next->prev = np; + } + jb->node_list = np; + + } + + switch_assert(np); + np->bad_hits = 0; + np->visible = 1; + jb->visible_nodes++; + np->parent = jb; + + switch_mutex_unlock(jb->list_mutex); + + return np; +} + +static inline void push_to_top(switch_jb_t *jb, switch_jb_node_t *node) +{ + if (node == jb->node_list) { + jb->node_list = node->next; + } else if (node->prev) { + node->prev->next = node->next; + } + + if (node->next) { + node->next->prev = node->prev; + } + + node->next = jb->node_list; + node->prev = NULL; + + if (node->next) { + node->next->prev = node; + } + + jb->node_list = node; + + switch_assert(node->next != node); + switch_assert(node->prev != node); +} + +static inline void hide_node(switch_jb_node_t *node, switch_bool_t pop) +{ + switch_jb_t *jb = node->parent; + + switch_mutex_lock(jb->list_mutex); + + if (node->visible) { + node->visible = 0; + node->bad_hits = 0; + jb->visible_nodes--; + + if (pop) { + push_to_top(jb, node); + } + } + + if (jb->node_hash_ts) { + switch_core_inthash_delete(jb->node_hash_ts, node->packet.header.ts); + } + + switch_core_inthash_delete(jb->node_hash, node->packet.header.seq); + + switch_mutex_unlock(jb->list_mutex); +} + +static inline void sort_free_nodes(switch_jb_t *jb) +{ + switch_mutex_lock(jb->list_mutex); + jb->node_list = sort_nodes(jb->node_list, node_cmp); + switch_mutex_unlock(jb->list_mutex); +} + +static inline void hide_nodes(switch_jb_t *jb) +{ + switch_jb_node_t *np; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + hide_node(np, SWITCH_FALSE); + } + switch_mutex_unlock(jb->list_mutex); +} + +static inline void drop_ts(switch_jb_t *jb, uint32_t ts) +{ + switch_jb_node_t *np; + int x = 0; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) continue; + + if (ts == np->packet.header.ts) { + hide_node(np, SWITCH_FALSE); + x++; + } + } + + if (x) { + sort_free_nodes(jb); + } + + switch_mutex_unlock(jb->list_mutex); + + if (x) jb->complete_frames--; +} + +static inline switch_jb_node_t *jb_find_lowest_seq(switch_jb_t *jb, uint32_t ts) +{ + switch_jb_node_t *np, *lowest = NULL; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) continue; + + if (ts && ts != np->packet.header.ts) continue; + + if (!lowest || ntohs(lowest->packet.header.seq) > ntohs(np->packet.header.seq)) { + lowest = np; + } + } + switch_mutex_unlock(jb->list_mutex); + + return lowest; +} + +static inline switch_jb_node_t *jb_find_lowest_node(switch_jb_t *jb) +{ + switch_jb_node_t *np, *lowest = NULL; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) continue; + + if (!lowest || ntohl(lowest->packet.header.ts) > ntohl(np->packet.header.ts)) { + lowest = np; + } + } + switch_mutex_unlock(jb->list_mutex); + + return lowest ? lowest : NULL; +} + +static inline uint32_t jb_find_lowest_ts(switch_jb_t *jb) +{ + switch_jb_node_t *lowest = jb_find_lowest_node(jb); + + return lowest ? lowest->packet.header.ts : 0; +} + +#if 0 +static inline switch_jb_node_t *jb_find_highest_node(switch_jb_t *jb) +{ + switch_jb_node_t *np, *highest = NULL; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) continue; + + if (!highest || ntohl(highest->packet.header.ts) < ntohl(np->packet.header.ts)) { + highest = np; + } + } + switch_mutex_unlock(jb->list_mutex); + + return highest ? highest : NULL; +} + +static inline uint32_t jb_find_highest_ts(switch_jb_t *jb) +{ + switch_jb_node_t *highest = jb_find_highest_node(jb); + + return highest ? highest->packet.header.ts : 0; +} + + + +static inline switch_jb_node_t *jb_find_penultimate_node(switch_jb_t *jb) +{ + switch_jb_node_t *np, *highest = NULL, *second_highest = NULL; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) continue; + + if (!highest || ntohl(highest->packet.header.ts) < ntohl(np->packet.header.ts)) { + if (highest) second_highest = highest; + highest = np; + } + } + switch_mutex_unlock(jb->list_mutex); + + return second_highest ? second_highest : highest; +} +#endif + +static inline void jb_hit(switch_jb_t *jb) +{ + jb->period_good_count++; + jb->consec_good_count++; + jb->consec_miss_count = 0; +} + +static void jb_frame_inc_line(switch_jb_t *jb, int i, int line) +{ + uint32_t old_frame_len = jb->frame_len; + + if (i == 0) { + jb->frame_len = jb->min_frame_len; + goto end; + } + + if (i > 0) { + if ((jb->frame_len + i) < jb->max_frame_len) { + jb->frame_len += i; + } else { + jb->frame_len = jb->max_frame_len; + } + + goto end; + } + + if (i < 0) { + if ((jb->frame_len + i) > jb->min_frame_len) { + jb->frame_len += i; + } else { + jb->frame_len = jb->min_frame_len; + } + } + + end: + + if (jb->frame_len > jb->highest_frame_len) { + jb->highest_frame_len = jb->frame_len; + } + + if (old_frame_len != jb->frame_len) { + jb_debug(jb, 2, "%d Change framelen from %u to %u\n", line, old_frame_len, jb->frame_len); + if (jb->session) { + switch_core_session_request_video_refresh(jb->session); + } + } + +} + +#define jb_frame_inc(_jb, _i) jb_frame_inc_line(_jb, _i, __LINE__) + + +static inline void jb_miss(switch_jb_t *jb) +{ + jb->period_miss_count++; + jb->consec_miss_count++; + jb->consec_good_count = 0; +} + +#if 0 +static inline int verify_oldest_frame(switch_jb_t *jb) +{ + switch_jb_node_t *lowest = NULL, *np = NULL; + int r = 0; + + lowest = jb_find_lowest_node(jb); + + if (!lowest || !(lowest = jb_find_lowest_seq(jb, lowest->packet.header.ts))) { + goto end; + } + + switch_mutex_lock(jb->mutex); + + jb->node_list = sort_nodes(jb->node_list, node_cmp); + + for (np = lowest->next; np; np = np->next) { + + if (!np->visible) continue; + + if (ntohs(np->packet.header.seq) != ntohs(np->prev->packet.header.seq) + 1) { + uint32_t val = (uint32_t)htons(ntohs(np->prev->packet.header.seq) + 1); + + if (!switch_core_inthash_find(jb->missing_seq_hash, val)) { + switch_core_inthash_insert(jb->missing_seq_hash, val, (void *)(intptr_t)1); + } + break; + } + + if (np->packet.header.ts != lowest->packet.header.ts || !np->next) { + r = 1; + } + } + + switch_mutex_unlock(jb->mutex); + + end: + + return r; +} +#endif + +static inline void drop_oldest_frame(switch_jb_t *jb) +{ + uint32_t ts = jb_find_lowest_ts(jb); + + drop_ts(jb, ts); + jb_debug(jb, 1, "Dropping oldest frame ts:%u\n", ntohl(ts)); +} + +#if 0 +static inline void drop_newest_frame(switch_jb_t *jb) +{ + uint32_t ts = jb_find_highest_ts(jb); + + drop_ts(jb, ts); + jb_debug(jb, 1, "Dropping highest frame ts:%u\n", ntohl(ts)); +} +#endif + +static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) +{ + switch_jb_node_t *node = new_node(jb); + + node->packet = *packet; + node->len = len; + memcpy(node->packet.body, packet->body, len); + + switch_core_inthash_insert(jb->node_hash, node->packet.header.seq, node); + + if (jb->node_hash_ts) { + switch_core_inthash_insert(jb->node_hash_ts, node->packet.header.ts, node); + } + + jb_debug(jb, (packet->header.m ? 1 : 2), "PUT packet last_ts:%u ts:%u seq:%u%s\n", + ntohl(jb->highest_wrote_ts), ntohl(node->packet.header.ts), ntohs(node->packet.header.seq), packet->header.m ? " " : ""); + + if (jb->write_init && jb->type == SJB_VIDEO && ((abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))) >= jb->max_frame_len) || + (abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts))) > (900000 * 5)))) { + jb_debug(jb, 2, "CHANGE DETECTED, PUNT %u\n", abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq)))); + switch_jb_reset(jb); + } + + if (!jb->write_init || ntohs(packet->header.seq) > ntohs(jb->highest_wrote_seq) || + (ntohs(jb->highest_wrote_seq) > USHRT_MAX - 10 && ntohs(packet->header.seq) <= 10) ) { + jb->highest_wrote_seq = packet->header.seq; + } + + if (jb->type == SJB_VIDEO) { + if (jb->write_init && htons(packet->header.seq) >= htons(jb->highest_wrote_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_wrote_ts))) { + jb->complete_frames++; + jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + jb->highest_wrote_ts = packet->header.ts; + //verify_oldest_frame(jb); + } else if (!jb->write_init) { + jb->highest_wrote_ts = packet->header.ts; + } + } else { + if (jb->write_init) { + jb_debug(jb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + jb->complete_frames++; + } else { + jb->highest_wrote_ts = packet->header.ts; + } + } + + if (!jb->write_init) jb->write_init = 1; +} + +static inline void increment_ts(switch_jb_t *jb) +{ + if (!jb->target_ts) return; + + jb->target_ts = htonl((ntohl(jb->target_ts) + jb->samples_per_frame)); + jb->psuedo_seq++; +} + +static inline void set_read_ts(switch_jb_t *jb, uint32_t ts) +{ + if (!ts) return; + + jb->last_target_ts = ts; + jb->target_ts = htonl((ntohl(jb->last_target_ts) + jb->samples_per_frame)); + jb->psuedo_seq++; +} + + +static inline void increment_seq(switch_jb_t *jb) +{ + jb->target_seq = htons((ntohs(jb->target_seq) + 1)); +} + +static inline void set_read_seq(switch_jb_t *jb, uint16_t seq) +{ + jb->last_target_seq = seq; + jb->target_seq = htons((ntohs(jb->last_target_seq) + 1)); +} + +static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_node_t **nodep) +{ + switch_jb_node_t *node = NULL; + + top: + + if (jb->type == SJB_VIDEO) { + if (jb->dropped) { + jb->dropped = 0; + jb_debug(jb, 2, "%s", "DROPPED FRAME DETECTED RESYNCING\n"); + jb->target_seq = 0; + + if (jb->session) { + switch_core_session_request_video_refresh(jb->session); + } + } + } + + if (!jb->target_seq) { + if ((node = jb_find_lowest_seq(jb, 0))) { + jb_debug(jb, 2, "No target seq using seq: %u as a starting point\n", ntohs(node->packet.header.seq)); + } else { + jb_debug(jb, 1, "%s", "No nodes available....\n"); + } + jb_hit(jb); + } else if ((node = switch_core_inthash_find(jb->node_hash, jb->target_seq))) { + jb_debug(jb, 2, "FOUND desired seq: %u\n", ntohs(jb->target_seq)); + jb_hit(jb); + } else { + jb_debug(jb, 2, "MISSING desired seq: %u\n", ntohs(jb->target_seq)); + jb_miss(jb); + + if (jb->type == SJB_VIDEO) { + int x; + + if (jb->period_miss_count > 1 && !jb->period_miss_inc) { + jb->period_miss_inc++; + jb_frame_inc(jb, 1); + } + + //if (jb->session) { + // switch_core_session_request_video_refresh(jb->session); + //} + + for (x = 0; x < 10; x++) { + increment_seq(jb); + if ((node = switch_core_inthash_find(jb->node_hash, jb->target_seq))) { + jb_debug(jb, 2, "FOUND incremental seq: %u\n", ntohs(jb->target_seq)); + + if (node->packet.header.m || node->packet.header.ts == jb->highest_read_ts) { + jb_debug(jb, 2, "%s", "SAME FRAME DROPPING\n"); + jb->dropped++; + drop_ts(jb, node->packet.header.ts); + node = NULL; + goto top; + } + break; + } else { + jb_debug(jb, 2, "MISSING incremental seq: %u\n", ntohs(jb->target_seq)); + } + } + } else { + increment_seq(jb); + } + } + + *nodep = node; + + if (node) { + set_read_seq(jb, node->packet.header.seq); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_NOTFOUND; + +} + + +static inline switch_status_t jb_next_packet_by_ts(switch_jb_t *jb, switch_jb_node_t **nodep) +{ + switch_jb_node_t *node = NULL; + + if (!jb->target_ts) { + if ((node = jb_find_lowest_node(jb))) { + jb_debug(jb, 2, "No target ts using ts: %u as a starting point\n", ntohl(node->packet.header.ts)); + } else { + jb_debug(jb, 1, "%s", "No nodes available....\n"); + } + jb_hit(jb); + } else if ((node = switch_core_inthash_find(jb->node_hash_ts, jb->target_ts))) { + jb_debug(jb, 2, "FOUND desired ts: %u\n", ntohl(jb->target_ts)); + jb_hit(jb); + } else { + jb_debug(jb, 2, "MISSING desired ts: %u\n", ntohl(jb->target_ts)); + jb_miss(jb); + increment_ts(jb); + } + + *nodep = node; + + if (node) { + set_read_ts(jb, node->packet.header.ts); + node->packet.header.seq = htons(jb->psuedo_seq); + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_NOTFOUND; + +} + +static inline switch_status_t jb_next_packet(switch_jb_t *jb, switch_jb_node_t **nodep) +{ + if (jb->samples_per_frame) { + return jb_next_packet_by_ts(jb, nodep); + } else { + return jb_next_packet_by_seq(jb, nodep); + } +} + +static inline void free_nodes(switch_jb_t *jb) +{ + switch_mutex_lock(jb->list_mutex); + jb->node_list = NULL; + switch_mutex_unlock(jb->list_mutex); +} + +SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second) +{ + jb->samples_per_frame = samples_per_frame; + jb->samples_per_second = samples_per_second; + switch_core_inthash_init(&jb->node_hash_ts); +} + +SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session) +{ + const char *var; + + jb->session = session; + jb->channel = switch_core_session_get_channel(session); + + if (jb->type == SJB_VIDEO && (var = switch_channel_get_variable_dup(jb->channel, "jb_video_low_bitrate", SWITCH_FALSE, -1))) { + int tmp = atoi(var); + + if (tmp > 128 && tmp < 10240) { + jb->video_low_bitrate = (uint32_t)tmp; + } + } + +} + +SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag) +{ + switch_set_flag(jb, flag); +} + +SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag) +{ + switch_clear_flag(jb, flag); +} + +SWITCH_DECLARE(int) switch_jb_poll(switch_jb_t *jb) +{ + return (jb->complete_frames >= jb->frame_len); +} + +SWITCH_DECLARE(int) switch_jb_frame_count(switch_jb_t *jb) +{ + return jb->complete_frames; +} + +SWITCH_DECLARE(void) switch_jb_debug_level(switch_jb_t *jb, uint8_t level) +{ + jb->debug_level = level; +} + +SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb) +{ + + if (jb->type == SJB_VIDEO) { + switch_mutex_lock(jb->mutex); + switch_core_inthash_destroy(&jb->missing_seq_hash); + switch_core_inthash_init(&jb->missing_seq_hash); + switch_mutex_unlock(jb->mutex); + + if (jb->session) { + switch_core_session_request_video_refresh(jb->session); + } + } + + jb_debug(jb, 2, "%s", "RESET BUFFER\n"); + + + jb->last_target_seq = 0; + jb->target_seq = 0; + jb->write_init = 0; + jb->highest_wrote_seq = 0; + jb->highest_wrote_ts = 0; + jb->next_seq = 0; + jb->highest_read_ts = 0; + jb->highest_read_seq = 0; + jb->complete_frames = 0; + jb->read_init = 0; + jb->next_seq = 0; + jb->complete_frames = 0; + jb->period_miss_count = 0; + jb->consec_miss_count = 0; + jb->period_miss_pct = 0; + jb->period_good_count = 0; + jb->consec_good_count = 0; + jb->period_count = 0; + jb->period_miss_inc = 0; + jb->target_ts = 0; + jb->last_target_ts = 0; + + switch_mutex_lock(jb->mutex); + hide_nodes(jb); + switch_mutex_unlock(jb->mutex); +} + +SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame) +{ + switch_jb_node_t *node = NULL; + + if (seq) { + uint16_t want_seq = seq + peek; + node = switch_core_inthash_find(jb->node_hash, want_seq); + } else if (ts && jb->samples_per_frame) { + uint32_t want_ts = ts + (peek * jb->samples_per_frame); + node = switch_core_inthash_find(jb->node_hash_ts, want_ts); + } + + if (node) { + frame->seq = ntohs(node->packet.header.seq); + frame->timestamp = ntohl(node->packet.header.ts); + frame->m = node->packet.header.m; + frame->datalen = node->len; + if (frame->data && frame->buflen > node->len) { + memcpy(frame->data, node->packet.body, node->len); + } + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(switch_status_t) switch_jb_get_frames(switch_jb_t *jb, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len) +{ + + switch_mutex_lock(jb->mutex); + + if (min_frame_len) { + *min_frame_len = jb->min_frame_len; + } + + if (max_frame_len) { + *max_frame_len = jb->max_frame_len; + } + + if (cur_frame_len) { + *cur_frame_len = jb->frame_len; + } + + switch_mutex_unlock(jb->mutex); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_jb_set_frames(switch_jb_t *jb, uint32_t min_frame_len, uint32_t max_frame_len) +{ + int lowest = 0; + + switch_mutex_lock(jb->mutex); + + if (jb->frame_len == jb->min_frame_len) lowest = 1; + + jb->min_frame_len = min_frame_len; + jb->max_frame_len = max_frame_len; + + if (jb->frame_len > jb->max_frame_len) { + jb->frame_len = jb->max_frame_len; + } + + if (jb->frame_len < jb->min_frame_len) { + jb->frame_len = jb->min_frame_len; + } + + if (jb->frame_len > jb->highest_frame_len) { + jb->highest_frame_len = jb->frame_len; + } + + if (lowest) { + jb->frame_len = jb->min_frame_len; + } + + switch_mutex_unlock(jb->mutex); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_jb_create(switch_jb_t **jbp, switch_jb_type_t type, + uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool) +{ + switch_jb_t *jb; + int free_pool = 0; + + if (!pool) { + switch_core_new_memory_pool(&pool); + free_pool = 1; + } + + jb = switch_core_alloc(pool, sizeof(*jb)); + jb->free_pool = free_pool; + jb->min_frame_len = jb->frame_len = min_frame_len; + jb->max_frame_len = max_frame_len; + jb->pool = pool; + jb->type = type; + jb->highest_frame_len = jb->frame_len; + + if (jb->type == SJB_VIDEO) { + switch_core_inthash_init(&jb->missing_seq_hash); + } + switch_core_inthash_init(&jb->node_hash); + switch_mutex_init(&jb->mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&jb->list_mutex, SWITCH_MUTEX_NESTED, pool); + + *jbp = jb; + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_jb_destroy(switch_jb_t **jbp) +{ + switch_jb_t *jb = *jbp; + *jbp = NULL; + + if (jb->type == SJB_VIDEO) { + switch_core_inthash_destroy(&jb->missing_seq_hash); + } + switch_core_inthash_destroy(&jb->node_hash); + + if (jb->node_hash_ts) { + switch_core_inthash_destroy(&jb->node_hash_ts); + } + + free_nodes(jb); + + if (jb->free_pool) { + switch_core_destroy_memory_pool(&jb->pool); + } + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb) +{ + switch_hash_index_t *hi = NULL; + uint32_t nack = 0; + uint16_t blp = 0; + uint16_t least = 0; + int i = 0; + void *val; + const void *var; + + if (jb->type != SJB_VIDEO) { + return 0; + } + + switch_mutex_lock(jb->mutex); + + top: + + for (hi = switch_core_hash_first(jb->missing_seq_hash); hi; hi = switch_core_hash_next(&hi)) { + uint16_t seq; + //const char *token; + switch_time_t then = 0; + + switch_core_hash_this(hi, &var, NULL, &val); + //token = (const char *) val; + + //if (token == TOKEN_2) { + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SKIP %u %s\n", ntohs(*((uint16_t *) var)), token); + //printf("WTf\n"); + // continue; + //} + + seq = ntohs(*((uint16_t *) var)); + then = (intptr_t) val; + + if (then != 1 && switch_time_now() - then < RENACK_TIME) { + //jb_debug(jb, 3, "NACKABLE seq %u too soon to repeat\n", seq); + continue; + } + + //if (then != 1) { + // jb_debug(jb, 3, "NACKABLE seq %u not too soon to repeat %lu\n", seq, switch_time_now() - then); + //} + + if (seq < ntohs(jb->target_seq) - jb->frame_len) { + jb_debug(jb, 3, "NACKABLE seq %u expired\n", seq); + switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(seq)); + goto top; + } + + if (!least || seq < least) { + least = seq; + } + } + + if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least))) { + jb_debug(jb, 3, "Found NACKABLE seq %u\n", least); + nack = (uint32_t) htons(least); + switch_core_inthash_insert(jb->missing_seq_hash, nack, (void *) (intptr_t)switch_time_now()); + + for(i = 0; i < 16; i++) { + if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least + i + 1))) { + switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(least + i + 1), (void *)(intptr_t)switch_time_now()); + jb_debug(jb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1); + blp |= (1 << i); + } + } + + blp = htons(blp); + nack |= (uint32_t) blp << 16; + + //jb_frame_inc(jb, 1); + } + + switch_mutex_unlock(jb->mutex); + + + return nack; +} + +SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) +{ + uint32_t i; + uint16_t want = ntohs(jb->next_seq), got = ntohs(packet->header.seq); + + switch_mutex_lock(jb->mutex); + + if (!want) want = got; + + if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO) { + jb->next_seq = htons(got + 1); + } else { + + if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(got))) { + if (got < ntohs(jb->target_seq)) { + jb_debug(jb, 2, "got nacked seq %u too late\n", got); + jb_frame_inc(jb, 1); + } else { + jb_debug(jb, 2, "got nacked %u saved the day!\n", got); + } + } + + if (got > want) { + if (got - want > jb->max_frame_len && got - want > 17) { + jb_debug(jb, 2, "Missing %u frames, Resetting\n", got - want); + switch_jb_reset(jb); + if (jb->session) { + switch_core_session_request_video_refresh(jb->session); + } + } else { + + if (jb->frame_len < got - want) { + jb_frame_inc(jb, 1); + } + + jb_debug(jb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1); + + for (i = want; i < got; i++) { + jb_debug(jb, 2, "MARK MISSING %u ts:%u\n", i, ntohl(packet->header.ts)); + switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i), (void *)(intptr_t)1); + } + } + } + + if (got >= want || (want - got) > 1000) { + jb->next_seq = htons(got + 1); + } + } + + add_node(jb, packet, len); + + if (switch_test_flag(jb, SJB_QUEUE_ONLY) && jb->complete_frames > jb->max_frame_len) { + drop_oldest_frame(jb); + } + + switch_mutex_unlock(jb->mutex); + + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len) +{ + switch_jb_node_t *node; + switch_status_t status = SWITCH_STATUS_NOTFOUND; + + switch_mutex_lock(jb->mutex); + if ((node = switch_core_inthash_find(jb->node_hash, seq))) { + jb_debug(jb, 2, "Found buffered seq: %u\n", ntohs(seq)); + *packet = node->packet; + *len = node->len; + memcpy(packet->body, node->packet.body, node->len); + status = SWITCH_STATUS_SUCCESS; + } else { + jb_debug(jb, 2, "Missing buffered seq: %u\n", ntohs(seq)); + } + switch_mutex_unlock(jb->mutex); + + return status; +} + +SWITCH_DECLARE(switch_size_t) switch_jb_get_last_read_len(switch_jb_t *jb) +{ + return jb->last_len; +} + + +SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len) +{ + switch_jb_node_t *node = NULL; + switch_status_t status; + + switch_mutex_lock(jb->mutex); + + if (jb->complete_frames < jb->frame_len) { + jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len); + switch_goto_status(SWITCH_STATUS_MORE_DATA, end); + } + + jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes); + + if (++jb->period_count >= PERIOD_LEN) { + + if (jb->consec_good_count >= (PERIOD_LEN - 5)) { + jb_frame_inc(jb, -1); + } + + jb->period_count = 1; + jb->period_miss_inc = 0; + jb->period_miss_count = 0; + jb->period_good_count = 0; + jb->consec_miss_count = 0; + jb->consec_good_count = 0; + + if (jb->type == SJB_VIDEO && jb->channel && jb->video_low_bitrate) { + //switch_time_t now = switch_time_now(); + //int ok = (now - jb->last_bitrate_change) > 10000; + + if (switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len == jb->min_frame_len) { + jb_debug(jb, 2, "%s", "Allow BITRATE changes\n"); + switch_channel_clear_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE); + jb->bitrate_control = 0; + if (jb->session) { + switch_core_session_request_video_refresh(jb->session); + } + } else if (!switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len > jb->min_frame_len * 2) { + switch_core_session_message_t msg = { 0 }; + + jb->bitrate_control = jb->video_low_bitrate; + + msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ; + msg.numeric_arg = jb->bitrate_control * 1024; + msg.from = __FILE__; + + jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control); + switch_core_session_receive_message(jb->session, &msg); + switch_channel_set_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE); + if (jb->session) { + switch_core_session_request_video_refresh(jb->session); + } + } + } + + } + + jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100; + + if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) { + jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq)); + + if (!jb->read_init || ntohs(node->packet.header.seq) > ntohs(jb->highest_read_seq) || + (ntohs(jb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) { + jb->highest_read_seq = node->packet.header.seq; + } + + if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) { + jb->complete_frames--; + jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes); + jb->highest_read_ts = node->packet.header.ts; + } else if (!jb->read_init) { + jb->highest_read_ts = node->packet.header.ts; + } + + if (!jb->read_init) jb->read_init = 1; + } else { + if (jb->type == SJB_VIDEO) { + switch_jb_reset(jb); + + switch(status) { + case SWITCH_STATUS_RESTART: + jb_debug(jb, 2, "%s", "Error encountered ask for new keyframe\n"); + switch_goto_status(SWITCH_STATUS_RESTART, end); + case SWITCH_STATUS_NOTFOUND: + default: + jb_debug(jb, 2, "%s", "No frames found wait for more\n"); + switch_goto_status(SWITCH_STATUS_MORE_DATA, end); + } + } else { + switch(status) { + case SWITCH_STATUS_RESTART: + jb_debug(jb, 2, "%s", "Error encountered\n"); + switch_jb_reset(jb); + switch_goto_status(SWITCH_STATUS_RESTART, end); + case SWITCH_STATUS_NOTFOUND: + default: + if (jb->consec_miss_count > jb->frame_len) { + switch_jb_reset(jb); + jb_frame_inc(jb, 1); + jb_debug(jb, 2, "%s", "Too many frames not found, RESIZE\n"); + switch_goto_status(SWITCH_STATUS_RESTART, end); + } else { + jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); + switch_goto_status(SWITCH_STATUS_NOTFOUND, end); + } + } + } + } + + if (node) { + status = SWITCH_STATUS_SUCCESS; + + *packet = node->packet; + *len = node->len; + jb->last_len = *len; + memcpy(packet->body, node->packet.body, node->len); + hide_node(node, SWITCH_TRUE); + + jb_debug(jb, 1, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " " : ""); + + } else { + status = SWITCH_STATUS_MORE_DATA; + } + + end: + + switch_mutex_unlock(jb->mutex); + + if (status == SWITCH_STATUS_SUCCESS && jb->type == SJB_AUDIO) { + if (jb->complete_frames > jb->max_frame_len) { + drop_oldest_frame(jb); + } + } + + return status; + +} + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: + */ diff --git a/src/switch_json.c b/src/switch_json.c index 487843df64..c3c25364da 100644 --- a/src/switch_json.c +++ b/src/switch_json.c @@ -204,7 +204,7 @@ static const char *parse_string(cJSON *item,const char *str) break; default: *ptr2++=*ptr; break; } - ptr++; + if (*ptr) ptr++; } } *ptr2=0; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0b8746ec76..bc3ca09fc9 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -54,7 +54,7 @@ #include #include #include -#include +#include #define JITTER_LEAD_FRAMES 10 #define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++ @@ -310,7 +310,6 @@ struct switch_rtp { uint8_t fir_seq; uint16_t fir_count; uint16_t pli_count; - uint32_t cur_nack; uint32_t cur_tmmbr; uint32_t tmmbr; uint32_t tmmbn; @@ -404,9 +403,9 @@ struct switch_rtp { switch_timer_t timer; uint8_t ready; uint8_t cn; - stfu_instance_t *jb; - switch_vb_t *vb; - switch_vb_t *vbw; + switch_jb_t *jb; + switch_jb_t *vb; + switch_jb_t *vbw; uint32_t max_missed_packets; uint32_t missed_count; rtp_msg_t write_msg; @@ -625,7 +624,7 @@ static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_ } if (rtp_session->jb && (rtp_session->rtp_bugs & RTP_BUG_FLUSH_JB_ON_DTMF)) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } } @@ -896,10 +895,10 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf)); switch_stun_packet_first_attribute(packet, attr); - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG8, "STUN PACKET TYPE: %s\n", - switch_stun_value_to_name(SWITCH_STUN_TYPE_PACKET_TYPE, packet->header.type)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG8, "%s STUN PACKET TYPE: %s\n", + rtp_type(rtp_session), switch_stun_value_to_name(SWITCH_STUN_TYPE_PACKET_TYPE, packet->header.type)); do { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG8, "|---: STUN ATTR %d %x %s\n", attr->type, attr->type, + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG8, "|---: %s STUN ATTR %d %x %s\n", rtp_type(rtp_session), attr->type, attr->type, switch_stun_value_to_name(SWITCH_STUN_TYPE_ATTRIBUTE, attr->type)); switch (attr->type) { @@ -913,18 +912,19 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_stun_error_code_t *err = (switch_stun_error_code_t *) attr->value; uint32_t code = (err->code * 100) + err->number; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "%s got stun binding response %u %s\n", + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "%s got %s stun binding response %u %s\n", rtp_session_name(rtp_session), + rtp_type(rtp_session), code, err->reason ); if ((ice->type & ICE_VANILLA) && code == 487) { if ((ice->type & ICE_CONTROLLED)) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Changing role to CONTROLLING\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "%s STUN Changing role to CONTROLLING\n", rtp_type(rtp_session)); ice->type &= ~ICE_CONTROLLED; } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Changing role to CONTROLLED\n"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "%s STUN Changing role to CONTROLLED\n", rtp_type(rtp_session)); ice->type |= ICE_CONTROLLED; } packet->header.type = SWITCH_STUN_BINDING_RESPONSE; @@ -1078,7 +1078,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, - "ICE Auto Changing port from %s:%u to %s:%u\n", old_host, old, host, port); + "%s ICE Auto Changing port from %s:%u to %s:%u\n", rtp_type(rtp_session), old_host, old, host, port); if (channel) { @@ -1185,9 +1185,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d rtp_session->wrong_addrs = 0; } else { if ((rtp_session->dtls->state != DS_READY || !ice->ready || !ice->rready)) { - if (elapsed > 500 || rtp_session->wrong_addrs > 1) { - do_adj = 1; - } + do_adj++; } else if (rtp_session->wrong_addrs > 5 || elapsed >= 3000) { do_adj++; } @@ -1231,8 +1229,9 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d ice->last_ok = now; rtp_session->wrong_addrs = 0; } - - switch_socket_sendto(sock_output, from_addr, 0, (void *) rpacket, &bytes); + if (cmp) { + switch_socket_sendto(sock_output, from_addr, 0, (void *) rpacket, &bytes); + } } } else if (packet->header.type == SWITCH_STUN_BINDING_ERROR_RESPONSE) { @@ -1895,12 +1894,14 @@ static int using_ice(switch_rtp_t *rtp_session) return 0; } +#define MAX_NACK 10 static int check_rtcp_and_ice(switch_rtp_t *rtp_session) { int ret = 0; int rtcp_ok = 0, rtcp_fb = 0; switch_time_t now = switch_micro_time_now(); - int rate = 0; + int rate = 0, nack_ttl = 0; + uint32_t cur_nack[MAX_NACK] = { 0 }; if (rtp_session->flags[SWITCH_RTP_FLAG_AUTO_CNG] && rtp_session->send_msg.header.ts && rtp_session->cng_pt != INVALID_PT && (rtp_session->timer.samplecount - rtp_session->last_write_samplecount >= rtp_session->samples_per_interval * 60)) { @@ -1921,10 +1922,23 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) rate = rtp_session->rtcp_interval; + if (rtp_session->flags[SWITCH_RTP_FLAG_NACK] && rtp_session->vb) { + int n; + for (n = 0; n < MAX_NACK; n++) { + uint32_t nack = switch_jb_pop_nack(rtp_session->vb); + + if (!nack) break; + + cur_nack[nack_ttl++] = nack; + } + } + + + if (rtp_session->rtcp_sent_packets < 4) { rate = 4000; } else { - if (rtp_session->pli_count || rtp_session->fir_count || rtp_session->cur_nack || rtp_session->tmmbr || rtp_session->tmmbn) { + if (rtp_session->pli_count || rtp_session->fir_count || nack_ttl || rtp_session->tmmbr || rtp_session->tmmbn) { //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "MARK BW/FIR ETC %d %d\n", rtp_session->pli_count, rtp_session->fir_count); rtcp_ok = 1; rtcp_fb = 1; @@ -1941,23 +1955,17 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) if (rtcp_ok && using_ice(rtp_session)) { if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { if (!rtp_session->ice.rready) { - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "FUCK 1\n"); rtcp_ok = 0; } } else { if (!rtp_session->rtcp_ice.rready) { - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "FUCK 2\n"); rtcp_ok = 0; } } } - //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "WTF %d %d %d\n", rate, rtp_session->rtcp_sent_packets, rtcp_ok); + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "WTF %d %d %d %d\n", rate, rtp_session->rtcp_sent_packets, rtcp_ok, nack_ttl); - if (rtp_session->flags[SWITCH_RTP_FLAG_NACK] && rtp_session->vb) { - rtp_session->cur_nack = switch_vb_pop_nack(rtp_session->vb); - } - if (rtp_session->rtcp_sock_output && rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU] && rtcp_ok) { switch_rtcp_numbers_t * stats = &rtp_session->stats.rtcp; struct switch_rtcp_receiver_report *rr; @@ -2031,29 +2039,34 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session) rtp_session->pli_count = 0; } - if (rtp_session->flags[SWITCH_RTP_FLAG_NACK] && rtp_session->cur_nack) { - switch_rtcp_ext_hdr_t *ext_hdr; - uint32_t *nack; - p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes; - ext_hdr = (switch_rtcp_ext_hdr_t *) p; - - ext_hdr->version = 2; - ext_hdr->p = 0; - ext_hdr->fmt = _RTCP_RTPFB_NACK; - ext_hdr->pt = _RTCP_PT_RTPFB; - ext_hdr->send_ssrc = htonl(rtp_session->ssrc); - ext_hdr->recv_ssrc = htonl(rtp_session->remote_ssrc); - ext_hdr->length = htons(3); - p += sizeof(switch_rtcp_ext_hdr_t); - nack = (uint32_t *) p; - *nack = rtp_session->cur_nack; + if (rtp_session->flags[SWITCH_RTP_FLAG_NACK] && nack_ttl > 0) { + int n = 0; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP NACK %u\n", - ntohs(*nack & 0xFFFF)); + for (n = 0; n < nack_ttl; n++) { + switch_rtcp_ext_hdr_t *ext_hdr; + uint32_t *nack; + p = (uint8_t *) (&rtp_session->rtcp_send_msg) + rtcp_bytes; + ext_hdr = (switch_rtcp_ext_hdr_t *) p; + + ext_hdr->version = 2; + ext_hdr->p = 0; + ext_hdr->fmt = _RTCP_RTPFB_NACK; + ext_hdr->pt = _RTCP_PT_RTPFB; + ext_hdr->send_ssrc = htonl(rtp_session->ssrc); + ext_hdr->recv_ssrc = htonl(rtp_session->remote_ssrc); + ext_hdr->length = htons(3); + p += sizeof(switch_rtcp_ext_hdr_t); + nack = (uint32_t *) p; + *nack = cur_nack[n]; + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP NACK %u\n", + ntohs(*nack & 0xFFFF)); - rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t) + sizeof(rtp_session->cur_nack); + rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t) + sizeof(cur_nack[n]); + cur_nack[n] = 0; + } - rtp_session->cur_nack = 0; + nack_ttl = 0; } if (rtp_session->fir_count) { @@ -2710,10 +2723,10 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session) if (rtp_session->ice.ready) { if (rtp_session->vb) { - switch_vb_reset(rtp_session->vb); + switch_jb_reset(rtp_session->vb); } if (rtp_session->vbw) { - switch_vb_reset(rtp_session->vbw); + switch_jb_reset(rtp_session->vbw); } rtp_session->ice.ready = rtp_session->ice.rready = 0; } @@ -3148,15 +3161,15 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_del_dtls(switch_rtp_t *rtp_session, d } if (rtp_session->jb) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } if (rtp_session->vb) { - switch_vb_reset(rtp_session->vb); + switch_jb_reset(rtp_session->vb); } if (rtp_session->vbw) { - switch_vb_reset(rtp_session->vbw); + switch_jb_reset(rtp_session->vbw); } } @@ -3245,7 +3258,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d dtls->ca = switch_core_sprintf(rtp_session->pool, "%s%sca-bundle.crt", SWITCH_GLOBAL_dirs.certs_dir, SWITCH_PATH_SEPARATOR); - dtls->ssl_ctx = SSL_CTX_new(DTLSv1_method()); + dtls->ssl_ctx = SSL_CTX_new((type & DTLS_TYPE_SERVER) ? DTLSv1_server_method() : DTLSv1_client_method()); switch_assert(dtls->ssl_ctx); bio = BIO_new_file(dtls->pem, "r"); @@ -3718,8 +3731,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Starting video timer.\n"); } - //switch_vb_create(&rtp_session->vb, 3, 10, rtp_session->pool); - //switch_vb_debug_level(rtp_session->vb, 10); + //switch_jb_create(&rtp_session->vb, 3, 10, rtp_session->pool); + //switch_jb_debug_level(rtp_session->vb, 10); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Not using a timer\n"); @@ -3909,27 +3922,6 @@ SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_pay rtp_session->flags[SWITCH_RTP_FLAG_AUTO_CNG] = 1; } -static void jb_callback(stfu_instance_t *i, void *udata) -{ - switch_core_session_t *session = (switch_core_session_t *) udata; - stfu_report_t r = { 0 }; - - stfu_n_report(i, &r); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG8, - "%s JB REPORT:\nlen: %u\nin: %u\nclean: %u\ngood: %u\nbad: %u\njitter percent %0.2f\nmissing percent %0.2f\n\n", - switch_core_session_get_name(session), - r.qlen, - r.packet_in_count, - r.clean_count, - r.consecutive_good_count, - r.consecutive_bad_count, - r.period_jitter_percent, - r.period_missing_percent - ); - -} - SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_session) { @@ -3944,7 +3936,7 @@ SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_se } -SWITCH_DECLARE(stfu_instance_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session) +SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session) { if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) { return NULL; @@ -3965,7 +3957,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp } if (rtp_session->pause_jb && !pause) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } rtp_session->pause_jb = pause ? 1 : 0; @@ -3985,48 +3977,35 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t return SWITCH_STATUS_SUCCESS; } -static void jb_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) +SWITCH_DECLARE(switch_status_t) switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_session, uint32_t *min_frame_len, uint32_t *max_frame_len, uint32_t *cur_frame_len, uint32_t *highest_frame_len) { - int ret; - char *data; - va_list ap; - - va_start(ap, fmt); - ret = switch_vasprintf(&data, fmt, ap); - if (ret != -1) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%d: %s", line, data); - free(data); - } - - //switch_log_printf(SWITCH_CHANNEL_ID_LOG_CLEAN, file, func, line, NULL, level, fmt, ap); - va_end(ap); -} - -SWITCH_DECLARE(uint32_t) switch_rtp_get_video_buffer_size(switch_rtp_t *rtp_session) -{ - uint32_t frames = 0; - + if (rtp_session->vb) { - switch_vb_get_frames(rtp_session->vb, &frames, NULL); + return switch_jb_get_frames(rtp_session->vb, min_frame_len, max_frame_len, cur_frame_len, highest_frame_len); } - return frames; + return SWITCH_STATUS_FALSE; } -SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *rtp_session, uint32_t frames) +SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *rtp_session, uint32_t frames, uint32_t max_frames) { if (!switch_rtp_ready(rtp_session)) { return SWITCH_STATUS_FALSE; } - if (!rtp_session->vb) { - switch_vb_create(&rtp_session->vb, frames, frames * 3, rtp_session->pool); + if (!max_frames) { + max_frames = 30; + } + + if (!rtp_session->vb) { + switch_jb_create(&rtp_session->vb, SJB_VIDEO, frames, max_frames, rtp_session->pool); + switch_jb_set_session(rtp_session->vb, rtp_session->session); } else { - switch_vb_set_frames(rtp_session->vb, frames, frames * 3); + switch_jb_set_frames(rtp_session->vb, frames, max_frames); } //switch_rtp_flush(rtp_session); - //switch_core_session_request_video_refresh(rtp_session->session); + switch_core_session_request_video_refresh(rtp_session->session); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Setting video buffer %u Frames.\n", frames); @@ -4035,22 +4014,19 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp_session, const char *name) { + int x = 0; if (!switch_rtp_ready(rtp_session)) { return SWITCH_STATUS_FALSE; } + + if (name) x = atoi(name); + if (x < 0) x = 0; if (rtp_session->jb) { - stfu_n_debug(rtp_session->jb, name); - stfu_global_set_logger(jb_logger); + switch_jb_debug_level(rtp_session->jb, x); } else if (rtp_session->vb) { - int x = 0; - - if (name) x = atoi(name); - if (x < 0) x = 0; - - switch_vb_debug_level(rtp_session->vb, x); - + switch_jb_debug_level(rtp_session->vb, x); } return SWITCH_STATUS_SUCCESS; @@ -4060,9 +4036,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * uint32_t queue_frames, uint32_t max_queue_frames, uint32_t samples_per_packet, - uint32_t samples_per_second, - uint32_t max_drift) + uint32_t samples_per_second) { + switch_status_t status = SWITCH_STATUS_FALSE; if (!switch_rtp_ready(rtp_session)) { return SWITCH_STATUS_FALSE; @@ -4079,21 +4055,17 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * READ_INC(rtp_session); if (rtp_session->jb) { - stfu_n_destroy(&rtp_session->jb); + status = switch_jb_set_frames(rtp_session->jb, queue_frames, max_queue_frames); + } else { + status = switch_jb_create(&rtp_session->jb, SJB_AUDIO, queue_frames, max_queue_frames, rtp_session->pool); + switch_jb_set_session(rtp_session->jb, rtp_session->session); + switch_jb_ts_mode(rtp_session->jb, samples_per_packet, samples_per_second); + //switch_jb_debug_level(rtp_session->jb, 10); } - rtp_session->jb = stfu_n_init(queue_frames, max_queue_frames, samples_per_packet, samples_per_second, max_drift); - READ_DEC(rtp_session); - if (rtp_session->jb) { - - stfu_n_call_me(rtp_session->jb, jb_callback, rtp_session->session); - - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_FALSE; + return status; } SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port, switch_bool_t mux) @@ -4415,15 +4387,15 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session) } if ((*rtp_session)->jb) { - stfu_n_destroy(&(*rtp_session)->jb); + switch_jb_destroy(&(*rtp_session)->jb); } if ((*rtp_session)->vb) { - switch_vb_destroy(&(*rtp_session)->vb); + switch_jb_destroy(&(*rtp_session)->vb); } if ((*rtp_session)->vbw) { - switch_vb_destroy(&(*rtp_session)->vbw); + switch_jb_destroy(&(*rtp_session)->vbw); } if ((*rtp_session)->dtls && (*rtp_session)->dtls == (*rtp_session)->rtcp_dtls) { @@ -4623,7 +4595,7 @@ SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_f if (rtp_session->jb) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } } else if (flag == SWITCH_RTP_FLAG_NOBLOCK && rtp_session->sock_input) { switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE); @@ -4898,15 +4870,15 @@ static void do_flush(switch_rtp_t *rtp_session, int force) if (switch_rtp_ready(rtp_session) ) { if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } //if (rtp_session->vb) { - // switch_vb_reset(rtp_session->vb); + // switch_jb_reset(rtp_session->vb); //} if (rtp_session->vbw) { - switch_vb_reset(rtp_session->vbw); + switch_jb_reset(rtp_session->vbw); } if (rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]) { @@ -4949,13 +4921,6 @@ static void do_flush(switch_rtp_t *rtp_session, int force) } } while (bytes > 0); -#if 0 - if (rtp_session->jb && flushed) { - stfu_n_sync(rtp_session->jb, flushed); - reset_jitter_seq(rtp_session); - } -#endif - if (was_blocking && switch_rtp_ready(rtp_session)) { switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK); switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE); @@ -5003,7 +4968,6 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t switch_status_t poll_status, switch_bool_t return_jb_packet) { switch_status_t status = SWITCH_STATUS_FALSE; - stfu_frame_t *jb_frame; uint32_t ts = 0; unsigned char *b = NULL; int sync = 0; @@ -5430,27 +5394,38 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->flags[SWITCH_RTP_FLAG_KILL_JB]) { rtp_session->flags[SWITCH_RTP_FLAG_KILL_JB] = 0; + if (rtp_session->jb) { - stfu_n_destroy(&rtp_session->jb); + switch_jb_destroy(&rtp_session->jb); + } + + if (rtp_session->vb) { + switch_jb_destroy(&rtp_session->vb); } } if (rtp_session->recv_msg.header.version == 2 && *bytes) { - if (rtp_session->vb) { - switch_vb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); + if (rtp_session->vb && jb_valid(rtp_session)) { + switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); status = SWITCH_STATUS_FALSE; *bytes = 0; + + if (!return_jb_packet) { + return status; + } } if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); + if (rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te && !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } else if (rtp_session->last_jb_read_ssrc && rtp_session->last_jb_read_ssrc != read_ssrc) { - stfu_n_reset(rtp_session->jb); + switch_jb_reset(rtp_session->jb); } + rtp_session->last_jb_read_ssrc = read_ssrc; if (!rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval) { @@ -5458,13 +5433,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t reset_jitter_seq(rtp_session); } - if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts, - ntohs((uint16_t) rtp_session->recv_msg.header.seq), - rtp_session->recv_msg.header.pt, - RTP_BODY(rtp_session), *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) { - - goto more; - } + switch_jb_put_packet(rtp_session->jb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); status = SWITCH_STATUS_FALSE; *bytes = 0; @@ -5472,41 +5441,46 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (!return_jb_packet) { return status; } - } } if (!*bytes || rtp_session->recv_msg.header.version == 2) { - + if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { - if ((jb_frame = stfu_n_read_a_frame(rtp_session->jb))) { - memcpy(RTP_BODY(rtp_session), jb_frame->data, jb_frame->dlen); + switch_status_t jstatus = switch_jb_get_packet(rtp_session->jb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); - if (jb_frame->plc) { + status = jstatus; + + switch(jstatus) { + case SWITCH_STATUS_MORE_DATA: + status = SWITCH_STATUS_BREAK; + break; + case SWITCH_STATUS_NOTFOUND: + { (*flags) |= SFF_PLC; - } else { + status = SWITCH_STATUS_SUCCESS; + rtp_session->recv_msg.header = rtp_session->last_rtp_hdr; + *bytes = switch_jb_get_last_read_len(rtp_session->jb); + } + break; + case SWITCH_STATUS_SUCCESS: + default: + { rtp_session->stats.inbound.jb_packet_count++; + status = SWITCH_STATUS_SUCCESS; + rtp_session->last_rtp_hdr = rtp_session->recv_msg.header; + + if (!xcheck_jitter) { + check_jitter(rtp_session); + xcheck_jitter = *bytes; + } } - *bytes = jb_frame->dlen + rtp_header_len; - rtp_session->recv_msg.header.version = 2; - rtp_session->recv_msg.header.x = 0; - rtp_session->recv_msg.header.ts = htonl(jb_frame->ts); - rtp_session->recv_msg.header.pt = jb_frame->pt; - rtp_session->recv_msg.header.seq = htons(jb_frame->seq); - rtp_session->recv_msg.header.ssrc = ntohl(rtp_session->remote_ssrc); - rtp_session->last_rtp_hdr = rtp_session->recv_msg.header; - status = SWITCH_STATUS_SUCCESS; - - if (!xcheck_jitter) { - check_jitter(rtp_session); - xcheck_jitter = *bytes; - } - + break; } } - - if (rtp_session->vb) { - switch_status_t vstatus = switch_vb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); + + if (rtp_session->vb && jb_valid(rtp_session)) { + switch_status_t vstatus = switch_jb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); status = vstatus; switch(vstatus) { @@ -5560,7 +5534,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Got NACK [%u][0x%x] for seq %u\n", nack, nack, ntohs(seq)); - if (switch_vb_get_packet_by_seq(rtp_session->vbw, seq, (switch_rtp_packet_t *) send_msg, &bytes) == SWITCH_STATUS_SUCCESS) { + if (switch_jb_get_packet_by_seq(rtp_session->vbw, seq, (switch_rtp_packet_t *) send_msg, &bytes) == SWITCH_STATUS_SUCCESS) { if (rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(rtp_session->session), SWITCH_LOG_CONSOLE, @@ -5585,7 +5559,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Also Got NACK for seq %u\n", ntohs(seq) + i + 1); /* If they are missing more than one, may as well gen a key frame for good measure */ switch_core_media_gen_key_frame(rtp_session->session); - if (switch_vb_get_packet_by_seq(rtp_session->vbw, htons(ntohs(seq) + i + 1), (switch_rtp_packet_t *) &send_msg, &bytes) == SWITCH_STATUS_SUCCESS) { + if (switch_jb_get_packet_by_seq(rtp_session->vbw, htons(ntohs(seq) + i + 1), (switch_rtp_packet_t *) &send_msg, &bytes) == SWITCH_STATUS_SUCCESS) { if (rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(rtp_session->session), SWITCH_LOG_CONSOLE, "X %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u seq=%u m=%d\n", @@ -5624,7 +5598,7 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t if (msg->header.type == _RTCP_PT_PSFB && (extp->header.fmt == _RTCP_PSFB_FIR || extp->header.fmt == _RTCP_PSFB_PLI)) { switch_core_media_gen_key_frame(rtp_session->session); if (rtp_session->vbw) { - switch_vb_reset(rtp_session->vbw); + switch_jb_reset(rtp_session->vbw); } } @@ -5708,7 +5682,7 @@ static switch_status_t process_rtcp_report(switch_rtp_t *rtp_session, rtcp_msg_t } if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->rtcp_frame.reports[i].loss_avg != old_avg) { - switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT, (void *)&rtp_session->rtcp_frame.reports[i].loss_avg, NULL, NULL); + switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_IO_WRITE, SCC_AUDIO_PACKET_LOSS, SCCT_INT, (void *)&rtp_session->rtcp_frame.reports[i].loss_avg, SCCT_NONE, NULL, NULL, NULL); } rtp_session->rtcp_frame.reports[i].ssrc = ntohl(report->ssrc); @@ -5976,11 +5950,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ read_pretriggered = 0; goto rtcp; } - - if (status != SWITCH_STATUS_FALSE) { - read_pretriggered = 1; - break; - } + + //if (status != SWITCH_STATUS_FALSE) { + // read_pretriggered = 1; + // break; + //} } } else if ((rtp_session->flags[SWITCH_RTP_FLAG_AUTOFLUSH] || rtp_session->flags[SWITCH_RTP_FLAG_STICKY_FLUSH])) { @@ -6098,7 +6072,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } if (rtp_session->vb) { - if (switch_vb_poll(rtp_session->vb)) { + if (switch_jb_poll(rtp_session->vb)) { pt = 0; } } @@ -6124,7 +6098,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } - if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && switch_vb_poll(rtp_session->vb))) { + if (poll_status == SWITCH_STATUS_SUCCESS || (rtp_session->vb && switch_jb_poll(rtp_session->vb))) { got_rtp_poll = 1; @@ -7050,8 +7024,8 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } } - /* TMP DISABLE DFF */ - if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { + + if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA) || switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { /* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base so if the timestamps and ssrc of the source change, it will not break the other end's jitter bufffer / decoder etc *cough* CHROME *cough* */ @@ -7061,33 +7035,34 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } if (!rtp_session->ts_norm.last_ssrc || send_msg->header.ssrc != rtp_session->ts_norm.last_ssrc) { - //#define USE_DELTA -#ifdef USE_DELTA - if (rtp_session->ts_norm.last_ssrc) { - rtp_session->ts_norm.delta_ct = 1; - rtp_session->ts_norm.delta_ttl = 0; - if (rtp_session->ts_norm.delta) { - rtp_session->ts_norm.ts += rtp_session->ts_norm.delta; + if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) { + if (rtp_session->ts_norm.last_ssrc) { + rtp_session->ts_norm.delta_ct = 1; + rtp_session->ts_norm.delta_ttl = 0; + if (rtp_session->ts_norm.delta) { + rtp_session->ts_norm.ts += rtp_session->ts_norm.delta; + } } } -#endif + rtp_session->ts_norm.last_ssrc = send_msg->header.ssrc; rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts); } if (ntohl(send_msg->header.ts) != rtp_session->ts_norm.last_frame) { -#ifdef USE_DELTA - int32_t delta = (int32_t) (ntohl(send_msg->header.ts) - rtp_session->ts_norm.last_frame); - if (delta > 0 && delta < 90000) { - rtp_session->ts_norm.delta = delta; + if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA)) { + int32_t delta = (int32_t) (ntohl(send_msg->header.ts) - rtp_session->ts_norm.last_frame); + + if (switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && delta > 0 && delta < 90000) { + rtp_session->ts_norm.delta = delta; + } + + rtp_session->ts_norm.ts += rtp_session->ts_norm.delta; + } else { + switch_core_timer_sync(&rtp_session->timer); + rtp_session->ts_norm.ts = rtp_session->timer.samplecount; } - //printf("WTF %d\n", rtp_session->ts_norm.delta); - rtp_session->ts_norm.ts += rtp_session->ts_norm.delta; -#else - switch_core_timer_sync(&rtp_session->timer); - rtp_session->ts_norm.ts = rtp_session->timer.samplecount; -#endif } rtp_session->ts_norm.last_frame = ntohl(send_msg->header.ts); @@ -7329,10 +7304,13 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (rtp_session->flags[SWITCH_RTP_FLAG_NACK]) { if (!rtp_session->vbw) { - switch_vb_create(&rtp_session->vbw, 10, 10, rtp_session->pool); - //switch_vb_debug_level(rtp_session->vbw, 10); + switch_jb_create(&rtp_session->vbw, SJB_VIDEO, 30, 30, rtp_session->pool); + if (rtp_session->vbw) { + switch_jb_set_flag(rtp_session->vbw, SJB_QUEUE_ONLY); + //switch_jb_debug_level(rtp_session->vbw, 10); + } } - switch_vb_push_packet(rtp_session->vbw, (switch_rtp_packet_t *)send_msg, bytes); + switch_jb_put_packet(rtp_session->vbw, (switch_rtp_packet_t *)send_msg, bytes); } #ifdef RTP_WRITE_PLOSS @@ -7689,7 +7667,7 @@ SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_sess } if (rtp_session->jb) { - s->inbound.largest_jb_size = stfu_n_get_most_qlen(rtp_session->jb); + switch_jb_get_frames(rtp_session->jb, NULL, NULL, NULL, (uint32_t *)&s->inbound.largest_jb_size); } do_mos(rtp_session, SWITCH_FALSE); diff --git a/src/switch_stfu.c b/src/switch_stfu.c deleted file mode 100644 index 13df191ca0..0000000000 --- a/src/switch_stfu.c +++ /dev/null @@ -1,1173 +0,0 @@ -/* - * STFU (S)ort (T)ransportable (F)ramed (U)tterances - * Copyright (c) 2007-2014 Anthony Minessale II - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * THOSE WHO DISAGREE MAY CERTAINLY STFU - */ - -#include "switch.h" -#include "switch_stfu.h" - -//#define DB_JB 1 - -#define DBG_IN 1 -#define DBG_OUT 2 - -#ifndef UINT_MAX -# define UINT_MAX 4294967295U -#endif - -#ifndef UINT16_MAX -# define UINT16_MAX 65535 -#endif - -#ifdef _MSC_VER -/* warning C4706: assignment within conditional expression*/ -#pragma warning(disable: 4706) -/* warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details. */ -#pragma warning(disable:4996) -#endif - -#define least1(_z) (_z ? _z : 1) - -#define PERIOD_SECONDS 20 -#define PERIOD_JITTER_TOLERANCE 5.0f - -static int stfu_log_level = 7; - -struct stfu_queue { - struct stfu_frame *array; - struct stfu_frame int_frame; - uint32_t real_array_size; - uint32_t array_size; - uint32_t array_len; - uint32_t wr_len; - uint32_t last_index; - int32_t last_jitter; -}; -typedef struct stfu_queue stfu_queue_t; - -struct stfu_instance { - struct stfu_queue a_queue; - struct stfu_queue b_queue; - struct stfu_queue c_queue; - struct stfu_queue *in_queue; - struct stfu_queue *out_queue; - struct stfu_queue *old_queue; - struct stfu_frame *last_frame; - uint32_t cur_ts; - uint16_t cur_seq; - uint32_t last_wr_ts; - uint32_t last_rd_ts; - uint32_t ms_per_packet; - uint32_t samples_per_packet; - uint32_t samples_per_second; - uint32_t miss_count; - uint32_t qlen; - uint32_t most_qlen; - uint32_t max_qlen; - uint32_t orig_qlen; - uint32_t packet_count; - uint32_t consecutive_good_count; - uint32_t consecutive_bad_count; - uint32_t period_good_count; - uint32_t period_bad_count; - uint32_t period_packet_in_count; - uint32_t period_packet_out_count; - uint32_t period_missing_count; - - uint32_t period_need_range; - uint32_t period_need_range_avg; - uint32_t period_clean_count; - uint32_t period_jitter_count; - double period_jitter_percent; - double period_missing_percent; - uint32_t period_jitter_size_time; - uint32_t period_jitter_size_ts; - uint32_t period_jitter_size; - - uint32_t session_clean_count; - uint32_t session_missing_count; - - uint32_t session_packet_in_count; - uint32_t session_packet_out_count; - - uint32_t sync_out; - uint32_t sync_in; - - int32_t ts_offset; - int32_t ts_drift; - int32_t max_drift; - uint32_t drift_dropped_packets; - uint32_t drift_max_dropped; - uint32_t consecutive_drift; - - int32_t ts_diff; - int32_t last_ts_diff; - int32_t same_ts; - - uint32_t last_ts_skew; - uint32_t last_time_skew; - - uint32_t period_time; - - uint32_t plc_len; - uint32_t plc_pt; - uint32_t diff; - uint32_t diff_total; - uint8_t ready; - uint8_t debug; - - switch_time_t last_clock_ts; - - char *name; - stfu_n_call_me_t callback; - void *udata; -}; - -static void stfu_n_reset_counters(stfu_instance_t *i); -static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...); -static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...); - -stfu_logger_t stfu_log = null_logger; - -int32_t stfu_n_get_drift(stfu_instance_t *i) -{ - return i->ts_drift; -} - -int32_t stfu_n_get_most_qlen(stfu_instance_t *i) -{ - return i->most_qlen; -} - -void stfu_global_set_logger(stfu_logger_t logger) -{ - if (logger) { - stfu_log = logger; - } else { - stfu_log = null_logger; - } -} - -void stfu_global_set_default_logger(int level) -{ - if (level < 0 || level > 7) { - level = 7; - } - - stfu_log = default_logger; - stfu_log_level = level; -} - - - -static stfu_status_t stfu_n_resize_aqueue(stfu_queue_t *queue, uint32_t qlen) -{ - struct stfu_frame *m; - - if (qlen <= queue->real_array_size) { - queue->array_size = qlen; - if (queue->array_len > qlen) { - queue->array_len = qlen; - } - } else { - m = realloc(queue->array, qlen * sizeof(struct stfu_frame)); - assert(m); - memset(m + queue->array_size, 0, (qlen - queue->array_size) * sizeof(struct stfu_frame)); - queue->array = m; - queue->real_array_size = queue->array_size = qlen; - } - - return STFU_IT_WORKED; -} - -static void stfu_n_init_aqueue(stfu_queue_t *queue, uint32_t qlen) -{ - - queue->array = calloc(qlen, sizeof(struct stfu_frame)); - assert(queue->array != NULL); - memset(queue->array, 0, sizeof(struct stfu_frame) * qlen); - queue->real_array_size = queue->array_size = qlen; - queue->int_frame.plc = 1; - memset(queue->int_frame.data, 255, sizeof(queue->int_frame.data)); -} - - -void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata) -{ - i->callback = callback; - i->udata = udata; -} - -void stfu_n_destroy(stfu_instance_t **i) -{ - stfu_instance_t *ii; - - if (i && *i) { - ii = *i; - *i = NULL; - if (ii->name) free(ii->name); - free(ii->a_queue.array); - free(ii->b_queue.array); - free(ii->c_queue.array); - free(ii); - } -} - -void stfu_n_debug(stfu_instance_t *i, const char *name) -{ - if (i->name) free(i->name); - - if (name) { - int debug = 0; - - if (strstr(name, ":out")) { - debug |= DBG_OUT; - } - - if (strstr(name, ":in")) { - debug |= DBG_IN; - } - - if (debug) i->debug = (uint8_t)debug; - else i->debug = 3; - - i->name = strdup(name); - } else { - i->name = strdup("none"); - i->debug = 0; - } -} - -void stfu_n_report(stfu_instance_t *i, stfu_report_t *r) -{ - stfu_assert(i); - r->qlen = i->qlen; - r->packet_in_count = i->period_packet_in_count; - r->clean_count = i->period_clean_count; - r->consecutive_good_count = i->consecutive_good_count; - r->consecutive_bad_count = i->consecutive_bad_count; - r->period_jitter_percent = i->period_jitter_percent; - r->period_missing_percent = i->period_missing_percent; -} - -stfu_status_t stfu_n_auto_size(stfu_instance_t *i, int check_down) -{ - stfu_status_t r = STFU_IT_FAILED; - uint32_t len; - - if (!i->ms_per_packet) { - return r; - } - - len = i->period_jitter_size / i->ms_per_packet; - - if (len > i->qlen || (check_down && len < i->qlen)) { - if (check_down) { - len = i->qlen - 1; - } - r = stfu_n_resize(i, len); - } - - return r; -} - -stfu_status_t _stfu_n_resize(stfu_instance_t *i, uint32_t qlen, int line) -{ - stfu_status_t s; - int diff; - - if (qlen == i->qlen) { - return STFU_IT_FAILED; - } - - if (qlen < i->orig_qlen) { - qlen = i->orig_qlen; - } else if (i->max_qlen && qlen >= (int32_t)i->max_qlen) { - if (i->qlen < i->max_qlen) { - qlen = i->max_qlen; - } else { - return STFU_IT_FAILED; - } - } - - diff = qlen - i->qlen; - - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%d %s resize %s %u %u\n", line, i->name, diff > 0 ? "up" : "down", i->qlen, i->qlen + diff); - } - - if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) { - stfu_n_resize_aqueue(&i->b_queue, qlen); - s = stfu_n_resize_aqueue(&i->c_queue, qlen); - - if (qlen > (int32_t)i->most_qlen) { - i->most_qlen = qlen; - } - - i->qlen = qlen; - i->last_frame = NULL; - } - - return s; -} - -stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second, uint32_t max_drift_ms) -{ - struct stfu_instance *i; - - i = malloc(sizeof(*i)); - if (!i) { - return NULL; - } - memset(i, 0, sizeof(*i)); - - i->qlen = qlen; - i->max_qlen = max_qlen; - i->orig_qlen = qlen; - i->samples_per_packet = samples_per_packet; - - stfu_n_init_aqueue(&i->a_queue, qlen); - stfu_n_init_aqueue(&i->b_queue, qlen); - stfu_n_init_aqueue(&i->c_queue, qlen); - - i->max_drift = (int32_t)(max_drift_ms * (samples_per_second / 1000) * -1); - - if (max_drift_ms && samples_per_packet) { - i->drift_max_dropped = (samples_per_second * 2) / samples_per_packet; - } - - i->in_queue = &i->a_queue; - i->out_queue = &i->b_queue; - i->old_queue = &i->c_queue; - i->name = strdup("none"); - - i->samples_per_second = samples_per_second ? samples_per_second : 8000; - - i->period_time = ((i->samples_per_second * PERIOD_SECONDS) / i->samples_per_packet); - - return i; -} - -static void stfu_n_reset_counters(stfu_instance_t *i) -{ - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s COUNTER RESET........\n", i->name); - } - - - - if (i->callback) { - i->callback(i, i->udata); - } - - i->consecutive_good_count = 0; - i->consecutive_bad_count = 0; - i->period_good_count = 0; - i->period_clean_count = 0; - i->period_bad_count = 0; - i->period_packet_in_count = 0; - i->period_packet_out_count = 0; - i->period_missing_count = 0; - i->period_jitter_count = 0; - - i->period_jitter_size_time = 0; - i->period_jitter_size_ts = 0; - i->period_jitter_size = 0; - - i->period_need_range = 0; - i->period_need_range_avg = 0; - - i->diff = 0; - i->diff_total = 0; - -} - -void _stfu_n_reset(stfu_instance_t *i, const char *file, const char *func, int line) -{ - if (stfu_log != null_logger && i->debug) { - stfu_log(file, func, line, STFU_LOG_LEVEL_EMERG, "%s RESET\n", i->name); - } - - i->ready = 0; - i->in_queue = &i->a_queue; - i->out_queue = &i->b_queue; - i->old_queue = &i->c_queue; - - i->in_queue->array_len = 0; - i->out_queue->array_len = 0; - i->out_queue->wr_len = 0; - i->last_frame = NULL; - i->in_queue->last_jitter = 0; - i->out_queue->last_jitter = 0; - - - stfu_n_reset_counters(i); - stfu_n_sync(i, 1); - - i->cur_ts = 0; - i->cur_seq = 0; - i->last_wr_ts = 0; - i->last_rd_ts = 0; - i->miss_count = 0; - i->packet_count = 0; - i->ts_offset = 0; - i->ts_drift = 0; - i->consecutive_drift = 0; -} - -stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets) -{ - - if (packets > i->qlen) { - stfu_n_reset(i); - } else { - i->sync_out = packets; - i->sync_in = packets; - } - - return STFU_IT_WORKED; -} - - -static void stfu_n_swap(stfu_instance_t *i) -{ - stfu_queue_t *last_in = i->in_queue, *last_out = i->out_queue, *last_old = i->old_queue; - - i->ready = 1; - - i->in_queue = last_old; - i->out_queue = last_in; - i->old_queue = last_out; - - i->in_queue->array_len = 0; - i->out_queue->wr_len = 0; - i->last_frame = NULL; - i->miss_count = 0; - i->in_queue->last_index = 0; - i->out_queue->last_index = 0; - i->out_queue->last_jitter = 0; -} - -stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last) -{ - uint32_t index = 0; - stfu_frame_t *frame; - size_t cplen = 0; - int good_ts = 0; - int32_t diff; - switch_time_t now; - - - i->ts_diff = ts - i->last_rd_ts; - - if (!i->samples_per_packet && ts && i->last_rd_ts) { - if (i->last_ts_diff == i->ts_diff) { - if (++i->same_ts == 5) { - i->samples_per_packet = i->ts_diff; - if (i->max_drift && i->samples_per_packet) { - i->drift_max_dropped = (i->samples_per_second * 2) / i->samples_per_packet; - } - } - } else { - i->same_ts = 0; - } - - if (!i->samples_per_packet) { - i->last_rd_ts = ts; - return STFU_IT_FAILED; - } - } - - i->last_ts_diff = i->ts_diff; - - if (!i->ms_per_packet) { - i->ms_per_packet = 1000 / (i->samples_per_second / i->samples_per_packet); - } - - now = switch_micro_time_now(); - - if (i->last_clock_ts) { - diff = (uint32_t) ((now - i->last_clock_ts) / 1000); - } else { - diff = 0; - } - - i->last_clock_ts = now; - - if (diff && i->ms_per_packet) { - i->last_time_skew = abs((int)(diff - (int)i->ms_per_packet)); - } - - if (i->last_ts_diff && i->samples_per_packet) { - i->last_ts_skew = abs((int)(i->last_ts_diff - (int)i->samples_per_packet)); - } - - if (i->ready && i->out_queue->array_len && (i->last_time_skew > 1 || i->last_ts_skew)) { - uint32_t time_ms = i->last_time_skew, ts_ms = (i->last_ts_skew / i->samples_per_packet) * i->ms_per_packet; - - if (time_ms > i->period_jitter_size_time) { - i->period_jitter_size_time = time_ms; - } - - if (ts_ms > i->period_jitter_size_ts) { - i->period_jitter_size_ts = ts_ms; - } - - if (i->period_jitter_size_time > i->period_jitter_size_ts) { - i->period_jitter_size = i->period_jitter_size_time; - } else { - i->period_jitter_size = i->period_jitter_size_ts; - } - - if (++i->period_jitter_count > 5) { - stfu_n_auto_size(i, 0); - } - } - - if (timer_ts && i->ready && i->out_queue->array_len) { - if (ts && !i->ts_offset) { - i->ts_offset = timer_ts - ts; - } - - if (i->ts_offset) { - i->ts_drift = ts + (i->ts_offset - timer_ts); - - if (i->ts_drift > 0) { - i->ts_offset = timer_ts - ts; - i->ts_drift = ts + (i->ts_offset - timer_ts); - } - - if (i->ts_drift) { - i->consecutive_drift++; - } else { - i->consecutive_drift = 0; - } - } - - - if (i->max_drift && i->consecutive_drift >= 10) { - if (i->ts_drift < i->max_drift) { - if (++i->drift_dropped_packets < i->drift_max_dropped) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); - } - stfu_n_reset(i); - //stfu_n_resize(i, 1); - //stfu_n_sync(i, 1); - //return STFU_ITS_TOO_LATE; - } - } else { - i->drift_dropped_packets = 0; - } - } - } - - if (i->sync_in) { - good_ts = 1; - i->sync_in = 0; - } else { - - if ((ts && ts == i->last_rd_ts + i->samples_per_packet) || (i->last_rd_ts > 4294900000u && ts < 5000)) { - good_ts = 1; - } - - if (i->last_wr_ts) { - if ((ts <= i->last_wr_ts && (i->last_wr_ts != UINT_MAX || ts == i->last_wr_ts))) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); - } - //stfu_n_resize(i, i->qlen + 1); - return STFU_ITS_TOO_LATE; - } - } - } - - if (good_ts) { - i->period_clean_count++; - i->session_clean_count++; - } - - i->period_packet_in_count++; - i->session_packet_in_count++; - - i->period_need_range_avg = i->period_need_range / least1(i->period_missing_count); - - //if (i->period_missing_count > i->qlen * 2) { - //stfu_n_resize(i, 1); - //} - - i->diff = 0; - - if (i->last_wr_ts) { - if (ts < 1000 && i->last_wr_ts > (UINT_MAX - 1000)) { - i->diff = abs((int)(((UINT_MAX - i->last_wr_ts) + ts) / i->samples_per_packet)); - } else if (ts) { - i->diff = abs((int)(i->last_wr_ts - ts)) / i->samples_per_packet; - } - } - - i->diff_total += i->diff; - - i->period_jitter_percent = (double)(((double)i->period_jitter_count / (double)i->period_time) * 100.0f); - i->period_missing_percent= (double)(((double)i->period_missing_count / (double)i->period_time) * 100.0f); - - if ((i->period_packet_in_count >= i->period_time)) { - i->period_packet_in_count = 0; - - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "PERIOD %f jitter missing:%f q:%d/%d\n", i->period_jitter_percent, i->period_missing_percent, i->qlen, i->orig_qlen); - } - stfu_n_auto_size(i, 1); - - //if (i->qlen > i->orig_qlen) { - //if (i->period_jitter_percent < PERIOD_JITTER_TOLERANCE && i->period_missing_percent < PERIOD_JITTER_TOLERANCE) { - // stfu_n_resize(i, -1); - //} - //} - - stfu_n_reset_counters(i); - } - - if (stfu_log != null_logger && (i->debug & DBG_IN)) { - stfu_log(STFU_LOG_EMERG, "I: %s len:%u/%u i=%u/%u - g:%u c:%u b:%u - ts:%u/%u/%u - m:%u(%f%%) j:%0.2f%% js:%u/%u dr:%d/%d\n", - i->name, - i->qlen, i->max_qlen, - i->period_packet_in_count, i->period_time, - i->consecutive_good_count, - i->period_clean_count, - i->consecutive_bad_count, - ts, ts / i->samples_per_packet, - i->last_wr_ts, - i->period_missing_count, - i->period_missing_percent, - i->period_jitter_percent, - i->period_jitter_size_time, - i->period_jitter_size_ts, - i->ts_drift, i->max_drift); - } - - if (last || i->in_queue->array_len == i->in_queue->array_size) { - stfu_n_swap(i); - } - - if (last) { - return STFU_IM_DONE; - } - - index = i->in_queue->array_len++; - assert(index < i->in_queue->array_size); - frame = &i->in_queue->array[index]; - - if (i->in_queue->array_len == i->in_queue->array_size) { - stfu_n_swap(i); - } - - if ((cplen = datalen) > sizeof(frame->data)) { - cplen = sizeof(frame->data); - } - - i->last_rd_ts = ts; - i->packet_count++; - - memcpy(frame->data, data, cplen); - - frame->pt = pt; - frame->ts = ts; - frame->seq = seq; - frame->dlen = cplen; - frame->was_read = 0; - - return STFU_IT_WORKED; -} - -static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_frame_t **r_frame, int force) -{ - uint32_t i = 0, best_index = 0; - int best_diff = 1000000, cur_diff = 0; - stfu_frame_t *frame = NULL, *best_frame = NULL; - int newer = 0; - uint32_t was_read = 0; - - stfu_assert(r_frame); - - *r_frame = NULL; - - top: - - was_read = 0; - - if (force) { - in->cur_ts = 0; - } - - for(i = 0; i < queue->real_array_size; i++) { - frame = &queue->array[i]; - - if (frame->was_read) was_read++; - - if (!frame->was_read && in->cur_ts && frame->ts > in->cur_ts) { - newer++; - } - - cur_diff = abs((int)(frame->ts - in->cur_ts)); - - if (!frame->was_read && cur_diff < best_diff) { - best_diff = cur_diff; - best_frame = frame; - best_index = i; - } - } - - if (was_read == queue->real_array_size) { - if (stfu_log != null_logger && in->debug) { - stfu_log(STFU_LOG_EMERG, "%s OUT QUEUE EMPTY, SWAPPING\n", in->name); - } - - stfu_n_swap(in); - in->ready = 0; - return 0; - } - - if (!force && !best_frame && newer) { - force = 1; - goto top; - } - - if (best_frame) { - *r_frame = best_frame; - queue->last_index = best_index; - best_frame->was_read = 1; - in->period_packet_out_count++; - in->session_packet_out_count++; - return 1; - } - - - return 0; -} - - -static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame) -{ - uint32_t i = 0; - stfu_frame_t *frame = NULL; - - if (r_frame) { - *r_frame = NULL; - } - - for(i = 0; i < queue->array_len; i++) { - frame = &queue->array[i]; - - if (frame->ts == ts) { - if (r_frame) { - *r_frame = frame; - queue->last_index = i; - frame->was_read = 1; - in->period_packet_out_count++; - in->session_packet_out_count++; - } - return 1; - } - } - - return 0; -} - -static stfu_frame_t *stfu_n_find_least_unread_frame(stfu_instance_t *i) -{ - uint32_t y, least = 0; - stfu_frame_t *frame = NULL, *lframe = NULL; - - for (y = 0; y < i->out_queue->array_len; y++) { - frame = &i->out_queue->array[y]; - if (!frame->was_read && (frame->ts < least || least == 0)) { - lframe = frame; - least = frame->ts; - } - } - - for (y = 0; y < i->in_queue->array_len; y++) { - frame = &i->in_queue->array[y]; - if (!frame->was_read && (frame->ts < least || least == 0)) { - least = frame->ts; - lframe = frame; - } - } - - return lframe; -} - -void stfu_n_dump(stfu_instance_t *i) -{ - uint32_t y; - stfu_frame_t *frame = NULL; - - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s OUT QUEUE: ------------\n", i->name); - for(y = 0; y < i->out_queue->array_len; y++) { - frame = &i->out_queue->array[y]; - stfu_log(STFU_LOG_EMERG, "%s\t%u:%u r:%d\n", i->name, frame->ts, frame->ts / i->samples_per_packet, frame->was_read); - } - stfu_log(STFU_LOG_EMERG, "%s\n\n", i->name); - stfu_log(STFU_LOG_EMERG, "%s IN QUEUE: ------------\n", i->name); - for(y = 0; y < i->in_queue->array_len; y++) { - frame = &i->in_queue->array[y]; - stfu_log(STFU_LOG_EMERG, "%s\t%u:%u r:%d\n", i->name, frame->ts, frame->ts / i->samples_per_packet, frame->was_read); - } - stfu_log(STFU_LOG_EMERG, "%s\n\n\n", i->name); - } -} - -stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) -{ - stfu_frame_t *rframe = NULL; - int found = 0; - - if (!i->samples_per_packet) { - return NULL; - } - - if (!i->ready) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s JITTERBUFFER NOT READY: IGNORING FRAME\n", i->name); - } - return NULL; - } - - - if (i->cur_ts == 0 && i->last_wr_ts < 1000) { - uint32_t x = 0; - for (x = 0; x < i->out_queue->array_len; x++) { - if (!i->out_queue->array[x].was_read) { - i->cur_ts = i->out_queue->array[x].ts; - i->cur_seq = i->out_queue->array[x].seq; - break; - } - if (i->cur_ts == 0) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s JITTERBUFFER ERROR: PUNTING\n", i->name); - return NULL; - } - } - } - } else { - i->cur_ts = i->cur_ts + i->samples_per_packet; - i->cur_seq++; - } - - found = stfu_n_find_frame(i, i->out_queue, i->cur_ts, &rframe); - - if (!found) { - found = stfu_n_find_frame(i, i->in_queue, i->cur_ts, &rframe); - - if (!found) { - found = stfu_n_find_frame(i, i->old_queue, i->cur_ts, &rframe); - } - } - - if (i->sync_out) { - if (!found) { - if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe, 1))) { - i->cur_ts = rframe->ts; - i->cur_seq = rframe->seq; - } - - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s SYNC %u %u:%u\n", i->name, i->sync_out, i->cur_ts, i->cur_ts / i->samples_per_packet); - } - - } - i->sync_out = 0; - } - - if (!i->cur_ts) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s NO TS\n", i->name); - } - return NULL; - } - - if (!found && i->samples_per_packet) { - stfu_frame_t *least = stfu_n_find_least_unread_frame(i); - - if (least && least->ts > i->cur_ts && (least->ts - i->cur_ts) / i->samples_per_packet > i->qlen) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s SLIPPED BEHIND %d packets, RESYNCRONIZING\n", i->name, (least->ts - i->cur_ts) / i->samples_per_packet); - } - found = 1; - i->cur_ts = least->ts; - i->cur_seq = least->seq; - rframe = least; - } - } - - - if (!found && i->samples_per_packet) { - int32_t delay = i->cur_ts - i->last_rd_ts; - uint32_t need = abs(delay) / i->samples_per_packet; - - i->period_missing_count++; - i->session_missing_count++; - i->period_need_range += need; - - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s MISSING %u:%u %u %u %d %u %d\n", i->name, - i->cur_ts, i->cur_ts / i->samples_per_packet, i->packet_count, i->last_rd_ts, delay, i->qlen, need); - } - - if (i->packet_count > i->orig_qlen * 100 && delay > 0 && need > i->qlen && need < (i->qlen + 5)) { - i->packet_count = 0; - } - - stfu_n_dump(i); - } - - if (stfu_log != null_logger && (i->debug & DBG_OUT)) { - if (found) { - stfu_log(STFU_LOG_EMERG, "O: %s %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc); - } - } - - if (found) { - i->consecutive_good_count++; - i->period_good_count++; - i->consecutive_bad_count = 0; - } else { - i->consecutive_bad_count++; - i->period_bad_count++; - i->consecutive_good_count = 0; - } - - if (found) { - i->last_frame = rframe; - i->out_queue->wr_len++; - i->last_wr_ts = rframe->ts; - - i->miss_count = 0; - if (rframe->dlen) { - i->plc_len = rframe->dlen; - } - - i->plc_pt = rframe->pt; - - } else { - if (i->consecutive_bad_count > (i->max_qlen / 2)) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s NO PACKETS HARD RESETTING\n", i->name); - } - stfu_n_reset(i); - } else { - i->last_wr_ts = i->cur_ts; - rframe = &i->out_queue->int_frame; - rframe->dlen = i->plc_len; - rframe->pt = i->plc_pt; - rframe->ts = i->cur_ts; - rframe->seq = i->cur_seq; - i->miss_count++; - - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s PLC %d/%d %d %ld %u:%u\n", i->name, - i->miss_count, i->max_qlen, rframe->plc, rframe->dlen, rframe->ts, rframe->ts / i->samples_per_packet); - } - } - - if (i->miss_count > i->max_qlen) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s TOO MANY MISS %d/%d SYNC...\n", i->name, i->miss_count, i->max_qlen); - } - stfu_n_sync(i, 1); - } - - } - - return rframe; -} - -SWITCH_DECLARE(int32_t) stfu_n_peek_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t **rframe) -{ - uint32_t i = 0, qi = 0; - stfu_frame_t *frame = NULL; - uint16_t want_seq = seq + distance; - stfu_queue_t *queues[2] = {jb->out_queue, jb->in_queue}; - - switch_assert(rframe); - - for (qi = 0; qi < 2; qi++) { - stfu_queue_t *queue = queues[qi]; - - for(i = 0; i < queue->array_len; i++) { - frame = &queue->array[i]; - - if (frame->seq == want_seq) { - *rframe = frame; - return 1; - } - } - } - - return 0; -} - - -#ifdef WIN32 -#ifndef vsnprintf -#define vsnprintf _vsnprintf -#endif -#endif - - -int vasprintf(char **ret, const char *format, va_list ap); - -int stfu_vasprintf(char **ret, const char *fmt, va_list ap) -{ -#if !defined(WIN32) && !defined(__sun) - return vasprintf(ret, fmt, ap); -#else - char *buf; - int len; - size_t buflen; - va_list ap2; - char *tmp = NULL; - -#ifdef _MSC_VER -#if _MSC_VER >= 1500 - /* hack for incorrect assumption in msvc header files for code analysis */ - __analysis_assume(tmp); -#endif - ap2 = ap; -#else - va_copy(ap2, ap); -#endif - - len = vsnprintf(tmp, 0, fmt, ap2); - - if (len > 0 && (buf = malloc((buflen = (size_t) (len + 1)))) != NULL) { - len = vsnprintf(buf, buflen, fmt, ap); - *ret = buf; - } else { - *ret = NULL; - len = -1; - } - - va_end(ap2); - return len; -#endif -} - - - - -int stfu_snprintf(char *buffer, size_t count, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret = vsnprintf(buffer, count-1, fmt, ap); - if (ret < 0) - buffer[count-1] = '\0'; - va_end(ap); - return ret; -} - -static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) -{ - if (file && func && line && level && fmt) { - return; - } - return; -} - - - -static const char *LEVEL_NAMES[] = { - "EMERG", - "ALERT", - "CRIT", - "ERROR", - "WARNING", - "NOTICE", - "INFO", - "DEBUG", - NULL -}; - -static const char *cut_path(const char *in) -{ - const char *p, *ret = in; - char delims[] = "/\\"; - char *i; - - for (i = delims; *i; i++) { - p = in; - while ((p = strchr(p, *i)) != 0) { - ret = ++p; - } - } - return ret; -} - - -static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...) -{ - const char *fp; - char *data; - va_list ap; - int ret; - - if (level < 0 || level > 7) { - level = 7; - } - if (level > stfu_log_level) { - return; - } - - fp = cut_path(file); - - va_start(ap, fmt); - - ret = stfu_vasprintf(&data, fmt, ap); - - if (ret != -1) { - fprintf(stderr, "[%s] %s:%d %s() %s", LEVEL_NAMES[level], fp, line, func, data); - free(data); - } - - va_end(ap); - -} - -/* For Emacs: -* Local Variables: -* mode:c -* indent-tabs-mode:t -* tab-width:4 -* c-basic-offset:4 -* End: -* For VIM: -* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: -*/ diff --git a/src/switch_time.c b/src/switch_time.c index b539d9be10..01e6dfab15 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -175,7 +175,7 @@ static void do_sleep(switch_interval_time_t t) #elif defined(DARWIN) t -= OFFSET; ts.tv_sec = t / APR_USEC_PER_SEC; - ts.tv_nsec = (t % APR_USEC_PER_SEC) * 1000; + ts.tv_nsec = (t % APR_USEC_PER_SEC) * 850; nanosleep(&ts, NULL); #else apr_sleep(t); diff --git a/src/switch_utf8.c b/src/switch_utf8.c index eaa59a5c9d..86c7f5e4a9 100644 --- a/src/switch_utf8.c +++ b/src/switch_utf8.c @@ -463,45 +463,12 @@ SWITCH_DECLARE(int) switch_u8_is_locale_utf8(char *locale) return 0; } -SWITCH_DECLARE(int) switch_u8_vprintf(char *fmt, va_list ap) -{ - int cnt, sz=0; - char *buf; - uint32_t *wcs; - - sz = 512; - buf = (char*)alloca(sz); - try_print: - cnt = vsnprintf(buf, sz, fmt, ap); - if (cnt >= sz) { - buf = (char*)alloca(cnt - sz + 1); - sz = cnt + 1; - goto try_print; - } - wcs = (uint32_t*)alloca((cnt+1) * sizeof(uint32_t)); - cnt = switch_u8_toucs(wcs, cnt+1, buf, cnt); - printf("%ls", (wchar_t*)wcs); - return cnt; -} - -SWITCH_DECLARE(int) switch_u8_printf(char *fmt, ...) -{ - int cnt; - va_list args; - - va_start(args, fmt); - - cnt = switch_u8_vprintf(fmt, args); - - va_end(args); - return cnt; -} /* reads the next utf-8 sequence out of a string, updating an index */ SWITCH_DECLARE(uint32_t) switch_u8_get_char(char *s, int *i) { - u_int32_t ch = 0; + uint32_t ch = 0; int sz = 0; do { diff --git a/src/switch_vidderbuffer.c b/src/switch_vidderbuffer.c deleted file mode 100644 index 8bc6d26150..0000000000 --- a/src/switch_vidderbuffer.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * Copyright (C) 2005-2014, Anthony Minessale II - * - * Version: MPL 1.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - * - * The Initial Developer of the Original Code is - * Anthony Minessale II - * Portions created by the Initial Developer are Copyright (C) - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Anthony Minessale II - * - * switch_vidderbuffer.c -- Video Buffer - * - */ -#include -#include - -#define MAX_MISSING_SEQ 20 -#define vb_debug(_vb, _level, _format, ...) if (_vb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ALERT, "VB:%p level:%d line:%d ->" _format, (void *) _vb, _level, __LINE__, __VA_ARGS__) - -const char *TOKEN_1 = "ONE"; -const char *TOKEN_2 = "TWO"; - -struct switch_vb_s; - -typedef struct switch_vb_node_s { - struct switch_vb_s *parent; - switch_rtp_packet_t packet; - uint32_t len; - uint8_t visible; - struct switch_vb_node_s *prev; - struct switch_vb_node_s *next; -} switch_vb_node_t; - -struct switch_vb_s { - struct switch_vb_node_s *node_list; - uint32_t last_target_seq; - uint32_t highest_read_ts; - uint32_t highest_read_seq; - uint32_t highest_wrote_ts; - uint32_t highest_wrote_seq; - uint16_t target_seq; - uint32_t visible_nodes; - uint32_t complete_frames; - uint32_t frame_len; - uint32_t min_frame_len; - uint32_t max_frame_len; - uint8_t write_init; - uint8_t read_init; - uint8_t debug_level; - uint16_t next_seq; - switch_inthash_t *missing_seq_hash; - switch_inthash_t *node_hash; - switch_mutex_t *mutex; - switch_mutex_t *list_mutex; - switch_memory_pool_t *pool; - int free_pool; - switch_vb_flag_t flags; -}; - -static inline switch_vb_node_t *new_node(switch_vb_t *vb) -{ - switch_vb_node_t *np; - - switch_mutex_lock(vb->list_mutex); - - for (np = vb->node_list; np; np = np->next) { - if (!np->visible) { - break; - } - } - - if (!np) { - - np = switch_core_alloc(vb->pool, sizeof(*np)); - - np->next = vb->node_list; - if (np->next) { - np->next->prev = np; - } - vb->node_list = np; - - } - - switch_assert(np); - - np->visible = 1; - vb->visible_nodes++; - np->parent = vb; - - switch_mutex_unlock(vb->list_mutex); - - return np; -} - -static inline void push_to_top(switch_vb_t *vb, switch_vb_node_t *node) -{ - if (node == vb->node_list) { - vb->node_list = node->next; - } else if (node->prev) { - node->prev->next = node->next; - } - - if (node->next) { - node->next->prev = node->prev; - } - - node->next = vb->node_list; - node->prev = NULL; - - if (node->next) { - node->next->prev = node; - } - - vb->node_list = node; - - switch_assert(node->next != node); - switch_assert(node->prev != node); -} - -static inline void hide_node(switch_vb_node_t *node, switch_bool_t pop) -{ - switch_vb_t *vb = node->parent; - - switch_mutex_lock(vb->list_mutex); - - if (node->visible) { - node->visible = 0; - vb->visible_nodes--; - - if (pop) { - push_to_top(vb, node); - } - } - - switch_core_inthash_delete(vb->node_hash, node->packet.header.seq); - - switch_mutex_unlock(vb->list_mutex); -} - -static inline void sort_free_nodes(switch_vb_t *vb) -{ - switch_vb_node_t *np, *this_np; - int start = 0; - - switch_mutex_lock(vb->list_mutex); - np = vb->node_list; - - while(np) { - this_np = np; - np = np->next; - - if (this_np->visible) { - start++; - } - - if (start && !this_np->visible) { - push_to_top(vb, this_np); - } - } - - switch_mutex_unlock(vb->list_mutex); -} - -static inline void hide_nodes(switch_vb_t *vb) -{ - switch_vb_node_t *np; - - switch_mutex_lock(vb->list_mutex); - for (np = vb->node_list; np; np = np->next) { - hide_node(np, SWITCH_FALSE); - } - switch_mutex_unlock(vb->list_mutex); -} - -static inline void drop_ts(switch_vb_t *vb, uint32_t ts) -{ - switch_vb_node_t *np; - int x = 0; - - switch_mutex_lock(vb->list_mutex); - for (np = vb->node_list; np; np = np->next) { - if (!np->visible) continue; - - if (ts == np->packet.header.ts) { - hide_node(np, SWITCH_FALSE); - x++; - } - } - - if (x) { - sort_free_nodes(vb); - } - - switch_mutex_unlock(vb->list_mutex); - - if (x) vb->complete_frames--; -} - -static inline uint32_t vb_find_lowest_ts(switch_vb_t *vb) -{ - switch_vb_node_t *np, *lowest = NULL; - - switch_mutex_lock(vb->list_mutex); - for (np = vb->node_list; np; np = np->next) { - if (!np->visible) continue; - - if (!lowest || ntohl(lowest->packet.header.ts) > ntohl(np->packet.header.ts)) { - lowest = np; - } - } - switch_mutex_unlock(vb->list_mutex); - - return lowest ? lowest->packet.header.ts : 0; -} - -static inline void drop_oldest_frame(switch_vb_t *vb) -{ - uint32_t ts = vb_find_lowest_ts(vb); - - drop_ts(vb, ts); - vb_debug(vb, 1, "Dropping oldest frame ts:%u\n", ntohl(ts)); -} - -static inline void add_node(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t len) -{ - switch_vb_node_t *node = new_node(vb); - - node->packet = *packet; - node->len = len; - memcpy(node->packet.body, packet->body, len); - - switch_core_inthash_insert(vb->node_hash, node->packet.header.seq, node); - - vb_debug(vb, (packet->header.m ? 1 : 2), "PUT packet last_ts:%u ts:%u seq:%u%s\n", - ntohl(vb->highest_wrote_ts), ntohl(node->packet.header.ts), ntohs(node->packet.header.seq), packet->header.m ? " " : ""); - - - - - - if (vb->write_init && ((abs(((int)htons(packet->header.seq) - htons(vb->highest_wrote_seq))) > 16) || - (abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(vb->highest_wrote_ts))) > 900000))) { - vb_debug(vb, 2, "%s", "CHANGE DETECTED, PUNT\n"); - switch_vb_reset(vb); - } - - - - - if (!vb->write_init || ntohs(packet->header.seq) > ntohs(vb->highest_wrote_seq) || - (ntohs(vb->highest_wrote_seq) > USHRT_MAX - 10 && ntohs(packet->header.seq) <= 10) ) { - vb->highest_wrote_seq = packet->header.seq; - } - - if (vb->write_init && htons(packet->header.seq) >= htons(vb->highest_wrote_seq) && (ntohl(node->packet.header.ts) > ntohl(vb->highest_wrote_ts))) { - vb->complete_frames++; - vb_debug(vb, 2, "WRITE frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), vb->complete_frames , vb->frame_len, vb->visible_nodes); - vb->highest_wrote_ts = packet->header.ts; - } else if (!vb->write_init) { - vb->highest_wrote_ts = packet->header.ts; - } - - if (!vb->write_init) vb->write_init = 1; - - if (vb->complete_frames > vb->max_frame_len) { - drop_oldest_frame(vb); - } -} - -static inline void increment_seq(switch_vb_t *vb) -{ - vb->target_seq = htons((ntohs(vb->target_seq) + 1)); -} - -static inline void set_read_seq(switch_vb_t *vb, uint16_t seq) -{ - vb->last_target_seq = seq; - vb->target_seq = htons((ntohs(vb->last_target_seq) + 1)); -} - -static inline switch_vb_node_t *vb_find_lowest_seq(switch_vb_t *vb) -{ - switch_vb_node_t *np, *lowest = NULL; - - switch_mutex_lock(vb->list_mutex); - for (np = vb->node_list; np; np = np->next) { - if (!np->visible) continue; - - if (!lowest || ntohs(lowest->packet.header.seq) > ntohs(np->packet.header.seq)) { - lowest = np; - } - } - switch_mutex_unlock(vb->list_mutex); - - return lowest; -} - -static inline switch_status_t vb_next_packet(switch_vb_t *vb, switch_vb_node_t **nodep) -{ - switch_vb_node_t *node = NULL; - - if (!vb->target_seq) { - if ((node = vb_find_lowest_seq(vb))) { - vb_debug(vb, 2, "No target seq using seq: %u as a starting point\n", ntohs(node->packet.header.seq)); - } else { - vb_debug(vb, 1, "%s", "No nodes available....\n"); - } - } else if ((node = switch_core_inthash_find(vb->node_hash, vb->target_seq))) { - vb_debug(vb, 2, "FOUND desired seq: %u\n", ntohs(vb->target_seq)); - } else { - int x; - - vb_debug(vb, 2, "MISSING desired seq: %u\n", ntohs(vb->target_seq)); - - for (x = 0; x < 10; x++) { - increment_seq(vb); - if ((node = switch_core_inthash_find(vb->node_hash, vb->target_seq))) { - vb_debug(vb, 2, "FOUND incremental seq: %u\n", ntohs(vb->target_seq)); - break; - } else { - vb_debug(vb, 2, "MISSING incremental seq: %u\n", ntohs(vb->target_seq)); - } - } - } - - *nodep = node; - - if (node) { - set_read_seq(vb, node->packet.header.seq); - return SWITCH_STATUS_SUCCESS; - } - - return SWITCH_STATUS_NOTFOUND; - -} - -static inline void free_nodes(switch_vb_t *vb) -{ - switch_mutex_lock(vb->list_mutex); - vb->node_list = NULL; - switch_mutex_unlock(vb->list_mutex); -} - -SWITCH_DECLARE(void) switch_vb_set_flag(switch_vb_t *vb, switch_vb_flag_t flag) -{ - switch_set_flag(vb, flag); -} - -SWITCH_DECLARE(void) switch_vb_clear_flag(switch_vb_t *vb, switch_vb_flag_t flag) -{ - switch_clear_flag(vb, flag); -} - -SWITCH_DECLARE(int) switch_vb_poll(switch_vb_t *vb) -{ - return (vb->complete_frames >= vb->frame_len); -} - -SWITCH_DECLARE(int) switch_vb_frame_count(switch_vb_t *vb) -{ - return vb->complete_frames; -} - -SWITCH_DECLARE(void) switch_vb_debug_level(switch_vb_t *vb, uint8_t level) -{ - vb->debug_level = level; -} - -SWITCH_DECLARE(void) switch_vb_reset(switch_vb_t *vb) -{ - - switch_mutex_lock(vb->mutex); - switch_core_inthash_destroy(&vb->missing_seq_hash); - switch_core_inthash_init(&vb->missing_seq_hash); - switch_mutex_unlock(vb->mutex); - - vb_debug(vb, 2, "%s", "RESET BUFFER\n"); - - - vb->last_target_seq = 0; - vb->target_seq = 0; - vb->write_init = 0; - vb->highest_wrote_seq = 0; - vb->highest_wrote_ts = 0; - vb->next_seq = 0; - vb->highest_read_ts = 0; - vb->highest_read_seq = 0; - vb->complete_frames = 0; - vb->read_init = 0; - vb->next_seq = 0; - vb->complete_frames = 0; - - switch_mutex_lock(vb->mutex); - hide_nodes(vb); - switch_mutex_unlock(vb->mutex); -} - -SWITCH_DECLARE(switch_status_t) switch_vb_get_frames(switch_vb_t *vb, uint32_t *min_frame_len, uint32_t *max_frame_len) -{ - - switch_mutex_lock(vb->mutex); - - if (min_frame_len) { - *min_frame_len = vb->min_frame_len; - } - - if (max_frame_len) { - *max_frame_len = vb->max_frame_len; - } - - switch_mutex_unlock(vb->mutex); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_set_frames(switch_vb_t *vb, uint32_t min_frame_len, uint32_t max_frame_len) -{ - switch_mutex_lock(vb->mutex); - vb->min_frame_len = vb->frame_len = min_frame_len; - vb->max_frame_len = max_frame_len; - switch_mutex_unlock(vb->mutex); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_create(switch_vb_t **vbp, uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool) -{ - switch_vb_t *vb; - int free_pool = 0; - - if (!pool) { - switch_core_new_memory_pool(&pool); - free_pool = 1; - } - - vb = switch_core_alloc(pool, sizeof(*vb)); - vb->free_pool = free_pool; - vb->min_frame_len = vb->frame_len = min_frame_len; - vb->max_frame_len = max_frame_len; - vb->pool = pool; - - switch_core_inthash_init(&vb->missing_seq_hash); - switch_core_inthash_init(&vb->node_hash); - switch_mutex_init(&vb->mutex, SWITCH_MUTEX_NESTED, pool); - switch_mutex_init(&vb->list_mutex, SWITCH_MUTEX_NESTED, pool); - - *vbp = vb; - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_destroy(switch_vb_t **vbp) -{ - switch_vb_t *vb = *vbp; - *vbp = NULL; - - switch_core_inthash_destroy(&vb->missing_seq_hash); - switch_core_inthash_destroy(&vb->node_hash); - - free_nodes(vb); - - if (vb->free_pool) { - switch_core_destroy_memory_pool(&vb->pool); - } - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(uint32_t) switch_vb_pop_nack(switch_vb_t *vb) -{ - switch_hash_index_t *hi = NULL; - uint32_t nack = 0; - uint16_t blp = 0; - uint16_t least = 0; - int i = 0; - - void *val; - const void *var; - - switch_mutex_lock(vb->mutex); - - for (hi = switch_core_hash_first(vb->missing_seq_hash); hi; hi = switch_core_hash_next(&hi)) { - uint16_t seq; - const char *token; - - switch_core_hash_this(hi, &var, NULL, &val); - token = (const char *) val; - - if (token == TOKEN_2) { - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SKIP %u %s\n", ntohs(*((uint16_t *) var)), token); - continue; - } - seq = ntohs(*((uint16_t *) var)); - - if (!least || seq < least) { - least = seq; - } - } - - if (least && switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(least))) { - vb_debug(vb, 3, "Found smallest NACKABLE seq %u\n", least); - nack = (uint32_t) htons(least); - - switch_core_inthash_insert(vb->missing_seq_hash, nack, (void *) TOKEN_2); - - for(i = 0; i < 16; i++) { - if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(least + i + 1))) { - switch_core_inthash_insert(vb->missing_seq_hash, (uint32_t)htons(least + i + 1), (void *) TOKEN_2); - vb_debug(vb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1); - blp |= (1 << i); - } - } - - blp = htons(blp); - nack |= (uint32_t) blp << 16; - } - - switch_mutex_unlock(vb->mutex); - - - return nack; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_push_packet(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t len) -{ - add_node(vb, packet, len); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_put_packet(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t len) -{ - uint32_t i; - uint16_t want = ntohs(vb->next_seq), got = ntohs(packet->header.seq); - int missing = 0; - - switch_mutex_lock(vb->mutex); - - if (!want) want = got; - - if (switch_test_flag(vb, SVB_QUEUE_ONLY)) { - vb->next_seq = htons(got + 1); - } else { - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "WTF %u\n", got); - - if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(got))) { - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "POPPED RESEND %u\n", got); - missing = 1; - } - - if (!missing || want == got) { - if (got > want) { - //vb_debug(vb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1); - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "XXXXXXXXXXXXXXXXXX WTF GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1); - for (i = want; i < got; i++) { - //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MISSING %u\n", i); - switch_core_inthash_insert(vb->missing_seq_hash, (uint32_t)htons(i), (void *)TOKEN_1); - } - - } - - if (got >= want || (want - got) > 1000) { - vb->next_seq = htons(got + 1); - } - } - } - - add_node(vb, packet, len); - - switch_mutex_unlock(vb->mutex); - - return SWITCH_STATUS_SUCCESS; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_get_packet_by_seq(switch_vb_t *vb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len) -{ - switch_vb_node_t *node; - - if ((node = switch_core_inthash_find(vb->node_hash, seq))) { - vb_debug(vb, 2, "Found buffered seq: %u\n", ntohs(seq)); - *packet = node->packet; - *len = node->len; - memcpy(packet->body, node->packet.body, node->len); - return SWITCH_STATUS_SUCCESS; - } else { - vb_debug(vb, 2, "Missing buffered seq: %u\n", ntohs(seq)); - } - - return SWITCH_STATUS_NOTFOUND; -} - -SWITCH_DECLARE(switch_status_t) switch_vb_get_packet(switch_vb_t *vb, switch_rtp_packet_t *packet, switch_size_t *len) -{ - switch_vb_node_t *node = NULL; - switch_status_t status; - - switch_mutex_lock(vb->mutex); - vb_debug(vb, 2, "GET PACKET %u/%u n:%d\n", vb->complete_frames , vb->frame_len, vb->visible_nodes); - - if (vb->complete_frames < vb->frame_len) { - vb_debug(vb, 2, "BUFFERING %u/%u\n", vb->complete_frames , vb->frame_len); - switch_goto_status(SWITCH_STATUS_MORE_DATA, end); - } - - if ((status = vb_next_packet(vb, &node)) == SWITCH_STATUS_SUCCESS) { - vb_debug(vb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq)); - - if (!vb->read_init || ntohs(node->packet.header.seq) > ntohs(vb->highest_read_seq) || - (ntohs(vb->highest_read_seq) > USHRT_MAX - 10 && ntohs(node->packet.header.seq) <= 10) ) { - vb->highest_read_seq = node->packet.header.seq; - } - - if (vb->read_init && htons(node->packet.header.seq) >= htons(vb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(vb->highest_read_ts))) { - vb->complete_frames--; - vb_debug(vb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), vb->complete_frames , vb->frame_len, vb->visible_nodes); - vb->highest_read_ts = node->packet.header.ts; - } else if (!vb->read_init) { - vb->highest_read_ts = node->packet.header.ts; - } - - if (!vb->read_init) vb->read_init = 1; - - - } else { - switch_vb_reset(vb); - - switch(status) { - case SWITCH_STATUS_RESTART: - vb_debug(vb, 2, "%s", "Error encountered ask for new keyframe\n"); - switch_goto_status(SWITCH_STATUS_RESTART, end); - case SWITCH_STATUS_NOTFOUND: - default: - vb_debug(vb, 2, "%s", "No frames found wait for more\n"); - switch_goto_status(SWITCH_STATUS_MORE_DATA, end); - } - } - - if (node) { - status = SWITCH_STATUS_SUCCESS; - - *packet = node->packet; - *len = node->len; - memcpy(packet->body, node->packet.body, node->len); - hide_node(node, SWITCH_TRUE); - - vb_debug(vb, 1, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " " : ""); - - } else { - status = SWITCH_STATUS_MORE_DATA; - } - - end: - - switch_mutex_unlock(vb->mutex); - - return status; - -} - - -/* For Emacs: - * Local Variables: - * mode:c - * indent-tabs-mode:t - * tab-width:4 - * c-basic-offset:4 - * End: - * For VIM: - * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: - */ diff --git a/src/switch_xml.c b/src/switch_xml.c index 4cf4bb3ad9..43ffabfcc7 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -1254,6 +1254,11 @@ static char *expand_vars(char *buf, char *ebuf, switch_size_t elen, switch_size_ *wp++ = *rp++; } + + if (wp == ep) { + return NULL; + } + *wp++ = '\0'; *newlen = strlen(ebuf); @@ -1394,11 +1399,16 @@ static int preprocess(const char *cwd, const char *file, FILE *write_fd, int rle break; } - eblen = len *2; + eblen = len * 2; ebuf = malloc(eblen); memset(ebuf, 0, eblen); - bp = expand_vars(buf, ebuf, eblen, &cur, &err); + while (!(bp = expand_vars(buf, ebuf, eblen, &cur, &err))) { + eblen *= 2; + ebuf = realloc(ebuf, eblen); + memset(ebuf, 0, eblen); + } + line++; if (err) { diff --git a/w32/Library/FreeSwitchCore.2010.vcxproj.filters b/w32/Library/FreeSwitchCore.2010.vcxproj.filters index 6a7b1912d7..34c4253470 100644 --- a/w32/Library/FreeSwitchCore.2010.vcxproj.filters +++ b/w32/Library/FreeSwitchCore.2010.vcxproj.filters @@ -34,9 +34,6 @@ Source Files - - Source Files - Source Files @@ -255,9 +252,6 @@ Header Files - - Header Files - Header Files diff --git a/w32/Library/FreeSwitchCore.2015.vcxproj b/w32/Library/FreeSwitchCore.2015.vcxproj index ac186d29cf..70c3a48dea 100644 --- a/w32/Library/FreeSwitchCore.2015.vcxproj +++ b/w32/Library/FreeSwitchCore.2015.vcxproj @@ -1,4 +1,4 @@ - + @@ -114,7 +114,7 @@ Disabled ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\sqlite-amalgamation-3080401;..\..\libs\pcre-8.34;..\..\libs\speex-1.2rc1\include;..\..\libs\curl-7.35.0\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;..\..\libs\openssl-$(OpenSSLVersion)\include;..\..\libs\sofia-sip\libsofia-sip-ua\sdp;..\..\libs\sofia-sip\libsofia-sip-ua\su;..\..\libs\sofia-sip\win32;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -177,7 +177,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs Disabled ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\sqlite-amalgamation-3080401;..\..\libs\pcre-8.34;..\..\libs\speex-1.2rc1\include;..\..\libs\curl-7.35.0\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;..\..\libs\openssl-$(OpenSSLVersion)\include;..\..\libs\sofia-sip\libsofia-sip-ua\sdp;..\..\libs\sofia-sip\libsofia-sip-ua\su;..\..\libs\sofia-sip\win32;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;PCRE_STATIC;STATICLIB;ENABLE_ZRTP;TPL_NOLIB;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -231,7 +231,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs MaxSpeed ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\sqlite-amalgamation-3080401;..\..\libs\pcre-8.34;..\..\libs\speex-1.2rc1\include;..\..\libs\curl-7.35.0\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;..\..\libs\openssl-$(OpenSSLVersion)\include;..\..\libs\sofia-sip\libsofia-sip-ua\sdp;..\..\libs\sofia-sip\libsofia-sip-ua\su;..\..\libs\sofia-sip\win32;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) MultiThreadedDLL Create switch.h @@ -282,7 +282,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs MaxSpeed ..\..\src\include;..\..\libs\include;..\..\libs\srtp\include;..\..\libs\srtp\crypto\include;..\..\libs\libteletone\src;..\..\libs\sqlite-amalgamation-3080401;..\..\libs\pcre-8.34;..\..\libs\speex-1.2rc1\include;..\..\libs\curl-7.35.0\include;..\..\libs\spandsp\src\msvc;..\..\libs\spandsp\src;..\..\libs\tiff-4.0.2\libtiff;..\..\libs\libzrtp\include;..\..\libs\libzrtp\third_party\bgaes;..\..\libs\libzrtp\third_party\bnlib;..\..\libs\libtpl-1.5\src;..\..\libs\libtpl-1.5\src\win;..\..\libs\openssl-$(OpenSSLVersion)\include;..\..\libs\sofia-sip\libsofia-sip-ua\sdp;..\..\libs\sofia-sip\libsofia-sip-ua\su;..\..\libs\sofia-sip\win32;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;STFU_EXPORTS;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;FREESWITCHCORE_EXPORTS;STATICLIB;CRASH_PROT;PCRE_STATIC;ENABLE_ZRTP;TPL_NOLIB;LIBSOFIA_SIP_UA_STATIC;HAVE_OPENSSL;HAVE_OPENSSL_DTLS_SRTP;HAVE_OPENSSL_DTLS;%(PreprocessorDefinitions) MultiThreadedDLL Create switch.h @@ -363,32 +363,6 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs - - - - - - - - - - - - - - - - - - - - - - - - - - Create @@ -482,7 +456,7 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs - + @@ -769,7 +743,6 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs - @@ -916,4 +889,4 @@ if not exist "$(OutDir)htdocs" xcopy "$(SolutionDir)htdocs\*.*" "$(OutDir)htdocs - \ No newline at end of file + diff --git a/w32/Setup/Setup.2015.wixproj b/w32/Setup/Setup.2015.wixproj index 7dcf416bf7..1d8563b353 100644 --- a/w32/Setup/Setup.2015.wixproj +++ b/w32/Setup/Setup.2015.wixproj @@ -61,7 +61,13 @@ + + + $(SolutionDir)packages\WiX.Toolset.2015.3.10.0.1503\tools\wix\ + $(WixToolPath)wix.targets + $(WixToolPath)WixTasks.dll + "$(WixToolPath)\heat.exe" dir "$(ProjectDir)..\..\conf\vanilla" -cg FreeSWITCHConfFiles -gg -scom -sreg -sfrag -srd -dr CONFLOCATION -var var.FreeSWITCHConfFilesDir -out "$(ProjectDir)Fragments\FreeSWITCHConfFiles.wxs" @@ -76,4 +82,4 @@ --> - + \ No newline at end of file diff --git a/w32/Setup/packages.config b/w32/Setup/packages.config new file mode 100644 index 0000000000..1479e99c37 --- /dev/null +++ b/w32/Setup/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/yum/freeswitch-release.spec b/yum/freeswitch-release.spec index b1c995163b..ce2e6657d7 100644 --- a/yum/freeswitch-release.spec +++ b/yum/freeswitch-release.spec @@ -1,6 +1,6 @@ Name: freeswitch-release Version: 1 -Release: 0 +Release: 6 Summary: FreeSWITCH Packages for Enterprise Linux repository configuration Group: System Environment/Base @@ -52,6 +52,8 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Sep 08 2015 Ken Rice - 5-0 +- Create New version for the 1.6 repository * Fri Jan 27 2012 Ken Rice - 5-0 - Replace GPG key with correct key, and update primary URLs * Wed Dec 21 2011 Ken Rice - 5-0 diff --git a/yum/freeswitch.repo b/yum/freeswitch.repo index f9722e2c82..3916bae582 100644 --- a/yum/freeswitch.repo +++ b/yum/freeswitch.repo @@ -1,6 +1,6 @@ [freeswitch] name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch -baseurl=http://files.freeswitch.org/yum/$releasever/$basearch +baseurl=http://files.freeswitch.org/yum-1.6/$releasever/$basearch #mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-5&arch=$basearch #failovermethod=priority enabled=1 @@ -9,7 +9,7 @@ gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-FREESWITCH [freeswitch-debuginfo] name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch - Debug -baseurl=http://files.freeswitch.org/yum/$releasever/$basearch/debug +baseurl=http://files.freeswitch.org/yum-1.6/$releasever/$basearch/debug #mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-debug-5&arch=$basearch #failovermethod=priority enabled=0 @@ -18,7 +18,7 @@ gpgcheck=1 [freeswitch-source] name=FreeSWITCH Packages for Enterprise Linux $releasever - $basearch - Source -baseurl=http://files.freeswitch.org/yum/$releasever/SRPMS +baseurl=http://files.freeswitch.org/yum-1.6/$releasever/SRPMS #mirrorlist=http://mirrors.freeswitch.org/mirrorlist?repo=freeswitch-source-5&arch=$basearch #failovermethod=priority enabled=0