Page MenuHomePhabricator

No OneTemporary

diff --git a/cdrlib.phtml b/cdrlib.phtml
index ce9e3ca..c721003 100644
--- a/cdrlib.phtml
+++ b/cdrlib.phtml
@@ -1,2136 +1,2135 @@
<?
if (!$maxrowsperpage) $maxrowsperpage=15;
$tz=$CDRTool['provider']['timezone'];
putenv("TZ=$tz");
class CDRS {
var $CDR_class = 'CDR';
var $intAccessCode = '00';
var $natAccessCode = '0';
var $RatingEngineSocket = false;
var $maxrowsperpage = 15;
var $status = array();
var $normalizedField = 'Normalized';
var $DestinationIdField = 'DestinationId';
var $BillingIdField = 'UserName';
var $sipTraceDataSource = 'sip_trace';
var $defaults = array();
var $whereUnnormalized = '';
var $skipNormalize = false;
var $reNormalize = false;
var $usageKeysForDeletionFromCache = array();
var $mc_key_mu_prefix = 'mu:';
var $CDRNormalizationFields=array('id' => 'RadAcctId',
'callId' => 'AcctSessionId',
'username' => 'UserName',
'domain' => 'Realm',
'gateway' => 'NASIPAddress',
'duration' => 'AcctSessionTime',
'startTime' => 'AcctStartTime',
'stopTime' => 'AcctStopTime',
'inputTraffic' => 'AcctInputOctets',
'outputTraffic' => 'AcctOutputOctets',
'aNumber' => 'CallingStationId',
'cNumber' => 'CalledStationId',
'timestamp' => 'timestamp',
'BillingPartyId' => 'UserName',
'price' => 'Price',
'DestinationId' => 'DestinationId'
);
function _readCDRNormalizationFieldsFromDB() {
foreach (array_keys($this->CDRNormalizationFields) as $field) {
$mysqlField=$this->CDRNormalizationFields[$field];
$CDRStructure[$mysqlField] = $this->CDRdb->f($mysqlField);
}
return $CDRStructure;
}
function _readCDRFieldsFromDB() {
foreach (array_keys($this->CDRFields) as $field) {
$mysqlField=$this->CDRFields[$field];
$CDRStructure[$mysqlField] = $this->CDRdb->f($mysqlField);
}
return $CDRStructure;
}
function CDRS($cdr_source) {
global $CDRTool;
global $DATASOURCES;
global $memcache_server;
global $RatingEngine;
if (!$DATASOURCES[$cdr_source] || !$DATASOURCES[$cdr_source]['db_class']) {
$log="Error: cdr_source or database not defined\n";
print $log;
syslog(LOG_NOTICE, $log);
return 0;
}
$this->initDefaults();
$this->cdrtool = new DB_CDRTool();
$this->cdr_source = $cdr_source;
$this->CDRTool = $CDRTool;
$this->rating_settings = $RatingEngine;
$this->DATASOURCES = $DATASOURCES;
$this->cdrtool->Halt_On_Error="no";
$this->table = $this->DATASOURCES[$this->cdr_source]['table'];
if (!$memcache_server && $this->defaults['START_MEMCACHE']) {
// for debian systems read the settings from /etc/default/cdrtool
if (preg_match("/yes/i",$this->defaults['START_MEMCACHE'])) {
$memcache_server=$this->defaults['MEMCACHE_IP'].":".$this->defaults['MEMCACHE_PORT'];
} else {
unset($memcache_server);
}
}
if ($memcache_server) {
$mc=new Memcache;
list($memcache_host,$memcache_port)=explode(":",$memcache_server);
if ($mc->pconnect($memcache_host,$memcache_port)) {
$this->mc = &$mc;
if ($mc_stats=$this->mc->getStats()) {
$this->mc_usage=$mc_stats['bytes']/$mc_stats['limit_maxbytes']*100;
}
$log=sprintf ("Connected to memcache %s:%d, usage: %.02f/%.02f MB (%.0f%s), keys: %s\n",$memcache_host,$memcache_port,$mc_stats['bytes']/1024/1024,$mc_stats['limit_maxbytes']/1024/1024,$this->mc_usage,"%",$mc_stats['curr_items']);
} else {
$log=sprintf ("Connection to memcache %s:%d failed\n",$memcache_host,$memcache_port);
}
syslog(LOG_NOTICE, $log);
}
// init names of CDR fields
foreach (array_keys($this->CDRFields) as $field) {
$mysqlField=$this->CDRFields[$field];
$_field=$field."Field";
$this->$_field=$mysqlField;
}
if ($this->DATASOURCES[$this->cdr_source]['rating']) {
$this->ratingEnabled = 1;
$this->rating = $this->DATASOURCES[$this->cdr_source]['rating'];
if ($this->DATASOURCES[$this->cdr_source]['showRate']) $this->showRate = $this->DATASOURCES[$this->cdr_source]['showRate'];
if ($this->DATASOURCES[$this->cdr_source]['rateField']) $this->rateField = $this->DATASOURCES[$this->cdr_source]['rateField'];
if ($this->DATASOURCES[$this->cdr_source]['priceField']) $this->priceField = $this->DATASOURCES[$this->cdr_source]['priceField'];
}
// connect to the CDR database(s)
$_dbClass = $this->DATASOURCES[$this->cdr_source]['db_class'];
if (is_array($_dbClass)) {
if (class_exists($_dbClass[0])) $this->primary_database = $_dbClass[0];
if (class_exists($_dbClass[1])) $this->secondary_database = $_dbClass[1];
} else {
$this->primary_database = $_dbClass;
}
if(!class_exists($this->primary_database)) {
$log="Error instantiating db class: $this->primary_database\n";
print $log;
syslog(LOG_NOTICE, $log);
return 0;
}
$this->CDRdb = new $this->primary_database;
// check db connectivity
if (!$this->CDRdb->query('SELECT 1')) {
if ($this->secondary_database) {
$this->CDRdb = new $this->secondary_database;
if (!$this->CDRdb->query('SELECT 1')) {
$log="Error: failed to connect to the CDR database\n";
print $log;
syslog(LOG_NOTICE, $log);
return 0;
} else {
$this->CDRdb1 = new $this->secondary_database;
$this->db_class = $this->secondary_database;
}
}
} else {
$this->CDRdb1 = new $this->primary_database;
$this->db_class = $this->primary_database;
}
if ($this->DATASOURCES[$this->cdr_source]['DestinationIdField']) {
$this->DestinationIdField = $this->DATASOURCES[$this->cdr_source]['DestinationIdField'];
}
if ($this->DATASOURCES[$this->cdr_source]['normalizedField']) {
$this->normalizedField=$this->DATASOURCES[$this->cdr_source]['normalizedField'];
}
if (strlen($this->DATASOURCES[$this->cdr_source]['intAccessCode'])) {
$this->intAccessCode=$this->DATASOURCES[$this->cdr_source]['intAccessCode'];
}
if (strlen($this->DATASOURCES[$this->cdr_source]['natAccessCode'])) {
$this->natAccessCode = $this->DATASOURCES[$this->cdr_source]['natAccessCode'];
}
if ($this->DATASOURCES[$this->cdr_source]['AccountsDBClass'] && class_exists($this->DATASOURCES[$this->cdr_source]['AccountsDBClass'])) {
$this->AccountsDB = new $this->DATASOURCES[$this->cdr_source]['AccountsDBClass'];
$this->AccountsDBClass = $this->DATASOURCES[$this->cdr_source]['AccountsDBClass'];
} else if (class_exists('DB_openser')) {
$this->AccountsDB = new DB_openser();
$this->AccountsDBClass = 'DB_openser';
}
if ($this->DATASOURCES[$this->cdr_source]['BillingIdField']) {
$this->BillingIdField = $this->DATASOURCES[$this->cdr_source]['BillingIdField'];
}
if ($this->DATASOURCES[$this->cdr_source]['sipTraceDataSource']) {
$this->sipTraceDataSource=$this->DATASOURCES[$this->cdr_source]['sipTraceDataSource'];
}
if ($this->DATASOURCES[$this->cdr_source]['domain_table']) {
$this->domain_table = $this->DATASOURCES[$this->cdr_source]['domain_table'];
}
if ($this->DATASOURCES[$this->cdr_source]['skipNormalize']) {
$this->skipNormalize = $this->DATASOURCES[$this->cdr_source]['skipNormalize'];
}
if ($this->DATASOURCES[$this->cdr_source]['enableThor']) {
$this->enableThor = $this->DATASOURCES[$this->cdr_source]['enableThor'];
}
if (is_array($this->CDRTool['normalize']['CS_CODES'])) $this->CS_CODES=array_keys($this->CDRTool['normalize']['CS_CODES']);
$this->missed_calls = $this->DATASOURCES[$this->cdr_source]['missed_calls'];
$this->traceInURL = $this->DATASOURCES[$this->cdr_source]['traceInURL'];
$this->traceOutURL = $this->DATASOURCES[$this->cdr_source]['traceOutURL'];
$this->protocolTraceURL = $this->DATASOURCES[$this->cdr_source]['protocolTraceURL'];
$spath = explode("/",$_SERVER["PHP_SELF"]);
$last = count($spath)-1;
$this->scriptFile=$spath[$last];
$this->next = $_REQUEST["next"];
$this->export = $_REQUEST["export"];
$this->trace = $_REQUEST["trace"];
if ($this->export) {
$this->maxrowsperpage=10000000;
} else {
if ($_REQUEST["maxrowsperpage"]) {
$this->maxrowsperpage = $_REQUEST["maxrowsperpage"];
} else {
$this->maxrowsperpage = "25";
}
}
// Init memcache key names to be unique per datasource
$this->mc_key_init = $this->cdr_source.':quotaCheckInit';
$this->mc_key_domains = $this->cdr_source.':domains';
$this->mc_key_accounts = $this->cdr_source.':accounts';
$this->LoadDisconnectCodes();
$this->LoadDestinations();
$this->LoadENUMtlds();
$this->LoadDomains();
$this->getCDRtables();
$this->initOK=1;
}
function initDefaults() {
if (is_readable('/etc/default/cdrtool')) {
$defaultContentLines=explode("\n",file_get_contents('/etc/default/cdrtool'));
foreach ($defaultContentLines as $_line) {
list($defaults_key, $defaults_value)=explode("=",$_line);
if (strlen($defaults_value)) $this->defaults[trim($defaults_key)]=trim($defaults_value);
}
}
}
function LoadDomains() {
}
function LoadAccounts() {
}
function LoadDestinations() {
$_destinations=array();
$_SipDestinations=array();
$this->destinationsCount=0;
$this->sipDestinationsCount=0;
//if (is_object($this->mc) && $mc_destinations = $this->mc->get('destinations') && $mc_SipDestinations = $this->mc->get('SipDestinations')) {
if (is_object($this->mc) && $mc_destinations = $this->mc->get('destinations')) {
$_dests=explode("\n",$mc_destinations);
foreach ($_dests as $_dest) {
if (!strlen($_dest)) continue;
$this->destinationsCount++;
$_els=explode("=",$_dest) ;
$_els_parts=explode(";",$_els[0]);
$_destinations[$_els_parts[0]][$_els_parts[1]]=$_els[1];
}
$mc_SipDestinations = $this->mc->get('SipDestinations');
$_SipDests=explode("\n",$mc_SipDestinations);
foreach ($_SipDests as $_dest) {
if (!strlen($_dest)) continue;
$this->sipDestinationsCount++;
$_els=explode("=",$_dest) ;
$_els_parts=explode(";",$_els[0]);
$_SipDestinations[$_els_parts[0]][$_els_parts[1]]=$_els[1];
}
} else {
$query="select * from destinations";
if ($this->CDRTool['filter']['aNumber']) {
$faNumber=$this->CDRTool['filter']['aNumber'];
$query .= " where subscriber = '$faNumber' or
(subscriber = '' and domain = '' and gateway = '') ";
} else if ($this->CDRTool['filter']['domain']) {
$fdomain=$this->CDRTool['filter']['domain'];
$query .= " where domain = '$fdomain' or
(subscriber = '' and domain = '' and gateway = '') ";
} else if ($this->CDRTool['filter']['gateway']) {
$fgateway=$this->CDRTool['filter']['gateway'];
$query .= " where gateway = '$fgateway' or
(subscriber = '' and domain = '' and gateway = '') ";
}
$this->cdrtool->query($query);
$mc_value_destinations = "\n";
$mc_value_SipDestinations = "\n";
while($this->cdrtool->next_record()) {
$gateway = trim($this->cdrtool->Record['gateway']);
$domain = trim($this->cdrtool->Record['domain']);
$subscriber = trim($this->cdrtool->Record['subscriber']);
$id = trim($this->cdrtool->Record['dest_id']);
$name = trim($this->cdrtool->Record['dest_name']);
$name_print = $this->cdrtool->Record['dest_name']." (".$id.")";
if (strstr($id,'@')) {
// SIP destination
$this->sipDestinationsCount++;
if ($subscriber) {
$_SipDestinations[$subscriber][$id]=$name;
if (is_object($this->mc)) $mc_value_SipDestinations.=$subscriber.";".$id."=".$name."\n";
continue;
}
if ($domain) {
$_SipDestinations[$domain][$id]=$name;
if (is_object($this->mc)) $mc_value_SipDestinations.=$domain.";".$id."=".$name."\n";
continue;
}
if ($gateway) {
$_SipDestinations[$gateway][$id]=$name;
if (is_object($this->mc)) $mc_value_SipDestinations.=$gateway.";".$id."=".$name."\n";
continue;
}
if ($id) {
$_SipDestinations["default"][$id]=$name;
if (is_object($this->mc)) $mc_value_SipDestinations.="default;".$id."=".$name."\n";
}
} else {
// PSTN destination
$this->destinationsCount++;
if ($subscriber) {
$_destinations[$subscriber][$id]=$name;
if (is_object($this->mc)) $mc_value_destinations.=$subscriber.";".$id."=".$name."\n";
continue;
}
if ($domain) {
$_destinations[$domain][$id]=$name;
if (is_object($this->mc)) $mc_value_destinations.=$domain.";".$id."=".$name."\n";
continue;
}
if ($gateway) {
$_destinations[$gateway][$id]=$name;
if (is_object($this->mc)) $mc_value_destinations.=$gateway.";".$id."=".$name."\n";
continue;
}
if ($id) {
$_destinations["default"][$id]=$name;
if (is_object($this->mc)) $mc_value_destinations.="default;".$id."=".$name."\n";
}
}
}
if (is_object($this->mc)) {
if ($this->mc->set('destinations',$mc_value_destinations,0,0)) {
$log=sprintf("Saved %d destinations in memcache key destinations",$this->destinationsCount);
syslog(LOG_NOTICE, $log);
}
if ($this->mc->set('SipDestinations',$mc_value_SipDestinations,0,0)) {
$log=sprintf("Saved %d SIP destinations in memcache key SipDestinations",$this->sipDestinationsCount);
syslog(LOG_NOTICE, $log);
}
}
}
$this->destinations = &$_destinations;
$this->sipDestinations = &$_SipDestinations;
if (is_array($this->destinations)) {
foreach ($this->destinations as $key => $val) {
$this->destinations_length[$key] = max(array_map(strlen, array_keys($val)));
}
}
$c=$this->destinationsCount + $this->sipDestinationsCount;
return $c;
}
function LoadENUMtlds() {
$_ENUMtlds =array();
if (is_object($this->mc) && $_value = $this->mc->get('ENUMtlds')) {
$_ENUMtlds=json_decode($_value,true);
$this->ENUMtlds = &$_ENUMtlds;
$c=count($this->ENUMtlds);
} else {
$query="select * from billing_enum_tlds";
$this->cdrtool->query($query);
$mc_value = "\n";
while($this->cdrtool->next_record()) {
$_ENUMtlds[trim($this->cdrtool->Record['enum_tld'])]=
array('discount' => trim($this->cdrtool->Record['discount']),
'e164_regexp' => trim($this->cdrtool->Record['e164_regexp'])
);
}
if (is_object($this->mc)) {
if ($this->mc->set('ENUMtlds',json_encode($_ENUMtlds),0,0)) {
$log=sprintf("Saved %d ENUM TLDs in memcache key ENUMtlds",count($_ENUMtlds));
syslog(LOG_NOTICE, $log);
}
}
$this->ENUMtlds = &$_ENUMtlds;
$c=count($this->ENUMtlds);
}
return count($this->ENUMtlds);
}
function LoadDisconnectCodes() {
}
function initForm() {
}
function searchForm() {
}
function showTableHeader($begin_datetime,$end_datetime) {
}
function showTableHeaderStatistics($begin_datetime,$end_datetime) {
}
function showResultsMenu($hide_rows="") {
global $loginname;
$REMOTE_ADDR = $_SERVER["REMOTE_ADDR"];
if (!$this->export) {
print "
<form action=log.phtml method=post>
<table border=0 align=center>
<tr>
<td><a href=\"$this->url_edit\" >Refine search</a>
| <a href=\"$this->url_run\">Refresh</a>
</td>
";
$log_query="insert into log
(date,login,ip,url,results,rerun,reedit,datasource)
values
(NOW(),'$loginname','$REMOTE_ADDR','$this->url','$this->rows','$this->url_run','$this->url_edit','$this->cdr_source')";
if ($this->cdrtool->query($log_query)) {
$this->cdrtool->query("select LAST_INSERT_ID() as lid");
$this->cdrtool->next_record();
$current_log=$this->cdrtool->f('lid');
}
if ($this->rows) {
print "<td> | <a href=\"$this->url_export\" target=_new>Export results to file</a></td>";
}
print "
<td valign=middle>
| Save a description for this query:
</td>
<td valign=middle>
<input type=text name=log_description value=\"$old_description\">
<input type=hidden name=current_log value=$current_log>
<input type=hidden name=task value=edit>
<input type=submit value=Save>
</td>
</form>
";
print "
</tr>
</table>
";
if (!$hide_rows) {
print "
<table width=100%>
<tr>
<td align=center>
";
if ($this->rows == 0) {
print "No records found.";
} else {
print "$this->rows records found. ";
}
print "</td>
</tr>
</table>
";
}
}
}
function showResultsMenuSubscriber($hide_rows="") {
global $loginname;
$REMOTE_ADDR = $_SERVER["REMOTE_ADDR"];
if (!$this->export) {
print "
<form action=log.phtml method=post>
<table border=0 align=center>
<tr>
<td>
<td>
<a href=\"$this->url_edit\">Refine search</a>
| <a href=\"$this->url_run\">Refresh</a>
</td>
";
$log_query="insert into log
(date,login,ip,url,results,rerun,reedit,datasource)
values
(NOW(),'$loginname','$REMOTE_ADDR','$this->url','$this->rows','$this->url_run','$this->url_edit','$this->cdr_source')";
if ($this->cdrtool->query($log_query)) {
$this->cdrtool->query("select LAST_INSERT_ID() as lid");
$this->cdrtool->next_record();
$current_log=$this->cdrtool->f('lid');
}
if (!$this->CDRTool['filter']['aNumber']) {
if ($this->rows) {
print " | <a href=\"$this->url_export\" target=_new>Export results to file</a>";
}
print "
</td>
<td valign=middle>
| Save a description for this query:
</td>
<td valign=middle>
<input type=text name=log_description value=\"$old_description\">
<input type=hidden name=current_log value=$current_log>
<input type=hidden name=task value=edit>
<input type=submit value=Save>
</td>
</form>
";
}
print "
</tr>
</table>
";
if (!$hide_rows) {
print "
<table width=100%>
<tr>
<td align=center>
";
if ($this->rows == 0) {
print "No records found.";
} else {
print "$this->rows records found. ";
}
print "</td>
</tr>
</table>
";
}
}
}
function showDateTimeElements($f) {
print "
<tr>
<td valign=middle align=left>
<b>Start time</b>
</td>
<td>
";
print "Date: ";
$f->show_element("begin_year","");
print "-";
$f->show_element("begin_month","");
print "-";
$f->show_element("begin_day","");
print " Time: ";
$f->show_element("begin_hour","");
print ":";
$f->show_element("begin_min","");
print "
</td>
</tr>
<tr>
</tr>
<tr>
<td valign=middle align=left>
<b>Stop time</b>
</td>
<td>
";
print "Date: ";
$f->show_element("end_year","");
print "-";
$f->show_element("end_month","");
print "-";
$f->show_element("end_day","");
print " Time: ";
$f->show_element("end_hour","");
print ":";
$f->show_element("end_min","");
print "
</td>
</tr>
<tr>
</tr>
";
}
function showDataSources ($f) {
global $perm;
print "
<tr>
<td class=cdr valign=middle align=left>
<b>Data source</b>
</td>
<td valign=middle>";
$f->show_element("cdr_source","");
if (count($this->tables) > 0) {
print " Table: ";
$this->f->show_element("cdr_table","");
}
print "
</td>
</tr>
<tr>
";
}
function showPagination($next,$maxrows) {
$PHP_SELF=$_SERVER["PHP_SELF"];
if (!$this->export) {
print "
<p>
<table border=0 align=center>
<tr>
<td>
";
if ($next!=0 ) {
$show_next=$this->maxrowsperpage-$next;
if ($show_next < 0) {
$mod_show_next = $show_next-2*$show_next;
}
$url_prev=$PHP_SELF.$this->url."&action=search&next=$mod_show_next";
print "<a href=\"$url_prev\">Previous</a> ";
}
print "
</td>
<td>
";
if ($this->rows>$this->maxrowsperpage && $this->rows!=$maxrows) {
$show_next = $this->maxrowsperpage + $this->next;
$url_next = $PHP_SELF.$this->url."&action=search&next=$show_next";
print "<a href=\"$url_next\">Next</a>";
}
print "
</td>
</tr>
</table>
";
}
}
function show() {
}
function dump() {
}
function unNormalize($where="",$table) {
if (!$where) $where=" (1=1) ";
if (!$table) $table=$this->table;
if ($this->skipNormalize) {
return 0;
}
if (!$this->normalizedField) {
return 0;
}
$query=sprintf("update %s set %s = '0' where %s ",
$table,
$this->normalizedField,
$where
);
$c=0;
if ($this->CDRdb->query($query)) {
$c=$this->CDRdb->affected_rows();
if ($c) {
if (is_object($this->mc)) $this->mc->delete($this->mc_key_init);
$query=sprintf("delete from memcache where `key`= '%s'",$this->mc_key_init);
$this->cdrtool->query($query);
}
}
$this->reNormalize=true;
return $c;
}
function buildWhereForUnnormalizedSessions () {
$this->whereUnnormalized = sprintf(" %s = '0'",$this->normalizedField);
if ($this->stopTimeField) $this->whereUnnormalized .= " and $this->stopTimeField != '0000-00-00 00:00:00' ";
if ($this->CDRFields['MediaTimeout']) {
/*
If we use MediaProxy information then eliminate all possible raise conditions
1. Session started and is in progress:
AcctStopTime = '0000-00-00 00:00:00'
AcctSessionTime = 0
MediaInfo is NULL
ConnectInfo_stop is NULL
2. Session closed with a negative response code ([4-6]XX):
AcctSessionTime = 0
AcctStopTime != '0000-00-00 00:00:00'
MediaInfo is NULL
ConnectInfo_stop is NULL
3. Session received a BYE:
ConnectInfo_stop is not NULL
AcctStopTime != '0000-00-00 00:00:00'
4. Media has timed-out:
MediaInfo = 'timeout'
ConnectInfo_stop is NULL
AcctStopTime != '0000-00-00 00:00:00'
5. MediaProxy update before BYE is received:
MediaInfo = ''
ConnectInfo_stop is NULL
AcctStopTime != '0000-00-00 00:00:00'
*/
$this->whereUnnormalized .= " and (ConnectInfo_stop is not NULL or MediaInfo is NULL or MediaInfo != '') ";
}
}
function getUnNormalized($where="",$table) {
- if (!$this->db_class) {
- return 0;
- }
-
if ($this->skipNormalize) {
- return 0;
+ return 1;
}
if (!$where) $where=" (1=1) ";
if (!$table) $table=$this->table;
$ReNormalize = $_REQUEST["ReNormalize"];
if ($ReNormalize) $this->unNormalize($where,$table);
if (!$this->normalizedField) {
- return 0;
+ return 1;
}
$this->buildWhereForUnnormalizedSessions();
$query=sprintf("select count(*) as c from %s where %s and %s",
$table,
$where,
$this->whereUnnormalized
);
if ($this->CDRdb->query($query)) {
$this->CDRdb->next_record();
$c=$this->CDRdb->f('c');
}
return $c;
}
function NormalizeCDRS($where="",$table) {
- if (!$this->db_class) {
- return 0;
- }
-
$b=time();
if (!$where) $where=" (1=1) ";
if (!$table) $table=$this->table;
if ($this->skipNormalize) {
return 0;
}
if (!$this->normalizedField) {
return 0;
}
$lockName=sprintf("%s:%s",$this->cdr_source,$table);
if (!$this->getNormalizeLock($lockName)) {
return 1;
}
$this->buildWhereForUnnormalizedSessions();
$query=sprintf("select *, UNIX_TIMESTAMP($this->startTimeField) as timestamp
from %s where %s and %s",
$table,
$where,
$this->whereUnnormalized
);
$this->status['cdr_to_normalize']=0;
$this->status['normalized']=0;
$this->status['normalize_failures']=0;
$this->CDRdb->query($query);
$this->status['cdr_to_normalize']=$this->CDRdb->num_rows();
- if ($this->status['cdr_to_normalize']>0) {
+ if ($this->status['cdr_to_normalize'] > 0) {
if ($this->ratingEnabled) {
// The rating table will be used in each instance of
// CDR structure but we load the rating related data once
if ($this->DATASOURCES[$this->cdr_source]['EnableNetworkRating'] && $this->rating_settings['socketIP'] && $this->rating_settings['socketPort'] ) {
$fp = fsockopen ($this->rating_settings['socketIP'], $this->rating_settings['socketPort'], $errno, $errstr, 2);
if ($fp) {
$this->RatingEngineSocket = $fp;
} else {
$target=$this->rating_settings['socketIP'].":".$this->rating_settings['socketPort'];
print "<p>";
print "<font color=red>Cannot connect to rating engine $target: $errstr ($errno). </font>";
syslog(LOG_NOTICE, "Error: Cannot connect to rating engine $errstr ($errno)");
-
- // continue loading of rating tables
- $this->RatingTables = new RatingTables();
- $this->RatingTables->LoadRatingTables();
}
- } else {
- // network rating engine not available, load all rates in memory
- $this->RatingTables = new RatingTables();
- $this->RatingTables->LoadRatingTables();
}
+
+ // Load rating tables
+ $this->RatingTables = new RatingTables();
+ $this->RatingTables->LoadRatingTables();
}
} else {
return 0;
}
$this->usageKeysForDeletionFromCache=array();
while ($this->CDRdb->next_record()) {
+
$Structure=$this->_readCDRNormalizationFieldsFromDB();
$found++;
- if (count($Structure) < 6 ) {
- continue;
- }
-
$CDR = new $this->CDR_class(&$this, &$Structure);
if ($CDR->normalize("Save",$table)) {
$this->status['normalized']++;
} else {
$this->status['normalize_failures']++;
}
if ($this->reNormalize && $CDR->pricePrint && !$this->usageKeysForDeletionFromCache[$CDR->BillingPartyId]) {
$this->usageKeysForDeletionFromCache[$CDR->BillingPartyId]++;
}
if ($this->status['cdr_to_normalize'] > 1000) {
if ($found > $progress*$this->status['cdr_to_normalize']/100) {
$progress++;
if ($progress%10==0) {
print "$progress% ";
}
flush();
}
}
}
if ($this->ratingEnabled && count($this->brokenRates) >0 ) {
- if ($this->CDRTool[rating][reportMissingRates]) {
+ if ($this->CDRTool['rating']['reportMissingRates']) {
if (count($this->brokenRates)) {
foreach (array_keys($this->brokenRates) as $dest) {
$missingRatesBodytext=$missingRatesBodytext."\nDestination id $dest (".$this->brokenRates[$dest]." calls)";
}
- $to=$this->CDRTool['provider'][toEmail];
- $from=$this->CDRTool['provider'][fromEmail];
+ $to=$this->CDRTool['provider']['toEmail'];
+ $from=$this->CDRTool['provider']['fromEmail'];
mail($to, "Missing CDRTool rates",$missingRatesBodytext, "From: $from");
}
}
}
if ($this->status['cdr_to_normalize']>0) {
$d=time()-$b;
$log=sprintf("Normalization done in %d s, memory usage: %0.2f MB",$d,memory_get_usage()/1024/1024);
syslog(LOG_NOTICE,$log );
if ($this->RatingEngineSocket) {
fclose($this->RatingEngineSocket);
}
}
if (count($this->usageKeysForDeletionFromCache)) {
if (is_object($this->mc)) {
if ($reset_quota_for = $this->mc->get('reset_quota_for')) {
$reset_quota_new=array_merge(json_decode($reset_quota_for),array_keys($this->usageKeysForDeletionFromCache));
} else {
$reset_quota_new=array_keys($this->usageKeysForDeletionFromCache);
}
$this->mc->set('reset_quota_for',json_encode(array_unique($reset_quota_new)));
}
}
return 1;
}
function NormalizeNumber($Number,$type="destination",$subscriber="",$domain="",$gateway="",$CountryCode="",$ENUMtld="") {
$this->CSCODE="";
$Number=strtolower(quoted_printable_decode($Number));
if ($pos = strpos($Number, "@")) {
// this is a SIP URI
$NumberStack['username'] = substr($Number,0,$pos);
if (strlen($NumberStack['username']) < 1) {
$NumberStack['username'] = "unknown";
}
$NumberStack['domain'] = substr($Number,$pos+1);
$NumberStack['delimiter'] = "@";
$pos = strpos($NumberStack['username'], ":");
if ($pos) {
$NumberStack['protocol'] = substr($NumberStack['username'],0,$pos+1);
$NumberStack['username'] = substr($NumberStack['username'],$pos+1);
}
if (preg_match("/^(.*)[=:;]/U",$NumberStack['domain'],$p)){
$NumberStack['domain'] = $p[1];
}
} else if (preg_match("/^([a-z0-9]+:)(.*)$/i",$Number,$m)) {
$oct=preg_split("/\./",$m[2]);
if(sizeof($oct)==4) {
// This is SIP address with no username
$NumberStack['username'] = "";
$NumberStack['domain'] = $m[2];
} else {
// This is SIP address with no domain
$NumberStack['username'] = $m[2];
$NumberStack['domain'] = "";
}
$NumberStack['protocol'] = $m[1];
$NumberStack['delimiter'] = "";
} else {
// This is a simple address like a phone number
$NumberStack['protocol'] = "";
$NumberStack['username'] = $Number;
$NumberStack['delimiter'] = "";
$NumberStack['domain'] = "";
}
if (preg_match("/^(.*)[=:;]/U",$NumberStack['domain'],$p)){
$NumberStack['domain'] = $p[1];
}
if ($type=="destination" && is_numeric($NumberStack['username'])) {
// strip custom prefix from destination
$usernameLength=strlen($NumberStack['username']);
if (is_array($this->CS_CODES)) {
foreach ($this->CS_CODES as $strip_prefix) {
$prefixLength = strlen($strip_prefix);
$restLength = $usernameLength-$prefixLength;
if ($restLength > 0 and preg_match("/^$strip_prefix(.*)$/",$NumberStack['username'],$m)) {
$NumberStack['username']=$m[1];
$this->CSCODE=$strip_prefix;
break;
}
}
}
if ($this->CDRTool['normalize']['E164Class'] && class_exists($this->CDRTool['normalize']['E164Class'])) {
$E164_class = $this->CDRTool['normalize']['E164Class'];
} else {
$E164_class = "E164_Europe";
}
if (!$CountryCode) $CountryCode=$this->CDRTool['normalize']['defaultCountryCode'];
$E164 = new $E164_class($this->intAccessCode, $this->natAccessCode,$CountryCode,$this->ENUMtlds[$ENUMtld]['e164_regexp']);
$NumberStack['E164']=$E164->E164Format($NumberStack['username']);
}
if ($type=="destination" && $NumberStack['E164']) {
// lookup destination id for the E164 number
$dst_struct = $this->lookupDestination($NumberStack[E164],$subscriber,$domain,$gateway);
$NumberStack['DestinationId'] = $dst_struct[0];
$NumberStack['destinationName'] = $dst_struct[1];
$NumberStack['NumberPrint'] = "+".$NumberStack[E164];
if (!$ENUMtld) {
$NumberStack['Normalized'] = $this->intAccessCode.
$NumberStack['E164'].
$NumberStack['delimiter'].
$NumberStack['domain'];
} else {
$NumberStack['Normalized'] =
$NumberStack['username'].
$NumberStack['delimiter'].
$NumberStack['domain'];
}
} else {
$dst_struct = $this->lookupDestination($Number,$subscriber,$domain,$gateway);
$NumberStack['DestinationId'] = $dst_struct[0];
$NumberStack['destinationName'] = $dst_struct[1];
$NumberStack['NumberPrint'] = $NumberStack['username'].
$NumberStack['delimiter'].
$NumberStack['domain'];
$NumberStack['Normalized'] = $NumberStack['username'].
$NumberStack['delimiter'].
$NumberStack['domain'];
}
return $NumberStack;
}
function lookupDestination($destination,$subscriber="",$domain="",$gateway="") {
if (!$destination) {
return;
}
if (is_numeric($destination)){
return $this->getPSTNDestinationId($destination,$subscriber,$domain,$gateway);
} else {
return $this->getSIPDestinationId($destination,$subscriber,$domain,$gateway);
}
}
function getSIPDestinationId($destination,$subscriber,$domain,$gateway) {
if ($this->sipDestinations[$subscriber]) {
$sipDestinations = $this->sipDestinations[$subscriber];
$fCustomer="subscriber=$subscriber";
} elseif ($this->sipDestinations[$domain]) {
$sipDestinations = $this->sipDestinations[$domain];
$fCustomer="domain=$domain";
} elseif ($this->sipDestinations[$gateway]) {
$sipDestinations = $this->sipDestinations[$gateway];
$fCustomer="gateway=$gateway";
} else {
$sipDestinations = $this->sipDestinations['default'];
$fCustomer="default";
}
if ($sipDestinations[$destination]) {
$ret=array($destination,$sipDestinations[$destination]);
return $ret;
} else {
return false;
}
}
function getPSTNDestinationId($destination,$subscriber,$domain,$gateway) {
if ($this->destinations[$subscriber]) {
$codes = $this->destinations[$subscriber];
$maxLength = $this->destinations_length[$subscriber];
$fCustomer="subscriber=$subscriber";
} elseif ($this->destinations[$domain]) {
$codes = $this->destinations[$domain];
$maxLength = $this->destinations_length[$domain];
$fCustomer="domain=$domain";
} elseif ($this->destinations[$gateway]) {
$codes = $this->destinations[$gateway];
$maxLength = $this->destinations_length[$gateway];
$fCustomer="gateway=$gateway";
} else {
$codes = $this->destinations['default'];
$maxLength = $this->destinations_length['default'];
$fCustomer="default";
}
if (!$destination)
return false;
if (count($codes)>0) {
$length = min(strlen($destination), $maxLength);
for ($i=$length; $i>0; $i--) {
$buf = substr($destination, 0, $i);
if ($codes[$buf]) {
$dest_name=$codes[$buf];
$ret=array($buf,$dest_name);
return $ret;
}
}
}
return false;
}
function import($file) {
}
function RadiusRecordRead($fp) {
$keepreading=1;
while ($keepreading) {
$contents = fgets($fp, 8192);
if (preg_match("/^$/",$contents)) {
$keepreading=0;
} else {
$record[]=$contents;
}
}
return $record;
}
function RadiusRecordParse($record) {
unset($radiusParsed);
if (!is_array($record)) {
return 0;
}
foreach ($record as $line) {
$line=trim($line);
foreach (array_keys($this->radiusAttributes) as $attribute) {
if (preg_match("/$attribute = (.*)$/",$line,$m)) {
$value=preg_replace("/\"/","",trim($m[1]));
$radiusParsed[$attribute]= $value;
}
}
}
return $radiusParsed;
}
function getCDRtables() {
if (!is_object($this->CDRdb)) return 0;
$_tables=$this->CDRdb->table_names();
$t=count($_tables);
if ($this->table) $this->tables[]=$this->table;
while ($t <> 0 ) {
$_table=$_tables[$t]["table_name"];
if ($_table=='radacct') $this->tables[]='radacct';
if (preg_match("/^(\w+)\d{6}$/",$_table,$m)) {
if ($list_t >24) break;
$this->tables[]=$_table;
$list_t++;
}
$t--;
}
$this->tables=array_unique($this->tables);
}
function rotateTable($sourceTable,$month,$action) {
// create a new table tableYYYYMM and copy data from the main table into it
// if no month is supplied, the default is the previous month
if (!$month) $month=date('Ym', mktime(0, 0, 0, date("m")-1, "01", date("Y")));
if (!$sourceTable) $sourceTable=$this->table;
if (preg_match("/^(\w+)\d{6}$/",$sourceTable,$m)) {
$destinationTable=$m[1].$month;
} else {
$destinationTable=$sourceTable.$month;
}
print("rotateTable($sourceTable,$month,$destinationTable)\n");
if ($sourceTable == $destinationTable) {
$log=sprintf("Error: cannot copy records to the same table %s.\n",$destinationTable);
syslog(LOG_NOTICE,$log);
print $log;
return 0;;
}
$createTableFile=$this->CDRTool['Path'].$this->createTableFile;
if (!$this->createTableFile || !is_readable($createTableFile)) {
$log=sprintf("Error: cannot locate mysql creation file\n");
syslog(LOG_NOTICE,$log);
print $log;
return 0;;
}
$lockFile="/var/lock/CDRTool_".$this->cdr_source."_rotateTable.lock";
$f=fopen($lockFile,"w");
if (flock($f, LOCK_EX + LOCK_NB, $w)) {
if ($w) {
$log=sprintf("Another CDRTool rotate table is in progress. Aborting.\n");
syslog(LOG_NOTICE,$log);
print $log;
return 0;;
}
} else {
$log=sprintf("Another CDRTool rotate table is in progress. Aborting.\n");
syslog(LOG_NOTICE,$log);
print $log;
return 0;;
}
$b=time();
if (!preg_match("/^(\d{4})(\d{2})$/",$month,$m)) {
print "Error: Month $month must be in YYYYMM format\n";
return 0;
} else {
if ($m[2] > 12) {
print "Error: Month must be in YYYYMM format\n";
return 0;
}
$lastMonth=$month;
$startSQL=$m[1]."-".$m[2]."-01";
$stopSQL =date('Y-m-01', mktime(0, 0, 0, $m[2]+1, "01", $m[1]));
}
$query=sprintf("select count(*) as c from %s
where %s >='%s'
and %s < '%s'\n",
$sourceTable,
$this->CDRFields['startTime'],$startSQL,
$this->CDRFields['startTime'],$stopSQL);
if ($this->CDRdb->query($query)) {
$this->CDRdb->next_record();
$rowsSourceTable=$this->CDRdb->f('c');
$log=sprintf ("Source table %s has %d records in month %s\n",$sourceTable,$rowsSourceTable,$month);
syslog(LOG_NOTICE,$log);
print $log;
if (!$rowsSourceTable) return 1;
} else {
$log=sprintf ("Error: %s (%s)\n",$this->table,$this->CDRdb->Error);
syslog(LOG_NOTICE,$log);
print $log;
return 0;
}
$query=sprintf("select count(*) as c from %s\n", $destinationTable);
if ($this->CDRdb->query($query)) {
$this->CDRdb->next_record();
$rowsDestinationTable = $this->CDRdb->f('c');
$log=sprintf ("Destination table %s has %d records\n",$destinationTable,$rowsDestinationTable);
syslog(LOG_NOTICE,$log);
print $log;
if ($rowsDestinationTable != $rowsSourceTable) {
$log=sprintf ("Error: source table has %d records and destination table has %d records\n",$rowsSourceTable,$rowsDestinationTable);
syslog(LOG_NOTICE,$log);
print $log;
} else {
$log=sprintf ("Tables are in sync\n");
syslog(LOG_NOTICE,$log);
print $log;
}
} else {
$log=sprintf ("%s (%s)\n",$this->CDRdb->Error,$this->CDRdb->Errno);
syslog(LOG_NOTICE,$log);
print $log;
if ($this->CDRdb->Errno==1146) {
$destinationTableTmp=$destinationTable."_tmp";
$query=sprintf("drop table if exists %s",$destinationTableTmp);
print($query);
$this->CDRdb->query($query);
if ($query=file_get_contents($createTableFile)) {
$query=preg_replace("/CREATE TABLE.*/","CREATE TABLE $destinationTableTmp (",$query);
if (!$this->CDRdb->query($query)) {
$log=sprintf ("Error creating table %s: %s, %s\n",$destinationTableTmp,$this->CDRdb->Error,$query);
syslog(LOG_NOTICE,$log);
print $log;
return 0;
}
} else {
$log=sprintf ("Cannot read file %s\n",$createTableFile);
syslog(LOG_NOTICE,$log);
print $log;
return 0;
}
// if we reached this point we start to copy records
$query=sprintf("insert into %s
select * from %s
where %s >='%s'
and %s < '%s'",
$destinationTableTmp,
$sourceTable,
$this->CDRFields['startTime'],$startSQL,
$this->CDRFields['startTime'],$stopSQL);
print ($query);
return ;
if ($this->CDRdb->query($query)) {
$e=time();
$d=$e-$b;
$rps=0;
if ($this->CDRdb->affected_rows() && $d) $rps=$this->CDRdb->affected_rows()/$d;
$log=printf ("Copied %d CDRs into table %s in %d s @ %.0f rps\n",$this->CDRdb->affected_rows(),$destinationTableTmp,$d,$rps);
syslog(LOG_NOTICE,$log);
print $log;
$query="rename table $destinationTableTmp to $destinationTableTmp";
if (!$this->CDRdb->query($query)) {
printf ("Error renaming table %s to %s: %s\n",$destinationTableTmp,$destinationTable,$this->CDRdb->Error);
return 0;
}
} else {
printf ("Error copying records in table %s: %s\n",$destinationTable,$this->CDRdb->Error);
return 0;
}
}
}
}
function purgeTable($sourceTable,$month) {
// delete records for a given month with minimal locking of database
// this function is useful after archive of CDR data using rotate script
$begin=time();
if ($month) {
if (!preg_match("/^(\d{4})(\d{2})$/",$month,$m)) {
print "Error: Month must be in YYYYMM format\n";
return 0;
} else {
$beginDate=$m[1]."-".$m[2]."-01";
$endDate=date('Y-m-d', mktime(0, 0, 0, $m[2]+1, '01', $m[1]));
}
} else if (is_int($this->DATASOURCES[$this->cdr_source]['purgeCDRsAfter'])) {
$beginDate="1970-01-01";
$endDate=date('Y-m-d', mktime(0, 0, 0, Date('m'), Date('d')-$this->DATASOURCES[$this->cdr_source]['purgeCDRsAfter'], Date('Y')));
} else {
return 0;
}
if (!$sourceTable) $sourceTable=$this->table;
$query=sprintf("select min(%s) as min,max(%s) as max from %s where %s >= '%s' and %s < '%s' ",
$this->CDRFields['id'],$this->CDRFields['id'],$sourceTable,$this->CDRFields['startTime'],$beginDate,$this->CDRFields['startTime'],$endDate);
print($query);
if (!$this->CDRdb->query($query)) {
printf ("Error: %s",$this->CDRdb->Error);
return 0;
}
$this->CDRdb->next_record();
$min=$this->CDRdb->f('min');
$max=$this->CDRdb->f('max');
if (!$min || !$max) {
$log=sprintf("No CDRs found in %s between %s and %s\n",$sourceTable,$beginDate,$endDate);
print $log;
syslog(LOG_NOTICE,$log);
return 0;
}
$deleted=0;
$i=$min;
$interval=100;
$rows2delete=$max-$min;
$found = 0;
print "$rows2delete CDRs will be deleted between $min and $max, $interval at a time\n";
while ($i <= $max) {
$found=$found+$interval;
if ($i + $interval < $max) {
$top=$i;
} else {
$top=$max;
}
$query=sprintf("delete low_priority from %s
where %s <= '%d' and %s >= '%d'",
$sourceTable,
$this->CDRFields['id'],
$top,
$this->CDRFields['id'],
$min);
if ($this->CDRdb->query($query)) {
$deleted=$deleted+$this->CDRdb->affected_rows();
} else {
$log=sprintf("Error: %s (%s)",$this->CDRdb->Error,$this->CDRdb->Errno);
syslog(LOG_NOTICE,$log);
print $log;
return 0;
}
if ($found > $progress*$rows2delete/100) {
$progress++;
if ($progress%10==0) {
print "$progress% ";
flush();
}
}
print ".";
flush();
$i=$i+$interval;
}
print "\n";
$end = time();
$duration = $end-$begin;
$rps=0;
if ($deleted && $duration) $rps=$deleted/$duration;
$log=sprintf("%s CDRs of month %s deleted from %s in %d s @ %.0f rps\n",$deleted,$month,$sourceTable,$duration,$rps);
syslog(LOG_NOTICE,$log);
print $log;
return 1;
}
function getMonthlyUsageFromCache($account) {
// retuns array with usage information saved with cacheMonthlyUsage
$_usage=array();
$mc_key=sprintf("%s%s",$this->mc_key_mu_prefix,$account);
if (is_object($this->mc)) {
// use memcache server
$previousUsage = $this->mc->get($mc_key);
} else {
// use MySQL server
$query=sprintf("select value from memcache where `key` ='%s'",$mc_key);
if ($this->cdrtool->query($query) && $this->cdrtool->num_rows()) {
$this->cdrtool->next_record();
$previousUsage=$this->cdrtool->f('value');
}
}
if ($previousUsage) {
$_usage=$this->parseMonthlyUsage($previousUsage);
}
return $_usage;
}
function cacheMonthlyUsage($accounts=array()) {
$saved_keys=0;
$failed_keys=0;
foreach (array_keys($accounts) as $_key) {
if (!$accounts[$_key]['usage']['calls']) continue;
$mc_value=sprintf("calls=%d duration=%d cost=%0.4f traffic=%0.2f",
$accounts[$_key]['usage']['calls'],
$accounts[$_key]['usage']['duration'],
$accounts[$_key]['usage']['cost'],
$accounts[$_key]['usage']['traffic']
);
$mc_key=sprintf("%s%s",$this->mc_key_mu_prefix,trim($_key));
if (is_object($this->mc)) {
// use memcache server
$mc_expire=time()+31*24*3600; // 31 days
if ($this->mc->set($mc_key,$mc_value,0,$mc_expire)) { // expire in 30 days
$saved_keys++;
} else {
$failed_keys++;
}
} else {
// use MySQL storage
$query=sprintf("delete from memcache where `key` = '%s'",$mc_key);
$this->cdrtool->query($query);
$query=sprintf("insert into memcache (`key`,`value`) values ('%s','%s')\n",
$mc_key,
$mc_value
);
if ($this->cdrtool->query($query) && $this->cdrtool->affected_rows()) {
$saved_keys++;
} else {
$failed_keys++;
}
}
}
$this->status['cached_keys']['saved_keys'] = $this->status['cached_keys']['saved_keys'] + $saved_keys;
$this->status['cached_keys']['failed_keys'] = $this->status['cached_keys']['failed_keys'] + $failed_keys;
return 1;
}
function parseMonthlyUsage($usage) {
if (!$usage) return ;
$_els=explode(" ",trim($usage));
$t=0;
while ($t < count($_els)) {
$_dict = explode("=",$_els[$t]);
$_key = $_dict[0];
$_value = $_dict[1];
if (!$_key) continue;
$_usage[$_key]=$_value;
$t++;
}
return $_usage;
}
function getNormalizeLock($lockname='') {
if (!$locker = new DB_Locker()) {
$log=sprintf("Error: cannot init locker database. ");
syslog(LOG_NOTICE, $log);
return 0;
}
if (!$lockname) {
$log=sprintf("Error: no lockname provided. ");
syslog(LOG_NOTICE, $log);
return 0;
}
unset($this->lock_connection_id);
register_shutdown_function("unLockNormalization",$locker,$lockname);
$query=sprintf("SELECT GET_LOCK('%s',0)",$lockname);
if ($locker->query($query)) {
$locker->next_record();
$return = $locker->Record[0];
$query=sprintf("SELECT IS_USED_LOCK('%s')",$lockname);
if ($locker->query($query)) {
$locker->next_record();
$this->lock_connection_id=$locker->Record[0];
}
if ($return == 0) {
$log=sprintf(" Warning: data source %s normalize in progress, lock id %s ",$lockname,$this->lock_connection_id);
syslog(LOG_NOTICE, $log);
print "$log\n";
return 0;
} else {
$log=sprintf(" Normalize lock id %s aquired for %s ",$this->lock_connection_id,$lockname);
syslog(LOG_NOTICE, $log);
//print "$log\n";
return 1;
}
} else {
syslog(LOG_NOTICE, "Error: failed to request mysql lock");
return 0;
}
}
}
class CDRS_unknown extends CDRS {
function searchForm() {
return;
}
}
class E164_Europe extends E164 {
function E164_Europe ($intAccessCode='00', $natAccessCode='0',$CountryCode='',$ENUMtldRegexp="([1-9][0-9]{7,})") {
$this->regexp_international = "/^".$intAccessCode."([1-9][0-9]{5,})\$/";
$this->regexp_national = "/^".$natAccessCode."([1-9][0-9]{3,})\$/";
$this->CountryCode = trim($CountryCode);
$this->ENUMtldRegexp = trim($ENUMtldRegexp);
}
}
class E164_US extends E164 {
function E164_US($intAccessCode='011', $natAccessCode='[1-9][0-9]{2}',$CountryCode='',$ENUMtldRegexp="([1-9][0-9]{7,})") {
$this->regexp_international = "/^".$intAccessCode."([1-9][0-9]{5,})\$/";
$this->regexp_national = "/^".$natAccessCode."([0-9]{3,})\$/";
$this->CountryCode = trim($CountryCode);
$this->ENUMtldRegexp = trim($ENUMtldRegexp);
}
}
class CDR {
// we need two db descriptors to update a CDR
// within same result set
var $idField = "RadAcctId";
var $callIdField = "AcctSessionId";
var $usernameField = "UserName";
var $domainField = "Realm";
var $gatewayField = "NASIPAddress";
var $gatewayPortField = "CiscoNASPort";
var $timestampField = "timestamp";
var $portIdField = "NASPortId";
var $portTypeField = "NASPortType";
var $startTimeField = "AcctStartTime";
var $stopTimeField = "AcctStopTime";
var $durationField = "AcctSessionTime";
var $inputTrafficField = "AcctInputOctets";
var $outputTrafficField = "AcctOutputOctets";
var $serviceTypeField = "ServiceType";
var $cNumberField = "CalledStationId";
var $aNumberField = "CallingStationId";
var $disconnectField = "H323DisconnectCause";
var $traceIn = "";
var $traceOut = "";
var $defaultApplicationType = "audio";
var $supportedApplicationTypes = array('audio',
'presence',
'message',
'video'
);
function CDR() {
}
function NormalizeDisconnect() {
$causePrint=$this->CDRS->disconnectCodesDescription[$this->disconnect]." (".$this->disconnect.")";
return $causePrint;
}
function traceOut () {
}
function traceIn () {
}
function show() {
}
function normalize($save="",$table) {
- if (!$table) $table=&$this->CDRS->table;
+ if (!$table) $table = $this->CDRS->table;
if ($this->CDRS->CSCODE && $CarrierInfo = $this->CDRS->CDRTool['normalize'][CS_CODES][$this->CDRS->CSCODE]) {
// We found a carrier so we set the BillingId
$this->BillingId = $CarrierInfo[BillingPartyId];
}
if ($save) {
+ if (!$this->id) {
+ return 0;
+ }
+
$query ="";
$query1 ="";
$query2 ="";
if ($this->CDRS->normalizedField) {
$Field=$this->CDRS->normalizedField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query .= " $Field = '1' ";
$updatedFields++;
}
if ($this->CDRS->DestinationIdField) {
$Field=$this->CDRS->DestinationIdField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".$this->DestinationId."' ";
}
if ($this->usernameNormalized && $this->usernameNormalized!=$this->username) {
$Field=$this->CDRS->usernameField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->usernameNormalized)."' ";
}
if ($this->aNumberNormalized && $this->aNumberNormalized!=$this->aNumber) {
$Field=$this->CDRS->aNumberField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->aNumberNormalized)."' ";
$this->aNumber=$this->aNumberNormalized;
}
if ($this->CDRS->applicationTypeField && $this->applicationTypeNormalized) {
$Field=$this->CDRS->applicationTypeField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->applicationTypeNormalized)."' ";
$this->applicationType=$this->applicationTypeNormalized;
}
if ($this->domainNormalized && $this->domainNormalized != $this->domain) {
$Field=$this->CDRS->domainField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->domainNormalized)."' ";
$this->domainNumber=$this->domainNormalized;
$this->domain=$this->domainNormalized;
}
if ($this->cNumberNormalized && $this->cNumberNormalized!=$this->cNumber) {
$Field=$this->CDRS->cNumberField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->cNumberNormalized)."' ";
$this->cNumber=$this->cNumberNormalized;
}
- if ($this->CDRS->CustomerNameField && $this->CustomerName) {
- $Field=$this->CDRS->CustomerNameField;
- if ($updatedFields) $query .= ", ";
- $updatedFields++;
- $query.=" $Field = '".addslashes($this->CustomerName)."' ";
- }
-
- if ($this->CDRS->CustomerIdField && $this->CustomerId) {
- $Field=$this->CDRS->CustomerIdField;
- if ($updatedFields) $query .= ", ";
- $updatedFields++;
- $query.=" $Field = '".addslashes($this->CustomerId)."' ";
- }
-
if ($this->CDRS->BillingIdField && $this->BillingId) {
$Field=$this->CDRS->BillingIdField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->BillingId)."' ";
}
if ($this->CDRS->RemoteAddressField && $this->RemoteAddressNormalized && $this->RemoteAddressNormalized!= $this->RemoteAddress) {
$Field=$this->CDRS->RemoteAddressField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->RemoteAddressNormalized)."' ";
}
if ($this->CDRS->CanonicalURIField && $this->CanonicalURINormalized && $this->CanonicalURINormalized!= $this->CanonicalURI) {
$Field=$this->CDRS->CanonicalURIField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".addslashes($this->CanonicalURINormalized)."' ";
}
if ($this->CDRS->ratingEnabled && $this->duration) {
+ /*
+ # since we changed the lookup of the rating entries directly to mysql query
+ # it seems that is faster not to go over the network
+
if ($this->CDRS->RatingEngineSocket && $this->NetworkRateDictionary) {
// get pricing from network rating engine
$this->lookupRateFromNetwork(&$this->NetworkRateDictionary,&$this->CDRS->RatingEngineSocket);
} else {
+ $Rate = new Rate($this->CDRS->rating_settings, $this->cdrtool);
- $Rate = new Rate($this->CDRS->rating_settings, $this->cdrtool);
$RateDictionary=array(
'callId' => $this->callId,
'timestamp' => $this->timestamp,
'duration' => $this->duration,
'DestinationId' => $this->DestinationId,
'inputTraffic' => $this->inputTraffic,
'outputTraffic' => $this->outputTraffic,
'BillingPartyId' => $this->BillingPartyId,
'domain' => $this->domain,
'gateway' => $this->gateway,
'RatingTables' => &$this->CDRS->RatingTables,
'applicationType' => $this->applicationType,
'aNumber' => $this->aNumber,
'cNumber' => $this->cNumber,
- 'destinationName' => $this->destinationName,
'ENUMtld' => $this->ENUMtld
);
$Rate->calculate(&$RateDictionary);
-
+
$this->pricePrint = $Rate->pricePrint;
$this->price = $Rate->price;
$this->rateInfo = $Rate->rateInfo;
-
}
+ */
+
+ $Rate = new Rate($this->CDRS->rating_settings, $this->cdrtool);
+
+ $RateDictionary=array(
+ 'callId' => $this->callId,
+ 'timestamp' => $this->timestamp,
+ 'duration' => $this->duration,
+ 'DestinationId' => $this->DestinationId,
+ 'inputTraffic' => $this->inputTraffic,
+ 'outputTraffic' => $this->outputTraffic,
+ 'BillingPartyId' => $this->BillingPartyId,
+ 'domain' => $this->domain,
+ 'gateway' => $this->gateway,
+ 'RatingTables' => &$this->CDRS->RatingTables,
+ 'applicationType' => $this->applicationType,
+ 'aNumber' => $this->aNumber,
+ 'cNumber' => $this->cNumber,
+ 'ENUMtld' => $this->ENUMtld
+ );
+
+ $Rate->calculate(&$RateDictionary);
+
+ $this->pricePrint = $Rate->pricePrint;
+ $this->price = $Rate->price;
+ $this->rateInfo = $Rate->rateInfo;
if ($this->CDRS->priceField) {
$Field=$this->CDRS->priceField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".$this->pricePrint."' ";
if ($this->CDRS->rateField ) {
$Field=$this->CDRS->rateField;
if ($updatedFields) $query .= ", ";
$updatedFields++;
$query.=" $Field = '".$this->rateInfo."' ";
}
}
}
- if (!$this->id) {
- return 0;
- }
-
$query1 = sprintf("update %s set %s where %s = '%s'",$table,$query,$this->idField,$this->id);
if ($updatedFields) {
if ($this->CDRS->CDRdb1->query($query1)) {
if ($this->CDRS->CDRdb1->affected_rows()) {
if ($table == $this->CDRS->table) {
// cache usage only if current month
$_traffic=($this->inputTraffic+$this->outputTraffic)/2;
$_usage[$this->BillingPartyId]['usage']=array("calls" => 1,
"duration" => $this->duration,
"cost" => $Rate->price,
"traffic" => $_traffic
);
$this->cacheMonthlyUsage($_usage);
}
} else {
if (preg_match("/^(\w+)(\d{4})(\d{2})$/",$table,$m)) {
$previousTable=$m[1].date('Ym', mktime(0, 0, 0, $m[3]-1, "01", $m[2]));
$query2 = sprintf("update %s set %s where %s = '%s'",$previousTable,$query,$this->idField,$this->id);
if ($this->CDRS->CDRdb1->query($query2)) {
if ($previousTable == $this->CDRS->table) {
// cache usage only if current month
$_traffic=($this->inputTraffic+$this->outputTraffic)/2;
$_usage[$this->BillingPartyId]['usage']=array("calls" => 1,
"duration" => $this->duration,
"cost" => $Rate->price,
"traffic" => $_traffic
);
$this->cacheMonthlyUsage($_usage);
}
} else {
$log=sprintf ("Database error: %s (%s)",$this->CDRS->CDRdb1->Error,$this->CDRS->CDRdb1->Errno);
syslog(LOG_NOTICE, $log);
print($log);
return 0;
}
}
}
return 1;
} else {
$log=sprintf ("Database error: %s (%s)",$this->CDRS->CDRdb1->Error,$this->CDRS->CDRdb1->Errno);
syslog(LOG_NOTICE, $log);
print($log);
return 0;
}
}
} else {
if ($this->CDRS->BillingPartyIdField && $CarrierInfo['BillingPartyId']) {
$this->domain = $CarrierInfo[BillingDomain];
}
if ($this->usernameNormalized && $this->usernameNormalized!=$this->username) {
$this->username=$this->usernameNormalized;
}
if ($this->aNumberNormalized && $this->aNumberNormalized!=$this->aNumber) {
$this->aNumber=$this->aNumberNormalized;
}
if ($this->domainNormalized && $this->domainNormalized != $this->domain) {
$this->domainNumber=$this->domainNormalized;
}
if ($this->cNumberNormalized && $this->cNumberNormalized!=$this->cNumber) {
$this->cNumber=$this->cNumberNormalized;
}
if ($this->CDRS->RemoteAddressField && $this->RemoteAddressNormalized && $this->RemoteAddressNormalized!= $this->RemoteAddress) {
$this->RemoteAddress=$this->RemoteAddressNormalized;
}
}
return 1;
}
function cacheMonthlyUsage($accounts) {
if (!is_array($accounts)) return ;
foreach (array_keys($accounts) as $_account) {
if ($this->CallerIsLocal) {
$_usage = $this->CDRS->getMonthlyUsageFromCache($_account);
$accounts[$_account]['usage']['calls'] = $accounts[$_account]['usage']['calls'] + $_usage['calls'];
$accounts[$_account]['usage']['duration'] = $accounts[$_account]['usage']['duration'] + $_usage['duration'];
$accounts[$_account]['usage']['cost'] = $accounts[$_account]['usage']['cost'] + $_usage['cost'];
$accounts[$_account]['usage']['traffic'] = $accounts[$_account]['usage']['traffic'] + $_usage['traffic'];
} else {
return ;
}
}
$this->CDRS->cacheMonthlyUsage($accounts);
}
function isCallerLocal() {
return 0;
}
function isCalleeLocal() {
return 0;
}
function obfuscateCallerId() {
global $obfuscateCallerId;
if ($obfuscateCallerId) {
}
}
function lookupRateFromNetwork(&$RateDictionary,&$fp) {
$this->rateInfo='';
$this->pricePrint='';
$this->price='';
$countEndofLines=0;
$cmd="ShowPrice";
foreach (array_keys(&$RateDictionary) as $key) {
$cmd .=" ".$key."=".$RateDictionary[$key]." ";
}
$this->price = 0;
$this->pricePrint = "";
$this->rateInfo = "";
if (fputs($fp,"$cmd\n") !== false) {
$i=0;
while ($i < 100) {
$i++;
$line = fgets($fp,1024);
if (!$line) {
syslog(LOG_NOTICE, "Error: lookupRateFromNetwork(): connection to network socket died");
break;
}
if (preg_match("/^\n/",$line) || preg_match("/^END/",$line)) {
break;
}
if ($i == 1) {
$this->price = trim($line);
$this->pricePrint = number_format($this->price,4);
continue;
}
$this->rateInfo.=$line;
}
}
}
}
function getLocalTime($timezone,$timestamp) {
global $CDRTool;
if (!$timezone || $timezone == $CDRTool['provider']['timezone']) {
return date("Y-m-d H:i:s", $timestamp);
}
putenv("TZ=$timezone");
$startTimeLocal=date("Y-m-d H:i:s", $timestamp);
$timezone=$CDRTool['provider']['timezone'];
putenv("TZ=$timezone");
return $startTimeLocal;
}
function sec2hms ($duration) {
// return seconds in HH:MM:SS format
$sum1=$duration;
$duration_print="";
$duration_hour=floor($sum1/3600);
if ($duration_hour > 0) {
$sum1=$sum1-($duration_hour*3600);
$duration_print="$duration_hour:";
}
$duration_min=floor($sum1/60);
if ($duration_min > 0) {
$sum1=$sum1-($duration_min*60);
if ($duration_min < 10) {
$duration_min="0"."$duration_min";
}
$duration_print="$duration_print"."$duration_min:";
} else {
$duration_print="$duration_print"."00:";
}
if ($sum1< 10 ) {
$duration_sec="0"."$sum1";
} else {
$duration_sec=$sum1;
}
$duration_print="$duration_print"."$duration_sec";
return $duration_print;
}
function validDay($month,$day,$year) {
if (!$month || !$year) {
return $day;
}
while (1) {
if (!checkdate($month,$day,$year) && $day) {
$day--;
next;
} else {
break;
}
}
return $day;
}
$ratingLibFile=$CDRTool['Path']."/rating_lib.phtml";
if (is_readable($ratingLibFile)) {
require_once($ratingLibFile);
}
// include CDRTool modules defined in global.inc
foreach ($CDRToolModules as $module) {
$module_filename=$CDRTool['Path']."/cdrlib_".$module.".phtml";
if (is_readable($module_filename)) include($module_filename);
$module_filename=$CDRTool['Path']."/local/cdrlib_".$module.".phtml";
if (is_readable($module_filename)) include($module_filename);
}
function unLockNormalization ($dbid,$lockname) {
$query=sprintf("SELECT RELEASE_LOCK('%s')",$lockname);
$log=sprintf("Unlock %s",$lockname);
syslog(LOG_NOTICE, $log);
if (!$dbid->query($query)) {
$log="Error in unLockNormalization()";
syslog(LOG_NOTICE, $log);
}
}
?>

File Metadata

Mime Type
text/x-diff
Expires
Sat, Feb 1, 10:56 AM (23 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489240
Default Alt Text
(78 KB)

Event Timeline