Re[2]: Re: PHPgnugkstatus v0.5 released GNUGK -> core dump!!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



about core dump read bellow.

Hello, there is the script with minor bug fixes at the bottom of the letter.

I did some tests - mostly to see behavoir of my script when there are lots of calls come through gnugk and lots of msgs in status port. And at same point I started to see some odd results (have no idea what was that):
/////// sample of my script debugging. Each line represents a line read from status port. 
[34] => ACF|192.168.0.1:6111|6009_gk1|24604|15149897407:dialedDigits|CallGen2:h323_ID|false;
[35] => ACF|192.168.0.1:5000|6007_gk1|57372|15149897407:dialedDigits|CallGen2:h323_ID|true;
[36] => Call No. 61 | CallI
[37] => Dial 15149897407:dialedDigits
[38] => ACF|192.168.0.1:6222|6008_gk1|15133|15149897407:dialedDigits|1514123:dialedDigits|false;
[39] => ACF|192.168.0.1:5000|6007_gk1|47901|15149897407:dialedDigits|1514123:dialedDigits|true;

As you can see line [36] is really wrong. I catched such lines very rarely, but sometimes they broke lines like ACF| and in such case - wrong output to the browser.
I fixed this problem a little bit in my script but, while testing I once tried to reload my script very fast many times AND I got seg. fault in gnugk which was previously running for 4 days and had served thousands of calls. I have core dump but don't know what should I do with it. In gnugk trace last lines were my code, but they had nothing to do with status and totatly safe - the only thing there was PString involved in it...




Bellow is the php script. Please test it, comments are welcome.
///////////   script.php
<?php


//Modify these.
define ('GK_HOST','192.168.0.128');
define ('GK_PORT','7000');


define ('SELF_NAME',$_SERVER['PHP_SELF']);


function sec2min($sec){
   $out='';
   $sec+=0;
   $s=$sec%3600;
   if($s!=$sec){
      $h=round(($sec-$s)/3600);
      if($h){
         $out=$h.'<span class="tm">h</span>';
      }
   }
   $sec=$s%60;
   $h=round(($s-$sec)/60);
      
   $out.=$h.'<span class="tm">m</span>'.$sec.'<span class="tm">s</span>';
   return $out;
}

set_time_limit (15);

function starts_with(&$str, $typ){
   if(strpos($str, $typ)===0) return true;
   else return false;
}
function value_by_key($str, $key){
   $i=strpos($str,$key);
   if($i===false){
      return 0;
   }else return trim(substr($str,$i+strlen($key)));
   
}

/*
   Readme. 
   There are some problems with this script reading 
   lines (sometimes from socket script gets unfinished lines)
   The reason might be with php returning not fully received 
   line of gnugk not sendig it on time while under heavy load.
   This might be noticed only when there are really lots of 
   messages passed through status which I think 
   will not be an issue for most of the people. 
   This script will not display any lines that 
   are considered invalid! (*SEE comments inside.)
*/

class GnuGKClient{
   var $fp, $calls, $regs, $last_call;
   function GnuGKClient($host, $port){
      $errno=''; $errstr='';
      $this->fp=fsockopen ($host, $port, $errno, $errstr, 12);
      if(!$this->fp){
         echo 'unable to connect gk status port'."<br>$errstr ($errno)";
         exit();
      }
      //stream_set_timeout($this->fp, 5);
      stream_set_blocking ($this->fp, FALSE);
      
      $this->calls=array();
      $this->regs=array();
      
      $this->last_call=array();
         }
   function RequestData(){
      if (!$this->sendCommand("PrintAllRegistrations") || 
         !$this->sendCommand("PrintCurrentCalls") ) return false;
      return true;
   }
   function WaitData(){
      $c_done =false;
      $r_done =false;
      $c_wait =true;
      $r_wait =true;
      while(!$c_done || !$r_done){
         if($line = trim( fgets($this->fp,10240) )){
            //echo "WaitData $line received...<br>\n";
            
            if($c_wait){
               //echo 'if(isset($this->calls[\'waiting\'])){<br>';
               if(starts_with($line,'CurrentCalls')){
                  //Debug($line);
                  $c_wait=false;
                  continue;
               }
            }elseif(!$c_done){
               if(starts_with($line,'Number of Calls:')){
                  //Debug($line);
                  if($this->last_call){
                     $this->calls[]=$this->last_call;
                  }
                  $this->num_of_calls=$line;
                  $c_done=true;
                  continue;
               }else{
                  if(starts_with($line,'Call No.')){
                     $this->next_call($line);
                     continue;
                  }elseif(starts_with($line,'Dial')){
                     $this->add_dial($line);
                     continue;
                  }elseif(starts_with($line,'ACF')){
                     $this->add_ep($line);
                     continue;
                  }                 
               }              
            }

            if($r_wait){
               if(starts_with($line,'AllRegistrations')){
                  //Debug($line);
                  $r_wait=false;
                  continue;
               }
            }elseif(!$r_done){
               if(starts_with($line,'Number of Endpoints:')){
                  //Debug($line);
                  $this->num_of_points=$line;
                  $r_done=true;
                  continue;
               }else{
                  if(starts_with($line,'RCF')){
                     $this->add_reg($line);
                     continue;
                  }
               }              
            }
            
         }
      }
      $this->last_call=array();
   }
   function DisconnectCall($num){
      $this->sendCommand('DisconnectCall '.$num);
   }
   function UnregisterIP($ip){
      $this->sendCommand('UnregisterIP '.$ip);
   }
   
   function next_call($line){ 
      //Debug($line);/
      $d=explode ('|',str_replace(" ", "", $line),4);    //NOTE: spaces removed!
      if($this->last_call){
         $this->calls[]=$this->last_call;
      }
      $this->last_call=array();
      $this->last_call['N'] = substr($d[0], 7);
      //$this->last_call['N'] = value_by_key($d[0],'CallNo.');
      $this->last_call['ID'] = substr($d[1], 6);
      //$this->last_call['ID'] = value_by_key($d[1],'CallID');
      $this->last_call['duration'] = $d[2];
      $this->last_call['left'] = $d[3];
      $this->last_call['EP']=array();
   }
   function add_ep(&$line){
      //Debug($line);/
      if($this->last_call) {
         $this->last_call['EP'][]=substr($line, 4);
      }
   }
   function add_dial($line){
      //Debug($line);/
      $this->last_call['D'] = substr($line, 5); //, strrpos($line,':')-5);
   }
   function add_reg(&$line){
      //Debug($line);
      $this->regs[]=substr($line, 4);     
   }
   
   function GoodBuy(){
      $this->sendCommand('Exit');      
       fclose ($this->fp);
   }
   function sendCommand($cmd){
      if($this->fp){
         return (false !== fwrite ($this->fp, $cmd."\r\n"));
      }
      return false;
   }
   function ArrangeData(){
      foreach($this->calls as $i => $call){
         $a=array();
         $from=array(); 
         $to=array();
         
         foreach($call['EP'] as $E){
            $a = explode('|',$E,6);
            if(strcasecmp($a[5],'false;')){
               $to[]=array($a[0],$a[1],$a[3],$a[4],$a[5]);
            }else{
               $from[]=array($a[0],$a[1],$a[3],$a[4],$a[5]);
            }
         }
         
         foreach($from as $F){
            foreach ($to as $T){
               if(!strncmp($F[2],$T[2],5) && !strncmp($F[3],$T[3],3)){ 
               // !!! UGLY hack. Should have been like below:
               //if(!strcmp($F[2],$T[2]) && !strcmp($F[3],$T[3])){
               //Sometimes lines are NOT read to the end by some reason when gnugk is under heavy load...
                  $to=array($T[0],$T[1],$T[2]);
                  $from=array($F[0],$F[1],$F[3]);
                  break 2;                
               }
            }
         }
         
         unset($call['EP']);
         $call['FROM']=$from;
         $call['TO']=$to;
         
         $this->calls[$i] = $call;        
      }

      foreach($this->regs as $i => $reg){
         $a=array();
         list($a['ADDR'],$a['ALIASES'],$a['TERM'],$a['EPID'])=explode('|',$reg,4);
         $this->regs[$i]=$a;
      }
   }
};




function GetConfig($server) { 
   $Z = new GnuGKClient(GK_HOST, GK_PORT);
   if(isset($_POST['action']) && isset($_POST['value'])){
      switch ($_POST['action']){
         case 'unregisterip':
         $Z->UnregisterIP($_POST['value']);
         break;
         case 'dropcall':
         $Z->DisconnectCall($_POST['value']);
         break;
      }
      #usleep(100000); #to be able to see changes....
   }
   if ($Z->RequestData()){
      $Z->WaitData();
      $Z->ArrangeData();
      $Z->GoodBuy();
   } else {
      $Z->GoodBuy();
      echo 'Error sening reques...';
      exit;
      }
      
      
   print "\n<br>{$Z->num_of_calls}<br>\n";
   print "<table cellspacing='0'>\n";
   print "<tr class='h'>\n\t<td>Action</td>\n\t<td>Call No.</td>\n\t<td>Dialed digits/id</td>\n\t<td>Caller info</td>\n\t<td>Calee info</td>\n\t<td>Duration</td>\n\t<td>Time left</td>\n\t<td>Call ID</td>\n</tr>";
   //$count=0;
   foreach($Z->calls as $call){  
      if($call['N'] && $call['D'] && $call['FROM'][0] && $call['FROM'][2] && $call['TO'][0] && $call['TO'][2] && $call['ID'] && isset($call['duration']) && isset($call['left']))
      {
         $class=$class?0:1;
         //$count++;
         print "<tr class='c$class'>\n\t<td>{$count}&nbsp;&nbsp;<input type='button' value='Disconnect' onclick='disconnect(".$call['N']."); return true;' /></td>\n\t<td>".$call['N']."</td>\n\t<td>".$call['D']."</td>\n\t<td>".$call['FROM'][0].'<br>'.$call['FROM'][2]."</td>\n\t<td>".$call['TO'][0].'<br>'.$call['TO'][2]."</td>\n\t<td class='t'>".sec2min($call['duration'])."</td>\n\t<td class='t'>".sec2min($call['left'])."</td>\n\t<td class='confid'>".$call['ID']."</td>\n</tr>";
      }
   }
   print "\n</table>\n<br>";
   /*
   $noc=str_replace(" ", "", $Z->num_of_calls);
   $noc=value_by_key($noc,'NumberofCalls:');
   $noc=substr($noc,0,strpos($noc,'A'));
   $noc=0+$noc;
   if($count!=$noc){
      echo '<div class="error">calls do not match!</div>';
   }
   */
   
   print "<br>\n{$Z->num_of_points}<br>\n";
   print "<table cellspacing='0'>\n";
   print "<tr class='h'>\n\t<td>Action</td>\n\t<td>Endpoint ID</td>\n\t<td>IP address</td>\n\t<td>Dialed digits/id</td>\n\t<td>Terminal type</td>\n</tr>";
   foreach($Z->regs as $reg){
      $class=$class?0:1;
      if ($reg['EPID'] && $reg['ADDR'] && $reg['ALIASES'] && $reg['TERM'])
         print "<tr class='c$class'>\n\t<td><input type='button' value='Unregister' onclick='unregister(\"".$reg['ADDR']."\"); return true;' /></td>\n\t<td>".$reg['EPID']."</td>\n\t<td>".$reg['ADDR']."</td>\n\t<td>".$reg['ALIASES']."</td>\n\t<td>".$reg['TERM']."</td>\n</tr>";
   }
   print "\n</table>\n<br><br>\n";
   
   //global $DBG;
   //echo PrintArg($DBG, 'DEBUG');
   //echo PrintArg($Z, 'Z');
   return ;
}
/*
$DBG=array();
function Debug($msg){
   global $DBG;
   $DBG[]=$msg;
}        
*/       
?>
<html>
<meta http-equiv="refresh" content="15;url=<?php echo SELF_NAME; ?>">
<head><title>Registered Endpoints in the MYSITE VoIP Network</title></head>
<style>
table, td{padding: 3px; cursor : default; border : 1px solid white; margin : 0; }
tr.h td{ background-color: #cce2ff; font-weight: bold;}
tr.c1 td{ background-color: #e2e2e2;}
tr.c0 td{ background-color: #cecece;}
.confid{font-size: 80%;}
.tm{color: #666666; font-size: 90%;}
.t{white-space: nowrap;}
.red{color: red}
.error{position:absolute; top: 0px; left: 100px; z-index: 100; font-size: 35px; font-weight: bold; line-height: 50px;}
td , body , table , form {cursor : default; font : normal normal normal 11px/13px verdana, tahoma, sans-serif; } 
//font : normal normal normal 0.8em/1em verdana, tahoma, sans-serif;  <-- set this to be able to change font-size in browser...
</style>
<script>
function unregister(adr){
   var f=document.getElementById('frm');
   if (f){
      f.action.value='unregisterip';
      f.value.value=''+adr;   
      f.submit();
   }
}
function disconnect(adr){
   var f=document.getElementById('frm');
   if (f){
      f.action.value='dropcall';
      f.value.value=''+adr;   
      f.submit();
   }
}
</script>
<body style="padding-top: 50px;">
<div><a href="<?php echo SELF_NAME; ?>"><h4 class="red">Reload</h4></a></div>
<br><br><br>
<div>
<?
   GetConfig(1);
?>
</div>
<p>
<form id="frm" target="_self" method="POST">
<input name="action" type="hidden" value="">
<input name="value" type="hidden" value="">
</form>
</p>
</html>

///////////   any_name.php - END


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click

_______________________________________________________

List: Openh323gk-users@xxxxxxxxxxxxxxxxxxxxx
Archive: http://sourceforge.net/mailarchive/forum.php?forum_id=8549
Homepage: http://www.gnugk.org/

[Index of Archives]     [SIP]     [Open H.323]     [Gnu Gatekeeper]     [Asterisk PBX]     [ISDN Cause Codes]     [Yosemite News]

  Powered by Linux