]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
update verto with some fixes and enhancements with reconnection
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 17 Jul 2014 20:03:57 +0000 (01:03 +0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 17 Jul 2014 20:04:04 +0000 (01:04 +0500)
12 files changed:
configure.ac
html5/verto/demo/index.html
html5/verto/demo/js/verto-min.js
html5/verto/demo/verto.js
html5/verto/js/src/jquery.jsonrpcclient.js
html5/verto/js/src/jquery.verto.js
src/include/switch_types.h
src/include/switch_utils.h
src/mod/endpoints/mod_verto/mcast/mcast.c
src/mod/endpoints/mod_verto/mod_verto.c
src/mod/endpoints/mod_verto/mod_verto.h
src/switch_utils.c

index 52eda71b0b0f329939a29a346d0d464f2bf1e539..a1bff4b6ea29ef3990c7f823f1937fa9e025897b 100644 (file)
@@ -787,7 +787,7 @@ AC_PROG_GCC_TRADITIONAL
 AC_FUNC_MALLOC
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
-AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize posix_openpt])
+AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize posix_openpt poll])
 AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
 AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
 
index 724e92b96f5260e3fd55e88bd54a77575e4053dd..ca4c6b1f4745c1f29991383d140d84cb58c56dc8 100644 (file)
@@ -2,7 +2,7 @@
 <html>
   <head>
   <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link rel="stylesheet" href="css/jquery.mobile-1.3.2.min.css" />
+  <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.3/jquery.mobile.min.css"/>
   <link rel="stylesheet" type="text/css" href="css/jsontable.css" />
   <link rel="shortcut icon" href="favicon.ico" />
     <meta charset="utf-8" />
         <div id="errordisplay" style="font-weight:bold;font-size:18px;color:#ae0000"></div>
       </div>
 
-      <div id="online" align="center">
+      <div id="online" align="center" style="width:600px">
        <div id="text"></div>
        <div data-role="fieldcontain">
          <input type="text" id="ext"/><br>
     </div>
 
 
-    <script type="text/javascript" src="js/jquery-2.0.3.min.js"></script> 
-    <script type="text/javascript" src="js/jquery.mobile-1.3.2.min.js"></script> 
+    <script type="text/javascript" src="//code.jquery.com/jquery-2.1.1.min.js"></script> 
+    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquerymobile/1.4.3/jquery.mobile.min.js"></script> 
     <script type="text/javascript" src="js/jquery.json-2.4.min.js"></script>  
     <script type="text/javascript" src="js/jquery.cookie.js"></script>
-    <script type="text/javascript" src="js/jquery.dataTables.js"></script>
+    <script type="text/javascript" src="//cdn.datatables.net/1.10.1/js/jquery.dataTables.min.js"></script>
     <script type="text/javascript" src="js/verto-min.js"></script>
     
     <script type="text/javascript" src="verto.js"></script>
index 236d5b45baae14994ad94e23425ac333e39cce4a..d56d60da55699f2e153d089392286a460dd68b0c 100644 (file)
@@ -55,7 +55,7 @@ return{addAnswerSDP:function(sdp,cbSuccess,cbError){peer.setRemoteDescription(ne
 var video_constraints={mandatory:{},optional:[]};function getUserMedia(options){var n=navigator,media;n.getMedia=n.webkitGetUserMedia||n.mozGetUserMedia;n.getMedia(options.constraints||{audio:true,video:video_constraints},streaming,options.onerror||function(e){console.error(e);});function streaming(stream){var video=options.video;if(video){video[moz?'mozSrcObject':'src']=moz?stream:window.webkitURL.createObjectURL(stream);}
 if(options.onsuccess){options.onsuccess(stream);}
 media=stream;}
-return media;}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid:null,getSocket:function(onmessage_cb){return self._getSocket(onmessage_cb);}},options);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={};}
+return media;}})(jQuery);(function($){$.JsonRpcClient=function(options){var self=this;this.options=$.extend({ajaxUrl:null,socketUrl:null,onmessage:null,login:null,passwd:null,sessid: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);};}
@@ -70,12 +70,15 @@ return true;}
 $.JsonRpcClient.prototype.closeSocket=function(){if(self.socketReady()){this._ws_socket.onclose=function(w){console.log("Closing Socket")}
 this._ws_socket.close();}}
 $.JsonRpcClient.prototype.loginData=function(params){self.options.login=params.login;self.options.passwd=params.passwd;}
-$.JsonRpcClient.prototype.connectSocket=function(onmessage_cb){var self=this;if(!self.socketReady()){self.authing=false;this._ws_socket=new WebSocket(this.options.socketUrl);if(this._ws_socket){this._ws_socket.onmessage=onmessage_cb;this._ws_socket.onclose=function(w){if(!self.ws_sleep){self.ws_sleep=2;}
-self.ws_cnt=0;if(self.options.onWSClose){self.options.onWSClose(self);}
-console.error("Websocket Lost sleep: "+self.ws_sleep+"sec");setTimeout(function(){console.log("Attempting Reconnection....");self.connectSocket(onmessage_cb);},self.ws_sleep*1000);if(++self.ws_cnt>=150){self.ws_sleep=30;}}
-this._ws_socket.onopen=function(){this.ws_sleep=2;this.ws_cnt=0;if(self.options.onWSConnect){self.options.onWSConnect(self);}
+$.JsonRpcClient.prototype.connectSocket=function(onmessage_cb){var self=this;if(self.to){clearTimeout(self.to);}
+if(!self.socketReady()){self.authing=false;if(self._ws_socket){delete self._ws_socket;}
+self._ws_socket=new WebSocket(self.options.socketUrl);if(self._ws_socket){self._ws_socket.onmessage=onmessage_cb;self._ws_socket.onclose=function(w){if(!self.ws_sleep){self.ws_sleep=500;}
+if(self.options.onWSClose){self.options.onWSClose(self);}
+console.error("Websocket Lost "+self.ws_cnt+" sleep: "+self.ws_sleep+"msec");self.to=setTimeout(function(){console.log("Attempting Reconnection....");self.connectSocket(onmessage_cb);},self.ws_sleep);self.ws_cnt++;if(self.ws_sleep<3000&&(self.ws_cnt%100)==0){self.ws_sleep+=500;}}
+self._ws_socket.onopen=function(){if(self.to){clearTimeout(self.to);}
+self.ws_sleep=500;self.ws_cnt=0;if(self.options.onWSConnect){self.options.onWSConnect(self);}
 var req;while(req=$.JsonRpcClient.q.pop()){self._ws_socket.send(req);}}}}
-return this._ws_socket?true:false;}
+return self._ws_socket?true:false;}
 $.JsonRpcClient.prototype._getSocket=function(onmessage_cb){if(this.options.socketUrl===null||!("WebSocket"in window))return null;this.connectSocket(onmessage_cb);return this._ws_socket;};$.JsonRpcClient.q=[];$.JsonRpcClient.prototype._wsCall=function(socket,request,success_cb,error_cb){var request_json=$.toJSON(request);if(socket.readyState<1){self=this;$.JsonRpcClient.q.push(request_json);}
 else{socket.send(request_json);}
 if('id'in request&&typeof success_cb!=='undefined'){this._ws_callbacks[request.id]={request:request_json,request_obj:request,success_cb:success_cb,error_cb:error_cb};}};$.JsonRpcClient.prototype._wsOnMessage=function(event){var response;try{response=$.parseJSON(event.data);if(typeof response==='object'&&'jsonrpc'in response&&response.jsonrpc==='2.0'){if('result'in response&&this._ws_callbacks[response.id]){var success_cb=this._ws_callbacks[response.id].success_cb;delete this._ws_callbacks[response.id];success_cb(response.result,this);return;}
@@ -102,7 +105,7 @@ verto.purge();}});if(verto.options.ringFile&&verto.options.tag){verto.ringer=$("
 verto.rpcClient.call('login',{});};$.verto.prototype.loginData=function(params){verto.options.login=params.login;verto.options.passwd=params.passwd;verto.rpcClient.loginData(params);};$.verto.prototype.logout=function(msg){var verto=this;verto.rpcClient.closeSocket();verto.purge();};$.verto.prototype.login=function(msg){var verto=this;verto.logout();verto.rpcClient.call('login',{});};$.verto.prototype.message=function(msg){var verto=this;var err=0;if(!msg.to){console.error("Missing To");err++;}
 if(!msg.body){console.error("Missing Body");err++;}
 if(err){return false;}
-verto.sendMethod("verto.info",{msg:msg});return true;};$.verto.prototype.processReply=function(method,success,e){var verto=this;var i;console.log("Response: "+method,success,e);switch(method){case"verto.subscribe":for(i in e.unauthorizedChannels){drop_bad(verto,e.unauthorizedChannels[i]);}
+verto.sendMethod("verto.info",{msg:msg});return true;};$.verto.prototype.processReply=function(method,success,e){var verto=this;var i;switch(method){case"verto.subscribe":for(i in e.unauthorizedChannels){drop_bad(verto,e.unauthorizedChannels[i]);}
 for(i in e.subscribedChannels){mark_ready(verto,e.subscribedChannels[i]);}
 break;case"verto.unsubscribe":break;}};$.verto.prototype.sendMethod=function(method,params){var verto=this;verto.rpcClient.call(method,params,function(e){verto.processReply(method,true,e);},function(e){verto.processReply(method,false,e);});};function do_sub(verto,channel,obj){}
 function drop_bad(verto,channel){console.error("drop unauthorized channel: "+channel);delete verto.eventSUBS[channel];}
@@ -148,7 +151,7 @@ if(la.onChange){la.onChange(la,{serno:serno,action:"bootObj",data:val,redraw:tru
 if(la.checkSerno(serno)){var redraw=la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"add",index:index,key:key,data:val,redraw:redraw});}}};la.modify=function(serno,val,key,index){if(key===null||key===undefined){key=serno;}
 if(la.checkSerno(serno)){la._add(key,val,index);if(la.onChange){la.onChange(la,{serno:serno,action:"modify",key:key,data:val,index:index});}}};la.del=function(serno,key,index){if(key===null||key===undefined){key=serno;}
 if(la.checkSerno(serno)){if(index===null||index<0||index===undefined){index=la.indexOf(key);}
-var ok=la._del(key);if(ok&&la.onChange){la.onChange(la,{serno:serno,action:"del",key:key,index:index});}}};var eventHandler=function(v,e,la){var packet=e.data;console.error("READ:",packet);if(packet.name!=la.name){return;}
+var ok=la._del(key);if(ok&&la.onChange){la.onChange(la,{serno:serno,action:"del",key:key,index:index});}}};var eventHandler=function(v,e,la){var packet=e.data;if(packet.name!=la.name){return;}
 switch(packet.action){case"init":la.init(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"bootObj":la.bootObj(packet.wireSerno,packet.data);break;case"add":la.add(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);break;case"modify":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.modify(packet.wireSerno,packet.data,packet.hashKey,packet.arrIndex);}
 break;case"del":if(!(packet.arrIndex||packet.hashKey)){console.error("Invalid Packet",packet);}else{la.del(packet.wireSerno,packet.hashKey,packet.arrIndex);}
 break;case"clear":la.clear();break;case"reorder":la.reorder(packet.wireSerno,packet.order);break;default:if(la.checkSerno(packet.wireSerno)){if(la.onChange){la.onChange(la,{serno:packet.wireSerno,action:packet.action,data:packet.data});}}
@@ -165,7 +168,7 @@ try{switch(args.action){case"bootObj":if(!args.data){console.error("missing data
 dt.fnClearTable();dt.fnAddData(obj.asArray());dt.fnAdjustColumnSizing();break;case"add":if(!args.data){console.error("missing data");return;}
 if(args.redraw>-1){dt.fnClearTable();dt.fnAddData(obj.asArray());}else{dt.fnAddData(args.data);}
 dt.fnAdjustColumnSizing();break;case"modify":if(!args.data){return;}
-console.debug(args,index);dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;}
+dt.fnUpdate(args.data,index);dt.fnAdjustColumnSizing();break;case"del":dt.fnDeleteRow(index);dt.fnAdjustColumnSizing();break;case"clear":dt.fnClearTable();break;case"reorder":dt.fnClearTable();dt.fnAddData(obj.asArray());break;case"hide":jq.hide();break;case"show":jq.show();break;}}catch(err){console.error("ERROR: "+err);iserr++;}
 if(iserr){obj.errs++;if(obj.errs<3){obj.bootstrap(obj.user_obj);}}else{obj.errs=0;}};la.onChange(la,{action:"init"});};var CONFMAN_SERNO=1;$.verto.confMan=function(verto,params){var confMan=this;conf
 confMan.params=$.extend({tableID:null,statusID:null,mainModID:null,dialog:null,hasVid:false,laData:null,onBroadcast:null,onLaChange:null,onLaRow:null},params);confMan.verto=verto;confMan.serno=CONFMAN_SERNO++;function genMainMod(jq){var play_id="play_"+confMan.serno;var stop_id="stop_"+confMan.serno;var recording_id="recording_"+confMan.serno;var rec_stop_id="recording_stop"+confMan.serno;var div_id="confman_"+confMan.serno;var html="<div id='"+div_id+"'><br>"+"<button class='ctlbtn' id='"+play_id+"'>Play</button>"+"<button class='ctlbtn' id='"+stop_id+"'>Stop</button>"+"<button class='ctlbtn' id='"+recording_id+"'>Record</button>"+"<button class='ctlbtn' id='"+rec_stop_id+"'>Record Stop</button>"
 +"<br><br></div>";jq.html(html);$("#"+play_id).click(function(){var file=prompt("Please enter file name","");confMan.modCommand("play",null,file);});$("#"+stop_id).click(function(){confMan.modCommand("stop",null,"all");});$("#"+recording_id).click(function(){var file=prompt("Please enter file name","");confMan.modCommand("recording",null,["start",file]);});$("#"+rec_stop_id).click(function(){confMan.modCommand("recording",null,["stop","all"]);});}
@@ -192,12 +195,12 @@ dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,tr
 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.error("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.info("Dialog "+dialog.callID+": state change from "+dialog.state.name+" to "+state.name);dialog.lastState=dialog.state;dialog.state=state;if(!dialog.causeCode){dialog.causeCode=16;}
 if(!dialog.cause){dialog.cause="NORMAL CLEARING";}
 if(dialog.callbacks.onDialogState){dialog.callbacks.onDialogState(this);}
 switch(dialog.state){case $.verto.enum.state.purge:dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.hangup:if(dialog.lastState.val>$.verto.enum.state.requesting.val&&dialog.lastState.val<$.verto.enum.state.hangup.val){dialog.sendMethod("verto.bye",{});}
 dialog.setState($.verto.enum.state.destroy);break;case $.verto.enum.state.destroy:delete verto.dialogs[dialog.callID];dialog.rtc.stop();break;}
-return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;console.log("Response: "+method+" State:"+dialog.state.name,success,e);switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();}
+return true;};$.verto.dialog.prototype.processReply=function(method,success,e){var dialog=this;switch(method){case"verto.answer":case"verto.attach":if(success){dialog.setState($.verto.enum.state.active);}else{dialog.hangup();}
 break;case"verto.invite":if(success){dialog.setState($.verto.enum.state.trying);}else{dialog.setState($.verto.enum.state.destroy);}
 break;case"verto.bye":dialog.hangup();break;case"verto.modify":if(e.holdState){if(e.holdState=="held"){if(dialog.state!=$.verto.enum.state.held){dialog.setState($.verto.enum.state.held);}}else if(e.holdState=="active"){if(dialog.state!=$.verto.enum.state.active){dialog.setState($.verto.enum.state.active);}}}
 if(success){}
index e4017e7dcbcb005318dc0f3a96621eb7b0247e9c..af9392bbfaf3714ae86d2df291053433cc48d961 100644 (file)
@@ -4,6 +4,9 @@ var confMan = null;
 var $display = $("#display");
 var verto;
 var ringing = false;
+var autocall = false;
+
+$( ".selector" ).pagecontainer({ "theme": "a" });
 
 function display(msg) {
     $("#calltitle").html(msg);
@@ -19,13 +22,11 @@ function clearConfMan() {
 }
 
 function goto_dialog(where) {
-    $.mobile.changePage("#dialog-" + where, {
-        role: "dialog"
-    });
+    $( ":mobile-pagecontainer" ).pagecontainer( "change", "#dialog-" + where, { role: "dialog" } );
 }
 
-function goto_page(where) {
-    $.mobile.changePage("#page-" + where);
+function goto_page(where, force) {
+    $( ":mobile-pagecontainer" ).pagecontainer( "change", "#page-" + where);
 }
 
 var first_login = false;
@@ -58,7 +59,7 @@ var callbacks = {
 
         switch (msg) {
         case $.verto.enum.message.pvtEvent:
-            console.error("pvtEvent", data.pvtData.action);
+            //console.error("pvtEvent", data.pvtData.action);
             if (data.pvtData) {
                 switch (data.pvtData.action) {
 
@@ -139,6 +140,10 @@ var callbacks = {
 
             break;
 
+        case $.verto.enum.state.trying:
+            display("Calling: " + d.cidString());
+            goto_page("incall");
+           break;
         case $.verto.enum.state.early:
         case $.verto.enum.state.active:
             display("Talking to: " + d.cidString());
@@ -168,14 +173,22 @@ var callbacks = {
         if (success) {
             online(true);
 
+           /*
             verto.subscribe("presence", {
                 handler: function(v, e) {
                     console.error("PRESENCE:", e);
                 }
-            });
+               });
+           */
+
             if (!window.location.hash) {
                 goto_page("main");
             }
+
+           if (autocall) {
+               autocall = false;
+               docall();
+           }
         } else {
             goto_page("login");
             goto_dialog("login-error");
@@ -193,7 +206,7 @@ var callbacks = {
     },
 
     onEvent: function(v, e) {
-        console.debug("w00t", e);
+        console.debug("GOT EVENT", e);
     },
 };
 
@@ -246,7 +259,7 @@ $("#webcam").click(function() {
     check_vid();
 });
 
-$("#callbtn").click(function() {
+function docall() {
     $('#ext').trigger('change');
 
     if (cur_call) {
@@ -262,6 +275,10 @@ $("#callbtn").click(function() {
         useVideo: check_vid(),
         useStereo: $("#use_stereo").is(':checked')
     });
+}
+
+$("#callbtn").click(function() {
+    docall();
 });
 
 function pop(id, cname, dft) {
@@ -366,58 +383,43 @@ function init() {
 }
 
 $(document).ready(function() {
-    var autocall = false;
     var hash = window.location.hash.substring(1);    
 
     if (hash && hash.indexOf("page-") == -1) {
        window.location.hash = "";
+       $("#ext").val(hash);
        autocall = true;
     }
 
     init();
 
-    $("#page-incall").on("pagebeforechange", function(event) {});
+});
 
-    if (autocall) {
-       $("#ext").val(hash);
-       $("#callbtn").trigger("click");
-    }
 
+var lastTo = 0;
 
-});
+$(document).bind("pagecontainerchange", function(e, data) {
 
-$(document).bind("pagebeforechange", function(e, data) {
-    if (typeof(data.toPage) !== "string") {
-        return;
+    if (lastTo) {
+       clearTimeout(lastTo);
     }
 
     switch (window.location.hash) {
 
     case "#page-incall":
-
-        console.error(e, data);
-        setTimeout(function() {
+        lastTo = setTimeout(function() {
             if (!cur_call) {
                 goto_page("main");
             }
-        },
-        10000);
-        break;
+        }, 1000);
 
-    case "#page-main":
-
-        console.error(e, data);
-        setTimeout(function() {
-            if (cur_call && !ringing) {
-                goto_page("incall");
-            }
-        },
-        2000);
         break;
 
+    case "#page-main":
+       break;
     case "#page-login":
 
-        setTimeout(function() {
+        lastTo = setTimeout(function() {
             if (online_visible) {
                 goto_page("main");
             }
@@ -426,3 +428,4 @@ $(document).bind("pagebeforechange", function(e, data) {
         break;
     }
 });
+
index c5ff8d7422713b7e575a5ef3554f71bc7a326311..9505cd14deadf7833d6e4944338afbded524f00a 100644 (file)
@@ -74,6 +74,8 @@
       getSocket   : function(onmessage_cb) { return self._getSocket(onmessage_cb); }
     }, options);
       
+      self.ws_cnt = 0;
+
     // Declare an instance version of the onmessage callback to wrap 'this'.
     this.wsOnMessage = function(event) { self._wsOnMessage(event); };
   };
   $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) {
       var self = this;
 
+      if (self.to) {
+         clearTimeout(self.to);
+      }
+
       if (!self.socketReady()) {
          self.authing = false;
+
+         if (self._ws_socket) {
+             delete self._ws_socket;
+         }
+
          // No socket, or dying socket, let's get a new one.
-         this._ws_socket = new WebSocket(this.options.socketUrl);
+         self._ws_socket = new WebSocket(self.options.socketUrl);
          
-         if (this._ws_socket) {
+         if (self._ws_socket) {
              // Set up onmessage handler.
-             this._ws_socket.onmessage = onmessage_cb;
-             this._ws_socket.onclose = function (w) {
+             self._ws_socket.onmessage = onmessage_cb;
+             self._ws_socket.onclose = function (w) {
                  if (!self.ws_sleep) {
-                     self.ws_sleep = 2;
+                     self.ws_sleep = 500;
                  }
 
-                 self.ws_cnt = 0;
-                 
                  if (self.options.onWSClose) {
                      self.options.onWSClose(self);
                  }
 
-                 console.error("Websocket Lost sleep: " + self.ws_sleep + "sec");
-
-                 setTimeout(function() {
+                 console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec");
+                 
+                 self.to = setTimeout(function() {
                      console.log("Attempting Reconnection....");
                      self.connectSocket(onmessage_cb);
-                 }, self.ws_sleep * 1000);
+                 }, self.ws_sleep);
                  
+                 self.ws_cnt++;
 
-                 if (++self.ws_cnt >= 150) {
-                     self.ws_sleep = 30;
+                 if (self.ws_sleep < 3000 && (self.ws_cnt % 100) == 0) {
+                     self.ws_sleep += 500;
                  }
              }
 
              // Set up sending of message for when the socket is open.
-             this._ws_socket.onopen = function() {
-                 this.ws_sleep = 2;      
-                 this.ws_cnt = 0;
+             self._ws_socket.onopen = function() {
+                 if (self.to) {
+                     clearTimeout(self.to);
+                 }
+                 self.ws_sleep = 500;    
+                 self.ws_cnt = 0;
                  if (self.options.onWSConnect) {
                      self.options.onWSConnect(self);
                  }
          }
       }      
       
-      return this._ws_socket ? true : false;
+      return self._ws_socket ? true : false;
   }
 
   $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) {
index e56503dd3f5641b3cea0a18315672d5b4618f429..029afc32a1caab493216f6fb1ae75eff289e985a 100644 (file)
         var verto = this;
        var i;
 
-        console.log("Response: " + method, success, e);
+        //console.log("Response: " + method, success, e);
 
         switch (method) {
         case "verto.subscribe":
         var eventHandler = function(v, e, la) {
             var packet = e.data;
 
-            console.error("READ:", packet);
+            //console.error("READ:", packet);
 
             if (packet.name != la.name) {
                 return;
                     if (!args.data) {
                         return;
                     }
-                    console.debug(args, index);
+                    //console.debug(args, index);
                     dt.fnUpdate(args.data, index);
                     dt.fnAdjustColumnSizing();
                     break;
             return false;
         }
 
-        console.error("Dialog " + dialog.callID + ": state change from " + dialog.state.name + " to " + state.name);
+        console.info("Dialog " + dialog.callID + ": state change from " + dialog.state.name + " to " + state.name);
 
         dialog.lastState = dialog.state;
         dialog.state = state;
     $.verto.dialog.prototype.processReply = function(method, success, e) {
         var dialog = this;
 
-        console.log("Response: " + method + " State:" + dialog.state.name, success, e);
+        //console.log("Response: " + method + " State:" + dialog.state.name, success, e);
 
         switch (method) {
 
index 96a484e6a0fa8e4119df14f93e19fe9df0400ddd..8b2fd99b9ff1357b813bc3be28a61222a68d349b 100644 (file)
@@ -2024,8 +2024,10 @@ typedef enum {
 
 #ifdef WIN32
 typedef SOCKET switch_os_socket_t;
+#define SWITCH_SOCK_INVALID INVALID_SOCKET
 #else
 typedef int switch_os_socket_t;
+#define SWITCH_SOCK_INVALID -1
 #endif
 
 typedef struct apr_pool_t switch_memory_pool_t;
@@ -2385,7 +2387,16 @@ typedef enum {
        ICE_CONTROLLED = (1 << 2)
 } switch_core_media_ice_type_t;
 
-
+typedef enum {
+       SWITCH_POLL_READ = (1 << 0),
+       SWITCH_POLL_WRITE = (1 << 1),
+       SWITCH_POLL_ERROR = (1 << 2),
+       SWITCH_POLL_HUP = (1 << 3),
+       SWITCH_POLL_RDNORM = (1 << 4),
+       SWITCH_POLL_RDBAND = (1 << 5),
+       SWITCH_POLL_PRI = (1 << 6),
+       SWITCH_POLL_INVALID = (1 << 7)
+} switch_poll_t;
 
 SWITCH_END_EXTERN_C
 #endif
index 751b94632c46e87825adb9c423f29537e7e99cde..fc6c06861b9490f2f4982c6331f27841534908df 100644 (file)
@@ -1066,7 +1066,7 @@ SWITCH_DECLARE(unsigned long) switch_atoul(const char *nptr);
  * \return     Pointer to message buffer, returning error message or "Unknown error xxx" if none found
  */
 SWITCH_DECLARE(char *) switch_strerror_r(int errnum, char *buf, switch_size_t buflen);
-
+SWITCH_DECLARE(int) switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags);
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:
index 71080b06773ec4084a848d45236a4554e2521bf5..9a2371b8ce19e702aa7c44b9d70b5f26bb31c5c5 100644 (file)
@@ -44,6 +44,7 @@
 #include <unistd.h>
 #include "mcast.h"
 #include <poll.h>
+#include <switch_utils.h>
 
 int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle, mcast_flag_t flags)
 {
@@ -151,7 +152,6 @@ ssize_t mcast_socket_send(mcast_handle_t *handle, void *data, size_t datalen)
 ssize_t mcast_socket_recv(mcast_handle_t *handle, void *data, size_t datalen, int ms)
 {
        socklen_t addrlen = sizeof(handle->recv_addr);
-       int r;
 
        if (data == NULL || datalen == 0) {
                data = handle->buffer;
@@ -159,16 +159,9 @@ ssize_t mcast_socket_recv(mcast_handle_t *handle, void *data, size_t datalen, in
        }
 
        if (ms > 0) {
-               struct pollfd pfds[1];
-               
-               pfds[0].fd = handle->sock;
-               pfds[0].events = POLLIN|POLLERR;
-               
-               if ((r = poll(pfds, 1, ms)) <= 0) {
-                       return r;
-               }
+               int pflags = switch_wait_sock(handle->sock, ms, SWITCH_POLL_READ | SWITCH_POLL_ERROR | SWITCH_POLL_HUP);
 
-               if (pfds[0].revents & POLLERR) {
+               if ((pflags & SWITCH_POLL_ERROR) || (pflags & SWITCH_POLL_HUP)) {
                        return -1;
                }
        }
index 74819c87d00dbb6e3060d31543e72172a5e93b74..a5897fbbb685825c6050d23d000fca36d43b0cf6 100644 (file)
@@ -554,6 +554,29 @@ static switch_ssize_t ws_write_json(jsock_t *jsock, cJSON **json, switch_bool_t
        return r;
 }
 
+static switch_status_t jsock_queue_event(jsock_t *jsock, cJSON **json)
+{
+       switch_status_t status = SWITCH_STATUS_FALSE;
+       
+       if (switch_queue_trypush(jsock->event_queue, *json) == SWITCH_STATUS_SUCCESS) {
+               status = SWITCH_STATUS_SUCCESS;
+               if (jsock->lost_events) {
+                       int le = jsock->lost_events;
+                       jsock->lost_events = 0;
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Lost %d json events!\n", le);
+               }
+       } else {
+               if (++jsock->lost_events > MAX_MISSED) {
+                       jsock->drop++;
+               }
+               cJSON_Delete(*json);
+       }
+
+       *json = NULL;
+
+       return status;
+}
+
 
 static void write_event(const char *event_channel, jsock_t *use_jsock, cJSON *event)
 {
@@ -569,7 +592,8 @@ static void write_event(const char *event_channel, jsock_t *use_jsock, cJSON *ev
                                params = cJSON_Duplicate(event, 1);
                                cJSON_AddItemToObject(params, "eventSerno", cJSON_CreateNumber(np->serno++));
                                msg = jrpc_new_req("verto.event", NULL, &params);
-                               ws_write_json(np->jsock, &msg, SWITCH_TRUE);
+                               //ws_write_json(np->jsock, &msg, SWITCH_TRUE);
+                               jsock_queue_event(np->jsock, &msg);
                        }
                }
        }
@@ -601,7 +625,8 @@ static void jsock_send_event(cJSON *event)
                cJSON *msg = NULL, *params;
                params = cJSON_Duplicate(event, 1);
                msg = jrpc_new_req("verto.event", NULL, &params);
-               ws_write_json(use_jsock, &msg, SWITCH_TRUE); 
+               //ws_write_json(use_jsock, &msg, SWITCH_TRUE); 
+               jsock_queue_event(use_jsock, &msg);
                switch_thread_rwlock_unlock(use_jsock->rwlock);
                use_jsock = NULL;
                return;
@@ -747,6 +772,7 @@ static void check_permissions(jsock_t *jsock, switch_xml_t x_user, cJSON *params
                }
        }
 
+
        set_perm(allowed_methods, &jsock->allowed_methods);
        set_perm(allowed_jsapi, &jsock->allowed_jsapi);
        set_perm(allowed_fsapi, &jsock->allowed_fsapi);
@@ -1186,6 +1212,19 @@ static switch_status_t process_input(jsock_t *jsock, uint8_t *data, switch_ssize
        return status;
 }
 
+static void jsock_check_event_queue(jsock_t *jsock)
+{
+       void *pop;
+       int this_pass = switch_queue_size(jsock->event_queue);
+
+       switch_mutex_lock(jsock->write_mutex);
+       while(this_pass-- > 0 && switch_queue_trypop(jsock->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+               cJSON *json = (cJSON *) pop;
+               ws_write_json(jsock, &json, SWITCH_TRUE);
+       }
+       switch_mutex_unlock(jsock->write_mutex);
+}
+
 static void client_run(jsock_t *jsock)
 {
 
@@ -1199,43 +1238,31 @@ static void client_run(jsock_t *jsock)
        }
 
        while(jsock->profile->running) {
-               struct pollfd pfds[1];
-               int res;
-               
-               memset(&pfds[0], 0, sizeof(pfds[0]));
+               int pflags = switch_wait_sock(jsock->client_socket, 50, SWITCH_POLL_READ | SWITCH_POLL_ERROR | SWITCH_POLL_HUP);
 
-               pfds[0].fd = jsock->client_socket;
-               pfds[0].events = POLLIN|POLLERR|POLLHUP|POLLRDNORM|POLLRDBAND|POLLPRI;
+               if (jsock->drop) {
+                       die("%s Dropping Connection\n", jsock->name);
+               }
 
-               
-               if ((res = poll(pfds, 1, -1)) < 0) {
+               if (pflags < 0) {
                        if (errno != EINTR) {
                                die("%s POLL FAILED\n", jsock->name);
                        }
                }
 
-               if (res < 0) {
+               if (pflags & SWITCH_POLL_ERROR) {
                        die("%s POLL ERROR\n", jsock->name);
                }
 
-               if (jsock->drop) {
-                       die("%s Dropping Connection\n", jsock->name);
-               }
-
-
-               if (pfds[0].revents & POLLERR) {
-                       die("%s POLL ERROR\n", jsock->name);
-               }
-
-               if (pfds[0].revents & POLLHUP) {
+               if (pflags & SWITCH_POLL_HUP) {
                        die("%s POLL HANGUP DETECTED\n", jsock->name);
                }
 
-               if (pfds[0].revents & POLLNVAL) {
+               if (pflags & SWITCH_POLL_INVALID) {
                        die("%s POLL INVALID SOCKET\n", jsock->name);
                }
 
-               if (pfds[0].revents & POLLIN) {
+               if (pflags & SWITCH_POLL_READ) {
                        switch_ssize_t bytes;
                        ws_opcode_t oc;
                        uint8_t *data;
@@ -1257,6 +1284,8 @@ static void client_run(jsock_t *jsock)
                                        switch_set_flag(jsock, JPFLAG_CHECK_ATTACH);
                                }
                        }
+               } else {
+                       jsock_check_event_queue(jsock);
                }
        }
 
@@ -1268,6 +1297,18 @@ static void client_run(jsock_t *jsock)
        return;
 }
 
+static void jsock_flush(jsock_t *jsock)
+{
+       void *pop;
+
+       switch_mutex_lock(jsock->write_mutex);
+       while(switch_queue_trypop(jsock->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+               cJSON *json = (cJSON *) pop;
+               cJSON_Delete(json);
+       }
+       switch_mutex_unlock(jsock->write_mutex);
+}
+
 static void *SWITCH_THREAD_FUNC client_thread(switch_thread_t *thread, void *obj)
 {
        jsock_t *jsock = (jsock_t *) obj;
@@ -1302,6 +1343,7 @@ static void *SWITCH_THREAD_FUNC client_thread(switch_thread_t *thread, void *obj
        switch_event_destroy(&jsock->allowed_jsapi);
        switch_event_destroy(&jsock->allowed_event_channels);
 
+       jsock_flush(jsock);
 
     switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Ending client thread.\n", jsock->name);
        switch_thread_rwlock_wrlock(jsock->rwlock);
@@ -1772,7 +1814,8 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_
                                        jmsg = jrpc_new_req("verto.display", tech_pvt->call_id, &params);
                                        cJSON_AddItemToObject(params, "display_name", cJSON_CreateString(name));
                                        cJSON_AddItemToObject(params, "display_number", cJSON_CreateString(number));
-                                       ws_write_json(jsock, &jmsg, SWITCH_TRUE);
+                                       //ws_write_json(jsock, &jmsg, SWITCH_TRUE);
+                                       jsock_queue_event(jsock, &jmsg);
                                }
 
                                switch_thread_rwlock_unlock(jsock->rwlock);
@@ -2709,7 +2752,8 @@ static switch_bool_t event_channel_check_auth(jsock_t *jsock, const char *event_
                        }
                }
 
-               if (!(switch_event_get_header(jsock->allowed_event_channels, event_channel) || 
+               if ((!globals.enable_fs_events && (!strcasecmp(event_channel, "FSevent") || (main_event_channel && !strcasecmp(main_event_channel, "FSevent")))) || 
+                       !(switch_event_get_header(jsock->allowed_event_channels, event_channel) || 
                          (main_event_channel && switch_event_get_header(jsock->allowed_event_channels, main_event_channel)))) {
                        ok = SWITCH_FALSE;
                }
@@ -3062,6 +3106,8 @@ static int start_jsock(verto_profile_t *profile, int sock)
        td->pool = pool;
 
        switch_mutex_init(&jsock->write_mutex, SWITCH_MUTEX_NESTED, jsock->pool);
+       switch_mutex_init(&jsock->filter_mutex, SWITCH_MUTEX_NESTED, jsock->pool);
+       switch_queue_create(&jsock->event_queue, MAX_QUEUE_LEN, jsock->pool);
        switch_thread_rwlock_create(&jsock->rwlock, jsock->pool);
        switch_thread_pool_launch_thread(&td);
 
@@ -3561,6 +3607,8 @@ static switch_status_t parse_config(const char *cf)
                                }
                        } else if (!strcasecmp(var, "enable-presence") && val) {
                                globals.enable_presence = switch_true(val);
+                       } else if (!strcasecmp(var, "enable-fs-events") && val) {
+                               globals.enable_fs_events = switch_true(val);
                        } else if (!strcasecmp(var, "detach-timeout-sec") && val) {
                                int tmp = atoi(val);
                                if (tmp > 0) {
@@ -3917,9 +3965,10 @@ static int verto_send_chat(const char *uid, const char *call_id, cJSON *msg)
                        jsock_t *jsock;
 
                        if ((jsock = get_jsock(tech_pvt->jsock_uuid))) {
-                               if (ws_write_json(jsock, &msg, SWITCH_FALSE) <= 0) {
-                                       switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
-                               }
+                               jsock_queue_event(jsock, &msg);
+                               //if (ws_write_json(jsock, &msg, SWITCH_FALSE) <= 0) {
+                               //      switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+                               //}
                                switch_thread_rwlock_unlock(jsock->rwlock);
                                done = 1;
                        }
@@ -3939,7 +3988,8 @@ static int verto_send_chat(const char *uid, const char *call_id, cJSON *msg)
                
                for(jsock = profile->jsock_head; jsock; jsock = jsock->next) {
                        if (!strcmp(uid, jsock->uid)) {
-                               ws_write_json(jsock, &msg, SWITCH_FALSE);
+                               //ws_write_json(jsock, &msg, SWITCH_FALSE);
+                               jsock_queue_event(jsock, &msg);
                                hits++;
                        }
                }
@@ -4351,6 +4401,10 @@ static void presence_event_handler(switch_event_t *event)
        char *event_channel;
        const char *presence_id = switch_event_get_header(event, "channel-presence-id");
 
+       if (!globals.running) {
+               return;
+       }
+
        if (!globals.enable_presence || zstr(presence_id)) {
                return;
        }
@@ -4388,6 +4442,38 @@ static void presence_event_handler(switch_event_t *event)
 
 }
 
+static void event_handler(switch_event_t *event)
+{
+       cJSON *msg = NULL, *data = NULL;
+       char *event_channel;
+
+       if (!globals.enable_fs_events) {
+               return;
+       }
+
+       switch_event_serialize_json_obj(event, &data);
+
+       msg = cJSON_CreateObject();
+
+       if (event->event_id == SWITCH_EVENT_CUSTOM) {
+               const char *subclass = switch_event_get_header(event, "Event-Subclass");
+               event_channel = switch_mprintf("FSevent.%s::%s", switch_event_name(event->event_id), subclass);
+               switch_tolower_max(event_channel + 8);
+       } else {
+               event_channel = switch_mprintf("FSevent.%s", switch_event_name(event->event_id));
+               switch_tolower_max(event_channel + 8);
+       }
+       
+       cJSON_AddItemToObject(msg, "eventChannel", cJSON_CreateString(event_channel));
+       cJSON_AddItemToObject(msg, "data", data);
+
+       /* comment broadcasting globally and change to only within the module cos FS events are heavy */
+       //switch_event_channel_broadcast(event_channel, &msg, __FILE__, NO_EVENT_CHANNEL_ID);
+       verto_broadcast(event_channel, msg, __FILE__, NO_EVENT_CHANNEL_ID);cJSON_Delete(msg);
+
+       free(event_channel);
+
+}
 
 /* Macro expands to: switch_status_t mod_verto_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
 SWITCH_MODULE_LOAD_FUNCTION(mod_verto_load)
@@ -4403,6 +4489,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_verto_load)
        globals.pool = pool;
        globals.ready = SIGUSR1;
        globals.enable_presence = SWITCH_TRUE;
+       globals.enable_fs_events = SWITCH_FALSE;
 
        switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
 
@@ -4423,8 +4510,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_verto_load)
        globals.detach_timeout = 120;
 
        
-       switch_event_bind(modname, SWITCH_EVENT_CHANNEL_CALLSTATE, SWITCH_EVENT_SUBCLASS_ANY, presence_event_handler, NULL);
-
 
 
        memset(&json_GLOBALS, 0, sizeof(json_GLOBALS));
@@ -4462,6 +4547,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_verto_load)
 
        switch_core_register_secondary_recover_callback(modname, verto_recover_callback);
 
+       if (globals.enable_presence) {
+               switch_event_bind(modname, SWITCH_EVENT_CHANNEL_CALLSTATE, SWITCH_EVENT_SUBCLASS_ANY, presence_event_handler, NULL);
+       }
+
+       if (globals.enable_fs_events) {
+               if (switch_event_bind(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
+                       return SWITCH_STATUS_GENERR;
+               }
+       }
+
        run_profiles();
 
        /* indicate that the module should continue to be loaded */
@@ -4478,6 +4574,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_verto_shutdown)
 
        switch_event_channel_unbind(NULL, verto_broadcast);
        switch_event_unbind_callback(presence_event_handler);
+       switch_event_unbind_callback(event_handler);
 
        switch_core_unregister_secondary_recover_callback(modname);
        do_shutdown();
index d7df38bf154d5ab34466a5064ec4d83fbf9f9b79..84a98649b9c378b269de1491e73b016ab2bd79d2 100644 (file)
@@ -51,6 +51,9 @@
 #include <openssl/ssl.h>
 #include "mcast.h"
 
+#define MAX_QUEUE_LEN 100000
+#define MAX_MISSED 500
+
 #define MAXPENDING 10000
 #define STACK_SIZE 80 * 1024
 
@@ -73,7 +76,10 @@ typedef enum {
 typedef enum {
        JPFLAG_INIT = (1 << 0),
        JPFLAG_AUTHED = (1 << 1),
-       JPFLAG_CHECK_ATTACH = (1 << 2)
+       JPFLAG_CHECK_ATTACH = (1 << 2),
+       JPFLAG_EVENTS = (1 << 3),
+       JPFLAG_AUTH_EVENTS = (1 << 4),
+       JPFLAG_ALL_EVENTS_AUTHED = (1 << 5)
 } jpflag_t;
 
 struct verto_profile_s;
@@ -114,10 +120,14 @@ struct jsock_s {
        switch_thread_rwlock_t *rwlock;
        
        switch_mutex_t *write_mutex;
+       switch_mutex_t *filter_mutex;
 
        switch_event_t *params;
        switch_event_t *vars;
 
+       switch_queue_t *event_queue;
+       int lost_events;
+
        struct jsock_s *next;
 };
 
@@ -231,6 +241,7 @@ struct globals_s {
        int ready;
        int profile_threads;
        int enable_presence;
+       int enable_fs_events;
 
        switch_hash_t *jsock_hash;
        switch_mutex_t *jsock_mutex;
index 66aa2e56d8925b791bf6e8856a401dc93cab0c5f..a45187b2cc1d742f26fe34e5e5932cb7ad34c0da 100644 (file)
@@ -2491,6 +2491,178 @@ SWITCH_DECLARE(char *) switch_util_quote_shell_arg_pool(const char *string, swit
        return dest;
 }
 
+
+
+#ifdef HAVE_POLL
+#include <poll.h>
+SWITCH_DECLARE(int) switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags)
+{
+       struct pollfd pfds[2] = { { 0 } };
+       int s = 0, r = 0;
+
+       if (sock == SWITCH_SOCK_INVALID) {
+               return SWITCH_SOCK_INVALID;
+       }       
+
+       pfds[0].fd = sock;
+
+
+       if ((flags & SWITCH_POLL_READ)) {
+               pfds[0].events |= POLLIN;
+       }
+
+       if ((flags & SWITCH_POLL_WRITE)) {
+               pfds[0].events |= POLLOUT;
+       }
+
+       if ((flags & SWITCH_POLL_ERROR)) {
+               pfds[0].events |= POLLERR;
+       }
+
+       if ((flags & SWITCH_POLL_HUP)) {
+               pfds[0].events |= POLLHUP;
+       }
+
+       if ((flags & SWITCH_POLL_RDNORM)) {
+               pfds[0].events |= POLLRDNORM;
+       }
+
+       if ((flags & SWITCH_POLL_RDBAND)) {
+               pfds[0].events |= POLLRDBAND;
+       }
+
+       if ((flags & SWITCH_POLL_PRI)) {
+               pfds[0].events |= POLLPRI;
+       }
+       
+       s = poll(pfds, 1, ms);
+
+       if (s < 0) {
+               r = s;
+       } else if (s > 0) {
+               if ((pfds[0].revents & POLLIN)) {
+                       r |= SWITCH_POLL_READ;
+               }
+               if ((pfds[0].revents & POLLOUT)) {
+                       r |= SWITCH_POLL_WRITE;
+               }
+               if ((pfds[0].revents & POLLERR)) {
+                       r |= SWITCH_POLL_ERROR;
+               }
+               if ((pfds[0].revents & POLLHUP)) {
+                       r |= SWITCH_POLL_HUP;
+               }
+               if ((pfds[0].revents & POLLRDNORM)) {
+                       r |= SWITCH_POLL_RDNORM;
+               }
+               if ((pfds[0].revents & POLLRDBAND)) {
+                       r |= SWITCH_POLL_RDBAND;
+               }
+               if ((pfds[0].revents & POLLPRI)) {
+                       r |= SWITCH_POLL_PRI;
+               }
+               if ((pfds[0].revents & POLLNVAL)) {
+                       r |= SWITCH_POLL_INVALID;
+               }
+       }
+
+       return r;
+
+}
+
+#else
+/* use select instead of poll */
+SWITCH_DECLARE(int) switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags)
+{
+       int s = 0, r = 0;
+       fd_set *rfds;
+       fd_set *wfds;
+       fd_set *efds;
+       struct timeval tv;
+
+       if (sock == SWITCH_SOCK_INVALID) {
+               return SWITCH_SOCK_INVALID;
+       }
+
+       rfds = malloc(sizeof(fd_set));
+       wfds = malloc(sizeof(fd_set));
+       efds = malloc(sizeof(fd_set));
+
+       FD_ZERO(rfds);
+       FD_ZERO(wfds);
+       FD_ZERO(efds);
+
+#ifndef WIN32
+       /* Wouldn't you rather know?? */
+       assert(sock <= FD_SETSIZE);
+#endif
+       
+       if ((flags & SWITCH_POLL_READ)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+       FD_SET(sock, rfds);
+#pragma warning( pop ) 
+#else
+       FD_SET(sock, rfds);
+#endif
+       }
+
+       if ((flags & SWITCH_POLL_WRITE)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+       FD_SET(sock, wfds);
+#pragma warning( pop ) 
+#else
+       FD_SET(sock, wfds);
+#endif
+       }
+
+       if ((flags & SWITCH_POLL_ERROR)) {
+
+#ifdef WIN32
+#pragma warning( push )
+#pragma warning( disable : 4127 )
+       FD_SET(sock, efds);
+#pragma warning( pop ) 
+#else
+       FD_SET(sock, efds);
+#endif
+       }
+
+       tv.tv_sec = ms / 1000;
+       tv.tv_usec = (ms % 1000) * ms;
+       
+       s = select(sock + 1, (flags & SWITCH_POLL_READ) ? rfds : NULL, (flags & SWITCH_POLL_WRITE) ? wfds : NULL, (flags & SWITCH_POLL_ERROR) ? efds : NULL, &tv);
+
+       if (s < 0) {
+               r = s;
+       } else if (s > 0) {
+               if ((flags & SWITCH_POLL_READ) && FD_ISSET(sock, rfds)) {
+                       r |= SWITCH_POLL_READ;
+               }
+
+               if ((flags & SWITCH_POLL_WRITE) && FD_ISSET(sock, wfds)) {
+                       r |= SWITCH_POLL_WRITE;
+               }
+
+               if ((flags & SWITCH_POLL_ERROR) && FD_ISSET(sock, efds)) {
+                       r |= SWITCH_POLL_ERROR;
+               }
+       }
+
+       free(rfds);
+       free(wfds);
+       free(efds);
+
+       return r;
+
+}
+#endif
+
 SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms)
 {
        int nsds = 0;