diff --git a/library/cdr_opensips.php b/library/cdr_opensips.php index a2837ec..938a8be 100644 --- a/library/cdr_opensips.php +++ b/library/cdr_opensips.php @@ -1,5665 +1,5665 @@ 'RadAcctId', 'callId' => 'AcctSessionId', 'duration' => 'AcctSessionTime', 'startTime' => 'AcctStartTime', 'stopTime' => 'AcctStopTime', 'inputTraffic' => 'AcctInputOctets', 'outputTraffic' => 'AcctOutputOctets', 'flow' => 'ServiceType', 'aNumber' => 'CallingStationId', 'username' => 'UserName', 'domain' => 'Realm', 'cNumber' => 'CalledStationId', 'timestamp' => 'timestamp', 'SipMethod' => 'SipMethod', 'disconnect' => 'SipResponseCode', 'disconnectOrig' => 'AcctTerminateCause', 'SipFromTag' => 'SipFromTag', 'SipToTag' => 'SipToTag', 'RemoteAddress' => 'SipTranslatedRequestURI', 'SipCodec' => 'SipCodecs', 'SipUserAgents' => 'SipUserAgents', 'application' => 'SipApplicationType', 'BillingPartyId' => 'UserName', 'SipRPID' => 'SipRPID', 'SipProxyServer' => 'NASIPAddress', 'gateway' => 'SourceIP', 'SourceIP' => 'SourceIP', 'SourcePort' => 'SourcePort', 'CanonicalURI' => 'CanonicalURI', 'normalized' => 'Normalized', 'rate' => 'Rate', 'price' => 'Price', 'DestinationId' => 'DestinationId', 'ResellerId' => 'BillingId', 'MediaInfo' => 'MediaInfo', 'RTPStatistics' => 'RTPStatistics', 'ENUMtld' => 'ENUMtld', 'UserAgent' => 'UserAgent', 'FromHeader' => 'FromHeader' ); var $CDRNormalizationFields=array('id' => 'RadAcctId', 'callId' => 'AcctSessionId', 'username' => 'UserName', 'domain' => 'Realm', 'gateway' => 'SourceIP', 'duration' => 'AcctSessionTime', 'startTime' => 'AcctStartTime', 'stopTime' => 'AcctStopTime', 'inputTraffic' => 'AcctInputOctets', 'outputTraffic' => 'AcctOutputOctets', 'aNumber' => 'CallingStationId', 'cNumber' => 'CalledStationId', 'timestamp' => 'timestamp', 'disconnect' => 'SipResponseCode', 'RemoteAddress' => 'SipTranslatedRequestURI', 'CanonicalURI' => 'CanonicalURI', 'SipRPID' => 'SipRPID', 'SipMethod' => 'SipMethod', 'application' => 'SipApplicationType', 'flow' => 'ServiceType', 'BillingPartyId' => 'UserName', 'ResellerId' => 'BillingId', 'price' => 'Price', 'DestinationId' => 'DestinationId', 'ENUMtld' => 'ENUMtld' ); var $GROUPBY=array('UserName' => 'SIP Billing Party', 'CallingStationId' => 'SIP Caller Party', 'SipRPID' => 'SIP Remote Party Id', 'CanonicalURI' => 'SIP Canonical URI', 'DestinationId' => 'SIP Destination Id', 'NASIPAddress' => 'SIP Proxy', 'MediaInfo' => 'Media Information', 'SourceIP' => 'Source IP', 'Realm' => 'SIP Billing domain', 'UserAgent' => 'User Agent', 'SipCodecs' => 'Codec type', 'SipApplicationType' => 'Application', 'SipResponseCode' => 'SIP status code', 'BillingId' => 'Tech prefix', 'ServiceType' => 'Call Flow', ' ' => '-------------', 'hour' => 'Hour of day', 'DAYOFWEEK' => 'Day of Week', 'DAYOFMONTH' => 'Day of Month', 'DAYOFYEAR' => 'Day of Year', 'BYMONTH' => 'Month', 'BYYEAR' => 'Year' ); var $FormElements=array( "begin_hour","begin_min","begin_month","begin_day","begin_year","begin_datetime", "end_hour","end_min","end_month","end_day","end_year","end_datetime", "call_id","sip_proxy", "a_number","a_number_comp","UserName","UserName_comp","BillingId", "c_number","c_number_comp","DestinationId","ExcludeDestinations", "NASPortId","Realm","Realms", "SipMethod","SipCodec","SipRPID","UserAgent", "application","sip_status","sip_status_class","gateway", "duration","action","MONTHYEAR", "order_by","order_type","group_by", "cdr_source","trace", "ReNormalize","media_info","cdr_table","maxrowsperpage", "flow" ); function initCDRFields() { // init names of CDR fields foreach (array_keys($this->CDRFields) as $field) { $mysqlField=$this->CDRFields[$field]; $_field=$field."Field"; $this->$_field=$mysqlField; } } function LoadDisconnectCodes() { $query="select * from sip_status order by code"; $this->disconnectCodesElements[]=array("label"=>"Any Status","value"=>""); $this->disconnectCodesElements[]=array("label"=>"Undefined (0)","value"=>"0"); $this->disconnectCodesClassElements[]=array("label"=>"Any Status Class","value"=>""); if ($this->cdrtool->query($query)) { while($this->cdrtool->next_record()) { $key = $this->cdrtool->f('code'); $value = $this->cdrtool->f('description'); $value_print = $this->cdrtool->f('description')." (".$this->cdrtool->f('code').")"; if (preg_match("/^[^2-6]/",$key)) { continue; } $this->disconnectCodesElements[]=array("label"=>$value_print,"value"=>$key); $this->disconnectCodesDescription[$key]=$value; $class=substr($key,0,1); $class_text=substr($key,0,1)."XX (".$this->cdrtool->f('code_type').")"; if (!$seen[$class]) { $this->disconnectCodesClassElements[]=array("label"=>$class_text,"value"=>substr($key,0,1)); $this->disconnectCodesClassDescription[substr($key,0,1)]=$class_text; $seen[$class]++; } $i++; } } } function showTableHeader() { print " "; } function showExportHeader() { print "id,StartTime,StopTime,BillingParty,BillingDomain,PSTNCallerId,CallerParty,CalledParty,DestinationId,DestinationName,RemoteAddress,CanonicalURI,Duration,Price,SIPProxy,Caller KBIn,Called KBIn,CallingUserAgent,CalledUserAgent,StatusCode,StatusName,Codec,Media\n"; } function showTableHeaderSubscriber() { if (!$this->export) { print "
Id Start Time Flow SIP Caller Caller Location Sip Proxy Media SIP Destination Dur Price KBIn KBOut Codecs Status
"; } else { print "id,StartTime,StopTime,SIPBillingParty,SIPBillingDomain,RemotePartyId,CallerParty,CalledParty,DestinationId,DestinationName,RemoteAddress,CanonicalURI,Duration,Price,SIPProxy,Applications,Caller KBIn,Called KBIn,CallingUserAgent,CalledUserAgent,StatusCode,StatusName,Codec,Application\n"; } } function showTableHeaderStatistics() { $group_byPrint=$this->GROUPBY[$this->group_byOrig]; if (!$this->export) { print "
Id Start Time SIP Caller Caller Location Sip Proxy SIP Destination Duration Price KBIn KBOut
"; } else { print "id,Calls,Seconds,Minutes,Hours,Price,TrafficIn(MB),TrafficOut(MB),Success(%),Success(calls),Failure(%),Failure(calls),$group_byPrint,Description\n"; } } function initForm() { // form els added below must have global vars foreach ($this->FormElements as $_el) { global ${$_el}; ${$_el} = trim($_REQUEST[$_el]); } $action = "search"; if ($this->CDRTool['filter']['gateway']) { $gateway=$this->CDRTool["filter"]["gateway"]; } if ($this->CDRTool['filter']['aNumber']) { $UserName=$this->CDRTool['filter']['aNumber']; } if ($this->CDRTool['filter']['domain']) { $Realm = $this->CDRTool['filter']['domain']; } if (!$maxrowsperpage) $maxrowsperpage=15; $this->f = new form; if (isset($this->CDRTool['dataSourcesAllowed'])) { while (list($k,$v)=each($this->CDRTool['dataSourcesAllowed'])) { if ($this->DATASOURCES[$v]['invisible']) continue; $cdr_source_els[]=array("label"=>$this->DATASOURCES[$v]['name'],"value"=>$v); } } if (!$cdr_source) $cdr_source=$cdr_source_els[0]['value']; $this->f->add_element(array("name"=>"cdr_source", "type"=>"select", "options"=>$cdr_source_els, "size"=>"1", "extrahtml"=>"class=span2 onChange=\"document.datasource.submit.disabled = true; location.href = 'callsearch.phtml?cdr_source=' + this.options[this.selectedIndex].value\"", "value"=>"$cdr_source" ) ); $cdr_table_els=array(); foreach ($this->tables as $_table) { if (preg_match("/^.*(\d{6})$/",$_table,$m)) { $cdr_table_els[]=array("label"=>$m[1],"value"=>$_table); } else { $cdr_table_els[]=array("label"=>$_table,"value"=>$_table); } } $this->f->add_element(array( "name"=>"cdr_table", "type"=>"select", "options"=>$cdr_table_els, "size"=>"1", "class"=>"span2", "value"=>$cdr_table, "extrahtml"=>"class=span2" )); if ($begin_datetime) { preg_match("/^(\d\d\d\d)-(\d+)-(\d+)\s+(\d\d):(\d\d)/", "$begin_datetime", $parts); $begin_year =date(Y,$begin_datetime); $begin_month=date(m,$begin_datetime); $begin_day =date(d,$begin_datetime); $begin_hour =date(H,$begin_datetime); $begin_min =date(i,$begin_datetime); } else { $begin_day = $_REQUEST["begin_day"]; $begin_month = $_REQUEST["begin_month"]; $begin_year = $_REQUEST["begin_year"]; $begin_hour = $_REQUEST["begin_hour"]; $begin_min = $_REQUEST["begin_min"]; } if ($end_datetime) { preg_match("/^(\d\d\d\d)-(\d+)-(\d+)\s+(\d\d):(\d\d)/", "$end_datetime", $parts); $end_year =date(Y,$end_datetime); $end_month =date(m,$end_datetime); $end_day =date(d,$end_datetime); $end_hour =date(H,$end_datetime); $end_min =date(i,$end_datetime); } else { $end_day = $_REQUEST["end_day"]; $end_month = $_REQUEST["end_month"]; $end_year = $_REQUEST["end_year"]; $end_hour = $_REQUEST["end_hour"]; $end_min = $_REQUEST["end_min"]; } // corect last day of the month to be valid day $begin_day = validDay($begin_month,$begin_day,$begin_year); $end_day = validDay($end_month,$end_day,$end_year); $default_year = Date("Y"); $default_month = Date("m"); $default_day = Date("d"); $default_hour = Date(H,time()); if ($default_hour > 1) $default_hour=$default_hour-1; $default_hour = preg_replace("/^(\d)$/","0$1",$default_hour); $default_min = Date("i"); if ($default_min > 10) { $default_min=$default_min-10; $default_min=preg_replace("/^(\d)$/","0$1",$default_min); } if (!$begin_hour) $begin_hour = $default_hour; if (!$begin_min) $begin_min = $default_min; if (!$begin_day) $begin_day = $default_day; if (!$begin_month) $begin_month = $default_month; if (!$begin_year) $begin_year = $default_year; if (!$end_hour) $end_hour = 23; if (!$end_min) $end_min = 55; if (!$end_day) $end_day = $default_day; if (!$end_month) $end_month = $default_month; if (!$end_year) $end_year = $default_year; $m=0; while ($m<24) { if ($m<10) { $v="0".$m; } else { $v=$m; } $hours_els[]=array("label"=>$v,"value"=>$v); $m++; } $this->f->add_element(array( "name"=>"begin_hour", "type"=>"select", "options"=>$hours_els, "size"=>"1", "extrahtml"=>"class=span1" )); $this->f->add_element(array( "name"=>"end_hour", "type"=>"select", "options"=>$hours_els, "size"=>"1", "value"=>"23", "extrahtml"=>"class=span1" )); $m=0; while ($m<60) { if ($m<10) { $v="0".$m; } else { $v=$m; } $min_els[]=array("label"=>$v,"value"=>$v); $m++; } $this->f->add_element(array( "name"=>"begin_min", "type"=>"select", "options"=>$min_els, "size"=>"1", "extrahtml"=>"class=span1" )); $this->f->add_element(array( "name"=>"end_min", "type"=>"select", "options"=>$min_els, "size"=>"1", "extrahtml"=>"class=span1" )); $m=1; while ($m<32) { if ($m<10) { $v="0".$m; } else { $v=$m; } $days_els[]=array("label"=>$v,"value"=>$v); $m++; } $this->f->add_element(array( "name"=>"begin_day", "type"=>"select", "options"=>$days_els, "size"=>"1", "extrahtml"=>"class=span1" )); $this->f->add_element(array( "name"=>"end_day", "type"=>"select", "options"=>$days_els, "size"=>"1", "extrahtml"=>"class=span1" )); $m=1; while ($m<13) { if ($m<10) { $v="0".$m; } else { $v=$m; } $month_els[]=array("label"=>$v,"value"=>$v); $m++; } $this->f->add_element(array( "name"=>"begin_month", "type"=>"select", "options"=>$month_els, "size"=>"1", "extrahtml"=>"class=span1" )); $this->f->add_element(array( "name"=>"end_month", "type"=>"select", "options"=>$month_els, "size"=>"1", "extrahtml"=>"class=span1" )); $thisYear=date("Y",time()); $y=$thisYear; while ($y>$thisYear-6) { $year_els[]=array("label"=>$y,"value"=>$y); $y--; } $this->f->add_element(array( "name"=>"begin_year", "type"=>"select", "options"=>$year_els, "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"end_year", "type"=>"select", "options"=>$year_els, "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"call_id", "type"=>"text", "size"=>"50", "maxlength"=>"100", "extrahtml"=>"class=span4" )); $this->f->add_element(array( "name"=>"UserName", "type"=>"text", "size"=>"25", "maxlength"=>"255", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"a_number", "type"=>"text", "size"=>"25", "maxlength"=>"255", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"BillingId", "type"=>"text", "size"=>"25", "maxlength"=>"255", "extra_html"=>"class=span2" )); $this->f->add_element(array( "name"=>"c_number", "type"=>"text", "size"=>"25", "maxlength"=>"255", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"sip_status", "type"=>"select", "options"=>$this->disconnectCodesElements, "size"=>"1", "value"=>$sip_status, "extrahtml"=>"class=span3" )); $this->f->add_element(array( "name"=>"sip_status_class", "type"=>"select", "options"=>$this->disconnectCodesClassElements, "size"=>"1", "extrahtml"=>"class=span3" )); if (!$this->CDRTool['filter']['aNumber']) { $durations_els = array( array("label"=>"All calls","value"=>""), array("label"=>"0 seconds","value"=>"zero"), array("label"=>"non 0 seconds","value"=>"nonzero"), array("label"=>"non 0 seconds without price","value"=>"zeroprice"), array("label"=>"less than 5 seconds","value"=>"< 5"), array("label"=>"more than 5 seconds","value"=>"> 5"), array("label"=>"less than 60 seconds","value"=>"< 60"), array("label"=>"greater than 1 hour","value"=>"> 3600"), array("label"=>"one hour","value"=>"onehour"), array("label"=>"greater than 5 hours","value"=>"> 18000"), array("label"=>"Un-normalized calls","value"=>"unnormalized"), array("label"=>"Un-normalized calls > 0s","value"=>"unnormalized_duration"), array("label"=>"One way media","value"=>"onewaymedia"), array("label"=>"No media","value"=>"nomedia") ); } else { $durations_els = array( array("label"=>"All calls","value"=>""), array("label"=>"0 seconds call","value"=>"zero"), array("label"=>"Succesfull calls","value"=>"nonzero"), array("label"=>"less than 60 seconds","value"=>"< 60"), array("label"=>"greater than 1 hour","value"=>"> 3600") ); $this->GROUPBY=array( 'UserName' => 'SIP Billing Party', 'CallingStationId' => 'SIP Caller Party', 'DestinationId' => 'SIP Destination Id', 'SipApplicationType' => 'Application', ' ' => '-------------', 'hour' => 'Hour of day', 'DAYOFWEEK' => 'Day of Week', 'DAYOFMONTH' => 'Day of Month', 'DAYOFYEAR' => 'Day of Year', 'BYMONTH' => 'Month', 'BYYEAR' => 'Year' ); } $flow_els = array( array("label"=>"Any Call Flow","value"=>""), array("label"=>"On Net","value"=>"on-net"), array("label"=>"Incoming","value"=>"incoming"), array("label"=>"Outgoing","value"=>"outgoing"), array("label"=>"Transit","value"=>"transit"), array("label"=>"Diverted On Net","value"=>"diverted-on-net"), array("label"=>"Diverted Off Net","value"=>"diverted-off-net"), array("label"=>"On Net Diverted On Net","value"=>"on-net-diverted-on-net"), array("label"=>"On Net Diverted Off Net","value"=>"on-net-diverted-off-net"), array("label"=>"Unknown Flow","value"=>"Sip-Session") ); $this->f->add_element(array( "name"=>"flow", "type"=>"select", "options"=>$flow_els, "value"=>"", "size"=>"1", "extrahtml"=>"class=span3" )); $this->f->add_element(array( "name"=>"duration", "type"=>"select", "options"=>$durations_els, "value"=>"All", "size"=>"1", "extrahtml"=>"class=span3" )); $comp_ops_els = array( array("label"=>"Begins with","value"=>"begin"), array("label"=>"Contains","value"=>"contain"), array("label"=>"Is empty","value"=>"empty"), array("label"=>"Equal","value"=>"equal") ); $this->f->add_element(array( "name"=>"a_number_comp", "type"=>"select", "options"=>$comp_ops_els, "value"=>"begin", "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"c_number_comp", "type"=>"select", "options"=>$comp_ops_els, "value"=>"begin", "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"UserName_comp", "type"=>"select", "options"=>$comp_ops_els, "value"=>"begin", "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array( "name"=>"Realm", "type"=>"text", "size"=>"25", "maxlength"=>"25", "extrahtml"=>"class=span2" )); $media_info_els=array( array("label"=>"","value"=>""), array("label"=>"Timeout","value"=>"timeout"), array("label"=>"ICE session","value"=>"ICE session") ); $this->f->add_element(array( "name"=>"media_info", "type"=>"select", "options"=>$media_info_els, "size"=>"1", "value"=>"", "extrahtml"=>"class=span2" )); $this->f->add_element(array("type"=>"submit", "name"=>"submit", "value"=>"Search","extrahtml"=>"class=btn" )); $max_els=array( array("label"=>"5","value"=>"5"), array("label"=>"10","value"=>"10"), array("label"=>"15","value"=>"15"), array("label"=>"25","value"=>"25"), array("label"=>"50","value"=>"50"), array("label"=>"100","value"=>"100"), array("label"=>"500","value"=>"500") ); $this->f->add_element(array( "name"=>"maxrowsperpage", "type"=>"select", "options"=>$max_els, "size"=>"1", "value"=>"25", "extrahtml"=>"class=span2" )); $order_type_els=array( array("label"=>"Descending","value"=>"DESC"), array("label"=>"Ascending","value"=>"ASC") ); $this->f->add_element(array( "name"=>"order_type", "type"=>"select", "options"=>$order_type_els, "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array("type"=>"hidden", "name"=>"action", "value"=>$action )); $order_by_els=array(array("label"=>"Id","value"=>"RadAcctId"), array("label"=>"Date","value"=>"AcctStopTime"), array("label"=>"Billing Party","value"=>"UserName"), array("label"=>"Remote Party Id","value"=>"SipRPID"), array("label"=>"Caller Party","value"=>"CallingStationId"), array("label"=>"Destination","value"=>"CalledStationId"), array("label"=>"Duration","value"=>"AcctSessionTime"), array("label"=>"Input traffic","value"=>"AcctInputOctets"), array("label"=>"Output traffic","value"=>"AcctOutputOctets"), array("label"=>"Price","value"=>"Price"), array("label"=>"Failures(%)","value"=>"zeroP"), array("label"=>"Success(%)","value"=>"nonzeroP"), array("label"=>"Group by","value"=>"group_by") ); $group_by_els[]=array("label"=>"","value"=>""); while (list($k,$v)=each($this->GROUPBY)) { $group_by_els[]=array("label"=>$v,"value"=>$k); } $this->f->add_element(array("name"=>"order_by", "type"=>"select", "options"=>$order_by_els, "value"=>$order_by, "size"=>"1", "extrahtml"=>"class=span3" )); $this->f->add_element(array("name"=>"group_by", "type"=>"select", "options"=>$group_by_els, "value"=>$group_by, "size"=>"1", "extrahtml"=>"class=span3" )); $application_els=array( array("label"=>"Any Application", "value"=>""), array("label"=>"Audio", "value"=>"audio"), array("label"=>"Video", "value"=>"video"), array("label"=>"Message" , "value"=>"message"), array("label"=>"IM Chat" , "value"=>"chat"), array("label"=>"Audio + Chat" , "value"=>"audio=2C chat"), array("label"=>"File Transfer","value"=>"file-transfer") ); $this->f->add_element(array("name"=>"application", "type"=>"select", "options"=>$application_els, "value"=>$application, "size"=>"1", "extrahtml"=>"class=span2" )); $this->f->add_element(array("name"=>"UserAgent", "type"=>"text", "size"=>"25", "maxlength"=>"50", "value"=>$UserAgent, "extrahtml"=>"class=span2" )); $this->f->add_element(array("name"=>"SipCodec", "type"=>"text", "size"=>"10", "maxlength"=>"50", "value"=>$SipCodec, "extrahtml"=>"class=span2" )); $this->f->add_element(array("name"=>"sip_proxy", "type"=>"text", "size"=>"25", "maxlength"=>"255", "value"=>$sip_proxy, "extrahtml"=>"class=span2" )); $this->f->add_element(array("name"=>"gateway", "type"=>"text", "size"=>"25", "maxlength"=>"255", "value"=>$gateway, "extrahtml"=>"class=span2" )); $this->f->add_element(array("name"=>"DestinationId", "type"=>"text", "size"=>"10", "extrahtml"=>"class=span3" )); $this->f->add_element(array( "name"=>"ExcludeDestinations", "type"=>"text", "size"=>"20", "maxlength"=>"255", "extrahtml"=>"class=span3" )); $this->f->load_defaults(); } function searchForm() { global $perm; $this->initForm(); $this->f->start("","POST","","","datasource"); print "
Calls Seconds Minutes Hours Price TrafficIn(MB) TrafficOut(MB) Success Failure $group_byPrint Description Action
"; $this->showDataSources ($this->f); $this->showDateTimeElements ($this->f); // freeze some form els if ($this->CDRTool['filter']['aNumber']) { $ff[]="a_number"; $ff[]="a_number_comp"; $ff[]="UserName"; $ff[]="UserName_comp"; } if ($this->CDRTool['filter']['domain']) { $Realm=$this->CDRTool['filter']['domain']; $ff[]="Realm"; } if ($this->CDRTool['filter']['gateway']) { $gateway=$this->CDRTool['filter']['gateway']; $ff[]="gateway"; } if (count($ff)) { $this->f->freeze($ff); } print " "; print " "; print " "; print " "; print " "; print " "; print " "; print " "; print "

"; $this->f->show_element("submit",""); $this->f->finish(); print "
"; } function searchFormSubscriber() { global $perm; $this->initForm(); $this->f->start("","POST","","","datasource"); print " "; $this->showDataSources ($this->f); $this->showDateTimeElements ($this->f); // freeze some form els if ($this->CDRTool['filter']['aNumber']) { $ff[]="UserName"; } if ($this->CDRTool['filter']['domain']) { $ff[]="Realm"; } if ($this->CDRTool["filter"]["gateway"]) { $ff[]="gateway"; } if (count($ff)) { $this->f->freeze($ff); } print " "; print " "; print " "; print " "; print " "; print "

"; $this->f->show_element("submit",""); $this->f->finish(); print "
"; } function show() { global $perm; if (!is_object($this->CDRdb)) { $log=sprintf("Error: CDR database is not initalized"); print $log; return false; } foreach ($this->FormElements as $_el) { ${$_el} = trim($_REQUEST[$_el]); } // overwrite some elements based on user rights if ($this->CDRTool['filter']['gateway']) { $gateway =$this->CDRTool['filter']['gateway']; } if (!$this->export) { if (!$begin_datetime) { $begin_datetime="$begin_year-$begin_month-$begin_day $begin_hour:$begin_min"; $begin_datetime_timestamp=mktime($begin_hour, $begin_min, 0, $begin_month,$begin_day,$begin_year); } else { $begin_datetime_timestamp=$begin_datetime; $begin_datetime=Date("Y-m-d H:i",$begin_datetime); } if (!$end_datetime) { $end_datetime_timestamp=mktime($end_hour, $end_min, 0, $end_month,$end_day,$end_year); $end_datetime="$end_year-$end_month-$end_day $end_hour:$end_min"; } else { $end_datetime_timestamp=$end_datetime; $end_datetime=Date("Y-m-d H:i",$end_datetime); } } else { $begin_datetime=Date("Y-m-d H:i",$begin_datetime); $end_datetime=Date("Y-m-d H:i",$end_datetime); } if (!$order_by || (!$group_by && $order_by == "group_by")) { $order_by=$this->idField; } if (!$cdr_table) $cdr_table=$this->table; $this->url=sprintf("?cdr_source=%s&cdr_table=%s",$this->cdr_source,$cdr_table); if ($this->CDRTool['filter']['domain']) { $this->url .= sprintf("&Realms=%s",urlencode($this->CDRTool['filter']['domain'])); $Realms = explode(" ",$this->CDRTool['filter']['domain']); } else if ($Realms) { $this->url .= sprintf("&Realms=%s",urlencode($Realms)); $Realms = explode(" ",$Realms); } if ($this->CDRTool['filter']['aNumber']) { $this->url .= sprintf("&UserName=%s",urlencode($this->CDRTool['filter']['aNumber'])); } if ($this->CDRTool['filter']['after_date']) { $where .= sprintf(" and %s >= '%s' ",addslashes($this->startTimeField),addslashes($this->CDRTool['filter']['after_date'])); } if ($order_by) { $this->url.=sprintf("&order_by=%s&order_type=%s",addslashes($order_by),addslashes($order_type)); } $this->url.=sprintf("&begin_datetime=%s",urlencode($begin_datetime_timestamp)); $this->url.=sprintf("&end_datetime=%s",urlencode($end_datetime_timestamp)); if (!$call_id && $begin_datetime && $end_datetime) { $where .= sprintf(" (%s >= '%s' and %s < '%s') ",addslashes($this->startTimeField),addslashes($begin_datetime),addslashes($this->startTimeField), addslashes($end_datetime)); } else { $where .= sprintf(" (%s >= '1970-01-01' ) ",addslashes($this->startTimeField)); } if ($MONTHYEAR) { $where .= sprintf(" and %s like '%s%s' ", addslashes($this->startTimeField), addslashes($MONTHYEAR), '%'); $this->url.= sprintf("&MONTHYEAR=%s",urlencode($MONTHYEAR)); } if ($flow) { $this->url.=sprintf("&flow=%s",urlencode($flow)); $where .= sprintf(" and %s = '%s' ", addslashes($this->flowField), addslashes($flow)); } if ($this->CDRTool['filter']['aNumber']) { // force user to see only CDRS with his a_numbers $where .= sprintf(" and ( %s = '%s' or %s = '%s') ", addslashes($this->usernameField), addslashes($this->CDRTool['filter']['aNumber']), addslashes($this->CanonicalURIField), addslashes($this->CDRTool['filter']['aNumber']) ); $UserName_comp='equal'; $UserName=$this->CDRTool['filter']['aNumber']; } if ($UserName_comp == "empty") { $where .= sprintf(" and %s = ''", addslashes($this->usernameField)); $this->url.=sprintf("&UserName_comp=%s",urlencode($UserName_comp)); } else if (strlen($UserName) && !$this->CDRTool['filter']['aNumber']) { if (!$UserName_comp) $UserName_comp='begin'; if ($UserName_comp=="begin") { $where .= sprintf(" and %s like '%s%s'", addslashes($this->usernameField), addslashes($UserName), '%'); } elseif ($UserName_comp=="contain") { $where .= sprintf(" and %s like '%s%s%s'", addslashes($this->usernameField), '%', addslashes($UserName), '%'); } elseif ($UserName_comp=="equal") { $where .= sprintf(" and %s = '%s'", addslashes($this->usernameField), addslashes($UserName)); } else { $where .= sprintf(" and %s = ''", addslashes($this->usernameField)); } $this->url.=sprintf("&UserName=%s&UserName_comp=%s",urlencode($UserName),$UserName_comp); } $a_number=trim($a_number); if ($a_number_comp == "empty") { $where .= sprintf(" and %s = ''", addslashes($this->aNumberField)); $this->url.=sprintf("&a_number_comp=%s",urlencode($a_number_comp)); } else if (strlen($a_number)) { $a_number=urldecode($a_number); if (!$a_number_comp) $a_number_comp="equal"; $this->url.=sprintf("&a_number=%s",urlencode($a_number)); if ($a_number_comp=="begin") { $where .= sprintf(" and %s like '%s%s'", addslashes($this->aNumberField), addslashes($a_number), '%'); } elseif ($a_number_comp=="contain") { $where .= sprintf(" and %s like '%s%s%s'", addslashes($this->aNumberField), '%', addslashes($a_number), '%'); } elseif ($a_number_comp=="equal") { $where .= sprintf(" and %s = '%s'", addslashes($this->aNumberField), addslashes($a_number)); } $this->url.=sprintf("&a_number_comp=%s",urlencode($a_number_comp)); } $c_number=trim($c_number); if ($c_number_comp == "empty") { $where .= sprintf(" and %s = ''", addslashes($this->CanonicalURIField)); $this->url.=sprintf("&c_number_comp=%s",urlencode($c_number_comp)); } else if (strlen($c_number)) { $c_number=urldecode($c_number); if (!$c_number_comp) $c_number_comp="begin"; if (!$c_number_comp || $c_number_comp=="begin") { $where .= sprintf(" and %s like '%s%s'", addslashes($this->CanonicalURIField), addslashes($c_number), '%'); } elseif ($c_number_comp=="contain") { $where .= sprintf(" and %s like '%s%s%s'", addslashes($this->CanonicalURIField), '%', addslashes($c_number), '%'); } elseif ($c_number_comp=="equal") { $where .= sprintf(" and %s = '%s'", addslashes($this->CanonicalURIField), addslashes($c_number)); } $this->url.=sprintf("&c_number=%s&c_number_comp=%s",urlencode($c_number),urlencode($c_number_comp)); } $Realm=trim($Realm); if ($Realms) { $where .= sprintf("and %s in (",$this->domainField); foreach ($Realms as $realm) { $where .= sprintf("'%s',",addslashes($realm)); } $where=rtrim($where, ","); $where .= ") "; } else if ($Realm) { $Realm=urldecode($Realm); $where .= sprintf(" and %s like '%s' ", $this->domainField, addslashes($Realm)); $this->url.=sprintf("&Realm=%s",urlencode($Realm)); } $BillingId=trim($BillingId); if (preg_match("/^\d+$/",$BillingId) && $this->BillingIdField) { $where .= " and $this->BillingIdField = '".addslashes($BillingId)."'"; $this->url.=sprintf("&BillingId=%s",urlencode($BillingId)); } if ($application) { $where .= " and $this->applicationField like '%".addslashes($application)."%'"; $this->url.=sprintf("&application=%s",urlencode($application)); } if ($DestinationId) { if ($DestinationId=="empty") { $DestinationIdSQL=""; } else { $DestinationIdSQL=$DestinationId; } $where .= " and $this->DestinationIdField = '".addslashes($DestinationIdSQL)."'"; $this->url.=sprintf("&DestinationId=%s",urlencode($DestinationId)); } if (strlen(trim($ExcludeDestinations))) { $ExcludeDestArray=explode(" ",trim($ExcludeDestinations)); foreach ($ExcludeDestArray as $exclDst) { if (preg_match("/^0+(\d+)$/",$exclDst,$m)) { $exclDest_id=$m[1]; } else { $exclDest_id=$exclDst; } $where .= " and ". $this->CanonicalURIField. " not like '". addslashes(trim($exclDst)). "'"; } $this->url.=sprintf("&ExcludeDestinations=%s",urlencode($ExcludeDestinations)); } $call_id=trim($call_id); if ($call_id) { $call_id=urldecode($call_id); $where .= " and $this->callIdField = '".addslashes($call_id)."'"; $this->url.=sprintf("&call_id=%s",urlencode($call_id)); } if ($sip_proxy) { $sip_proxy=urldecode($sip_proxy); $where .= " and $this->SipProxyServerField = '".addslashes($sip_proxy)."'"; $this->url.=sprintf("&sip_proxy=%s",urlencode($sip_proxy)); } if ($SipCodec) { $this->url.=sprintf("&SipCodec=%s",urlencode($SipCodec)); if ($SipCodec != "empty") { $where .= " and $this->SipCodecField = '".addslashes($SipCodec)."'"; } else { $where .= " and $this->SipCodecField = ''"; } } if ($SipRPID) { $this->url.=sprintf("&SipRPID=%s",urlencode($SipRPID)); if ($SipRPID != "empty") { $where .= " and $this->SipRPIDField = '".addslashes($SipRPID)."'"; } else { $where .= " and $this->SipRPIDField = ''"; } } if ($UserAgent) { $where .= " and $this->UserAgentField like '%".addslashes($UserAgent)."%'"; $this->url.=sprintf("&UserAgent=%s",urlencode($UserAgent)); } if (strlen($sip_status)) { $where .= " and $this->disconnectField ='".addslashes($sip_status)."'"; $this->url.=sprintf("&sip_status=%s",urlencode($sip_status)); } if ($sip_status_class) { $where .= " and $this->disconnectField like '$sip_status_class%'"; $this->url.=sprintf("&sip_status_class=%s",urlencode($sip_status_class)); } if ($this->CDRTool[filter]["gateway"]) { $gatewayFilter=$this->CDRTool[filter]["gateway"]; $where .= " and $this->gatewayField = '".addslashes($gatewayFilter)."'"; } else if ($gateway) { $gateway=urldecode($gateway); $where .= " and $this->gatewayField = '".addslashes($gateway)."'"; $this->url.=sprintf("&gateway=%s",urlencode($gateway)); } if ($duration) { if (preg_match("/\d+/",$duration) ) { $where .= " and ($this->durationField > 0 and $this->durationField $duration) "; } elseif (preg_match("/onehour/",$duration) ) { $where .= " and ($this->durationField < 3610 and $this->durationField > 3530) "; } elseif ($duration == "zero") { $where .= " and $this->durationField = 0"; } elseif ($duration == "zeroprice" && $this->priceField) { $where .= " and $this->durationField > 0 and ($this->priceField = '' or $this->priceField is NULL)"; $mongo_where[$this->priceField] = ''; } elseif ($duration == "nonzero") { $where .= " and $this->durationField > 0"; } elseif ($duration == "onewaymedia") { $where .= " and (($this->inputTrafficField > 0 && $this->outputTrafficField = 0) || ($this->inputTrafficField = 0 && $this->outputTrafficField > 0)) " ; } elseif ($duration == "nomedia") { $where .= " and ($this->inputTrafficField = 0 && $this->outputTrafficField = 0) " ; } $this->url.=sprintf("&duration=%s",urlencode($duration)); } if ($media_info) { $this->url.=sprintf("&media_info=%s",urlencode($media_info)); $where .= sprintf(" and %s = '%s' ",addslashes($this->MediaInfoField), addslashes($media_info)); } $this->url.=sprintf("&maxrowsperpage=%s",addslashes($this->maxrowsperpage)); $url_calls = $this->scriptFile.$this->url."&action=search"; if ($group_by) { $this->url.=sprintf("&group_by=%s",urlencode($group_by)); } $this->url_edit = $this->scriptFile.$this->url."&action=edit"; $this->url_run = $this->scriptFile.$this->url."&action=search"; $this->url_export = $_SERVER["PHP_SELF"].$this->url."&action=search&export=1"; if ($duration == "unnormalized") { $where .= " and $this->normalizedField = '0' "; } if ($duration == "unnormalized_duration") { $where .= " and $this->normalizedField = '0' and $this->durationField > 0 "; } if ($group_by) { $this->group_byOrig=$group_by; if ($group_by=="hour") { $group_by="HOUR(AcctStartTime)"; } else if (preg_match("/^DAY/",$group_by)) { $group_by="$group_by(AcctStartTime)"; } else if (preg_match("/BYMONTH/",$group_by)) { $group_by="DATE_FORMAT(AcctStartTime,'%Y-%m')"; } else if (preg_match("/BYYEAR/",$group_by)) { $group_by="DATE_FORMAT(AcctStartTime,'%Y')"; } else if ($group_by=="UserAgentType") { $group_by="SUBSTRING_INDEX($this->SipUserAgentsField, ' ', '1')"; } $this->group_by=$group_by; if ($group_by==$this->callIdField) { $having=sprintf(" having count(%s) > 1 ", addslashes($group_by)); } $query= sprintf("select sum(%s) as duration, SEC_TO_TIME(sum(%s)) as duration_print, count(%s) as calls, %s from %s where %s group by %s %s ", addslashes($this->durationField), addslashes($this->durationField), $group_by, $group_by, addslashes($cdr_table), $where, $group_by, $having ); } else { $query = sprintf("select count(*) as records from %s where ", addslashes($cdr_table)). $where; } dprint($query); if ($this->CDRdb->query($query)) { $this->CDRdb->next_record(); if ($group_by) { $rows = $this->CDRdb->num_rows(); } else { $rows = $this->CDRdb->f('records'); } } else { printf ("%s",$this->CDRdb->Error); $rows = 0; } $this->rows=$rows; if ($this->CDRTool['filter']['aNumber']) { $this->showResultsMenuSubscriber('0',$begin_datetime,$end_datetime); } else { $this->showResultsMenu('0',$begin_datetime,$end_datetime); } if (!$this->next) { $i=0; $this->next=0; } else { $i=intval($this->next); } $j=0; $z=0; if ($rows>0) { if ($call_id && $ReNormalize) { $query=sprintf("update %s set %s = '0' where %s = '%s'", addslashes($cdr_table), addslashes($this->normalizedField), addslashes($this->callIdField), addslashes($call_id) ); $this->CDRdb->query($query); } if ($UnNormalizedCalls=$this->getUnNormalized($where,$cdr_table)) { if (!$this->DATASOURCES[$this->cdr_source]['skipNormalizeOnPageLoad']) { if ($UnNormalizedCalls < $this->maxCDRsNormalizeWeb) { $this->NormalizeCDRS($where,$cdr_table); if (!$this->export && $this->status['normalized'] ) { print "
"; print "  "; printf ("%d CDRs normalized. ",$this->status['normalized']); if ($this->status['cached_keys']['saved_keys']) { printf ("Quota usage updated for %d accounts. ",$this->status['cached_keys']['saved_keys']); } print "
"; } } } } if ($rows > $this->maxrowsperpage) { $maxrows=$this->maxrowsperpage+$this->next; if ($maxrows > $rows) { $maxrows=$rows; $prev_rows=$maxrows; } } else { $maxrows=$rows; } if ($duration == "unnormalized") { // if display un normalized calls we must substract // the amount of calls normalized above $maxrows=$maxrows-$this->status['normalized']; } if ($group_by) { if ($order_by=="group_by") { $order_by1=$group_by; } else { if ($order_by == $this->inputTrafficField || $order_by == $this->outputTrafficField || $order_by == $this->durationField || $order_by == $this->priceField || $order_by == "zeroP" || $order_by == "nonzeroP" ) { $order_by1=$order_by; } else { $order_by1="calls"; } } $this->SipMethodField=$this->CDRFields['SipMethod']; $query= " select sum($this->durationField) as $this->durationField, SEC_TO_TIME(sum($this->durationField)) as hours, count($group_by) as calls, $this->SipMethodField, 2*sum($this->inputTrafficField)/1024/1024 as $this->inputTrafficField, 2*sum($this->outputTrafficField)/1024/1024 as $this->outputTrafficField, SUM($this->durationField = '0') as zero, SUM($this->durationField > '0') as nonzero, "; if ($order_by=="zeroP" || $order_by=="nonzeroP") { $query.=" SUM($this->durationField = '0')/count($group_by)*100 as zeroP, SUM($this->durationField > '0')/count($group_by)*100 as nonzeroP, "; } $query.=" sum($this->inputTrafficField)*8*2/1024/sum($this->durationField) as netrate_in, sum($this->outputTrafficField)*8*2/1024/sum($this->durationField) as netrate_out "; if ($this->priceField) { $query.= ", sum($this->priceField) as $this->priceField "; } $_max_rows = intval($this->maxrowsperpage); if (!$_max_rows) { $_max_rows = 10; } /* $query.= " , $group_by as mygroup from $cdr_table where $where group by $group_by $having order by $order_by1 $order_type limit $i,$_max_rows "; */ $query.= sprintf(", %s as mygroup from %s where %s group by %s %s order by %s %s limit %d, %d ", $group_by, addslashes($cdr_table), $where, $group_by, addslashes($having), addslashes($order_by1), addslashes($order_type), $i, $_max_rows); dprint($query); $this->CDRdb->query($query); $this->showTableHeaderStatistics(); while ($i<$maxrows) { $found=$i+1; $this->CDRdb->next_record(); $calls = $this->CDRdb->f('calls'); $seconds = $this->CDRdb->f($this->durationField); $seconds = $this->CDRdb->f($this->durationField); $seconds_print = number_format($this->CDRdb->f($this->durationField),0); $minutes = number_format($this->CDRdb->f($this->durationField)/60,0,"",""); $minutes_print = number_format($this->CDRdb->f($this->durationField)/60,0); $hours = $this->CDRdb->f('hours'); $AcctInputOctets = number_format($this->CDRdb->f($this->inputTrafficField),2,".",""); $AcctOutputOctets = number_format($this->CDRdb->f($this->outputTrafficField),2,".",""); $NetRateIn = $this->CDRdb->f('netrate_in'); $NetRateOut = $this->CDRdb->f('netrate_out'); $SipMethod = $this->CDRdb->f($this->callTypeField); $AcctTerminateCause = $this->CDRdb->f($this->disconnectField); $mygroup = $this->CDRdb->f('mygroup'); $zero = $this->CDRdb->f('zero'); $nonzero = $this->CDRdb->f('nonzero'); $success = number_format($nonzero/$calls*100,2,".",""); $failure = number_format($zero/$calls*100,2,".",""); $NetworkRateIn = number_format($NetRateIn,2); $NetworkRateOut = number_format($NetRateOut,2); $NetworkRate = max($NetworkRateIn,$NetworkRateOut); if ($this->priceField) { $price = $this->CDRdb->f($this->priceField); } $rr=floor($found/2); $mod=$found-$rr*2; if ($mod ==0) { $inout_color="lightgrey"; } else { $inout_color="white"; } $traceValue=""; $mygroup_print=quoted_printable_decode($mygroup); if ($this->group_byOrig==$this->DestinationIdField) { if ($this->CDRTool['filter']['domain'] && $this->destinations[$this->CDRTool['filter']['domain']]) { list($_dst_id,$_dst_name)=$this->getPSTNDestinationId($mygroup,'',$this->CDRTool['filter']['domain']); $description=$_dst_name; } else { $description=$this->destinations[0]["default"][$mygroup]["name"]; //list($_dst_id,$_dst_name)=$this->getPSTNDestinationId($mygroup); //$description=$_dst_name; } if ($mygroup) { $traceValue=$mygroup; } else { $traceValue="empty"; } } else if ($this->group_byOrig==$this->aNumberField) { # Normalize Called Station Id $N=$this->NormalizeNumber($mygroup); $mygroup_print=$N['username']."@".$N[domain]; $description=""; $traceField="a_number"; $traceValue=urlencode($mygroup); } else if ($this->group_byOrig==$this->CanonicalURIField) { $traceField="c_number"; $traceValue=urlencode($mygroup); } else if ($this->group_byOrig==$this->SipProxyServerField) { $traceField="sip_proxy"; $traceValue=urlencode($mygroup); } else if ($this->group_byOrig==$this->SipCodecField) { $traceField="SipCodec"; } else if (preg_match("/UserAgent/",$this->group_byOrig)) { $traceField="UserAgent"; } else if (preg_match("/^BY/",$this->group_byOrig)) { $traceField="MONTHYEAR"; } else if ($this->group_byOrig==$this->callIdField) { $traceField="call_id"; } else if ($this->group_byOrig=="DAYOFWEEK") { if ($mygroup == "1") { $description="Sunday"; } else if ($mygroup == "2") { $description="Monday"; } else if ($mygroup == "3") { $description="Tuesday"; } else if ($mygroup == "4") { $description="Wednesday"; } else if ($mygroup == "5") { $description="Thursday"; } else if ($mygroup == "6") { $description="Friday"; } else if ($mygroup == "7") { $description="Saturday"; } } else if ($this->group_byOrig=="DAYOFMONTH") { $description =$this->CDRdb->f('day'); } else if ($this->group_byOrig=="DAYOFYEAR") { $description =$this->CDRdb->f('day'); } else if ($this->group_byOrig=="SourceIP") { $traceField="gateway"; } else if ($this->group_byOrig=="SipResponseCode") { $description =$this->disconnectCodesDescription[$mygroup]; $traceField="sip_status"; } else if ($this->group_byOrig=="SipApplicationType") { $traceField="application"; } else if ($this->group_byOrig=="ServiceType") { $traceField="flow"; } else { $description=""; } if (!$traceField) { $traceField = $group_by; } if (!$traceValue) { $traceValue = $mygroup; } if (!$traceValue) { $traceValue=""; $comp_type="empty"; } else { $comp_type="begin"; } $traceValue_enc=urlencode($traceValue); if (!$this->export) { print " $found $calls $seconds_print $minutes_print $hours "; if ($perm->have_perm("showPrice")) { $pricePrint=number_format($price,4,".",""); } else { $pricePrint='x.xxx'; } print " $pricePrint $AcctInputOctets $AcctOutputOctets $success% ($nonzero calls) $failure% ($zero calls) $mygroup_print $description "; printf("Display calls",$url_calls,$traceField,$traceValue_enc,$traceField,$comp_type); print " "; } else { print "$found,"; print "$calls,"; print "$seconds,"; print "$minutes,"; print "$hours,"; if ($perm->have_perm("showPrice")) { $pricePrint=$price; } else { $pricePrint='x.xxx'; } print "$pricePrint,"; print "$AcctInputOctets,"; print "$AcctOutputOctets,"; print "$success,"; print "$nonzero,"; print "$failure,"; print "$zero,"; print "$mygroup_print,"; print "$description"; print "\n"; } $i++; } if (!$this->export) { print " "; } } else { if (!$this->export) { printf ("
For more information about each call click on its Id column.
"); } if ($order_by=="zeroP" || $order_by=="nonzeroP") { $order_by="timestamp"; } $_max_rows = intval($this->maxrowsperpage); if (!$_max_rows) { $_max_rows = 10; } $query=sprintf("select *, UNIX_TIMESTAMP($this->startTimeField) as timestamp from %s where %s order by %s %s limit %d, %d", addslashes($cdr_table), $where, addslashes($order_by), addslashes($order_type), intval($i), $_max_rows ); $this->CDRdb->query($query); if ($this->CDRTool['filter']['aNumber']) { $this->showTableHeaderSubscriber(); } else { if (!$this->export) { $this->showTableHeader(); } else { $this->showExportHeader(); } } while ($i<$maxrows) { global $found; $found=$i+1; $this->CDRdb->next_record(); $Structure=$this->_readCDRFieldsFromDB(); //dprint_r($Structure); $CDR = new $this->CDR_class($this, $Structure); if ($this->CDRTool['filter']['aNumber']) { $CDR->showSubscriber(); } else { if (!$this->export) { $CDR->show(); } else { $CDR->export(); } } $i++; } if (!$this->export) { print " "; } } $this->showPagination($this->next,$maxrows); } } function LoadDomains() { if (!$this->db_subscribers) { $log=printf("Error: Cannot load domains because db_subscribers is not defined in datasource %s",$this->cdr_source); print $log; syslog(LOG_NOTICE,$log); return false; } if (!is_object($this->AccountsDB)) { $log=printf("Error: AccountsDB is not a valid database object"); print $log; syslog(LOG_NOTICE,$log); return false; } if (strlen($this->DATASOURCES[$this->cdr_source]['enableThor'])) { $this->domain_table = "sip_domains"; } else { $this->domain_table = "domain"; } $query=sprintf("select * from %s",$this->domain_table); if ($this->CDRTool['filter']['aNumber']) { $els=explode("@",$this->CDRTool['filter']['aNumber']); $query.= sprintf(" where domain = '%s' ", addslashes($els[1])); } else if ($this->CDRTool['filter']['domain']) { $fdomain=$this->CDRTool['filter']['domain']; $query.=sprintf(" where domain = '%s' ", addslashes($fdomain)); } if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database %s error: %s (%d) %s\n",$this->db_subscribers,$this->AccountsDB->Error,$this->AccountsDB->Errno,$query); print $log; syslog(LOG_NOTICE,$log); return false; } while($this->AccountsDB->next_record()) { if ($this->AccountsDB->f('domain')) { $this->localDomains[$this->AccountsDB->f('domain')]=array('name' => $this->AccountsDB->f('domain'), 'reseller' => intval($this->AccountsDB->f('reseller_id')) ); } } return count($this->localDomains); } function LoadTrustedPeers() { if (!$this->db_subscribers) { $log=printf("Error: Cannot load trusted peers because db_subscribers is not defined in datasource %s",$this->cdr_source); print $log; syslog(LOG_NOTICE,$log); return false; } if (!is_object($this->AccountsDB)) { $log=printf("Error: AccountsDB is not a valid database object"); print $log; syslog(LOG_NOTICE,$log); return false; } if (strlen($this->DATASOURCES[$this->cdr_source]['enableThor'])) { $this->trusted_table = "sip_trusted"; } else { $this->trusted_table = "trusted_peers"; } $query=sprintf("select * from %s",addslashes($this->trusted_table)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database %s error: %s (%d) %s\n",$this->db_subscribers,$this->AccountsDB->Error,$this->AccountsDB->Errno,$query); print $log; syslog(LOG_NOTICE,$log); return false; } while($this->AccountsDB->next_record()) { if ($this->AccountsDB->f('ip')) { $this->trustedPeers[$this->AccountsDB->f('ip')]=array('ip' => $this->AccountsDB->f('ip'), 'reseller' => intval($this->AccountsDB->f('reseller_id')) ); } } return count($this->trustedPeers); } function getQuota($account) { if (!$this->quotaEnabled) return true; if (!$account) return; if (!is_object($this->AccountsDB)) { $log=printf("Error: AccountsDB is not a valid database object"); print $log; syslog(LOG_NOTICE,$log); return false; } list($username,$domain) = explode("@",$account); if ($this->enableThor) { $query=sprintf("select * from sip_accounts where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query 1 %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return 0; } if ($this->AccountsDB->num_rows()) { $this->AccountsDB->next_record(); $_profile=json_decode(trim($this->AccountsDB->f('profile'))); return $_profile->quota; } else { return 0; } } else { $query=sprintf("select quota from subscriber where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return 0; } if ($this->AccountsDB->num_rows()) { $this->AccountsDB->next_record(); return $this->AccountsDB->f('quota'); } else { return 0; } } } function getBlockedByQuotaStatus($account) { if (!$this->quotaEnabled) return true; if (!$account) return 0; if (!is_object($this->AccountsDB)) { $log=printf("Error: AccountsDB is not a valid database object"); print $log; syslog(LOG_NOTICE,$log); return false; } list($username,$domain) = explode("@",$account); if ($this->enableThor) { $query=sprintf("select * from sip_accounts where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query2 %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return 0; } if ($this->AccountsDB->num_rows()) { $this->AccountsDB->next_record(); $_profile=json_decode(trim($this->AccountsDB->f('profile'))); if (in_array('quota',$_profile->groups)) { return 1; } else { return 0; } } else { return 0; } } else { $query=sprintf("select CONCAT(username,'@',domain) as account from grp where grp = 'quota' and username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return 0; } if ($this->AccountsDB->num_rows()) { return 1; } else { return 0; } } return 0; } function notifyLastSessions($count='200',$account='') { // send emails with last missed and received sessions to subscribers in group $this->missed_calls_group $lockName=sprintf("%s:notifySessions",$this->cdr_source); if (!$this->getNormalizeLock($lockName)) { return true; } if (strlen($account)) { list($username,$domain)=explode('@',$account); if (!strlen($username) || !strlen($domain)) return false; } else { $query=sprintf("select * from memcache where `key` = '%s'",'notifySessionsLastRun'); $this->cdrtool->query($query); if ($this->cdrtool->num_rows()) { $this->cdrtool->next_record(); $lastRun=$this->cdrtool->f('value'); if (Date('Y-m-d') == $lastRun) { $log=sprintf("Notify sessions script already run for date %s\n",$lastRun); print $log; syslog(LOG_NOTICE,$log); return true; } } } $this->notifySubscribers=array(); require_once('Mail.php'); require_once('Mail/mime.php'); if ($this->enableThor) { $query=sprintf("select * from sip_accounts"); if (strlen($account)) { $query=sprintf("select * from sip_accounts where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); } if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return 0; } if ($this->AccountsDB->num_rows()) { while ($this->AccountsDB->next_record()) { $_profile=json_decode(trim($this->AccountsDB->f('profile'))); if (in_array($this->missed_calls_group,$_profile->groups)) { $this->notifySubscribers[$this->AccountsDB->f('username').'@'.$this->AccountsDB->f('domain')]=array('email'=>$this->AccountsDB->f('email'),'timezone' => $_profile->timezone); } } } else { return 0; } } else { $query=sprintf("select CONCAT(username,'@',domain) as account,email_address,timezone from grp join subscriber on grp.subscriber_id =subscriber.id where grp = '%s'", addslashes($this->missed_calls_group)); if (strlen($account)) { $query.= sprintf (" and username = '%s' and domain = '%s' ",$username,$domain); } if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return 0; } if ($this->AccountsDB->num_rows()) { while ($this->AccountsDB->next_record()) { $this->notifySubscribers[$this->AccountsDB->f('account')]=array('email'=>$this->AccountsDB->f('email_address'),'timezone' => $this->AccountsDB->f('timezone')); } } else { return 0; } } if (!count($this->notifySubscribers)) return 0; $j=0; foreach (array_keys($this->notifySubscribers) as $_subscriber) { $j++; $_last_sessions=array(); unset($textBody); unset($htmlBody); $query = sprintf("SELECT *, UNIX_TIMESTAMP(%s) as timestamp FROM %s where (%s = '%s' or %s = '%s') and %s > DATE_ADD(NOW(), INTERVAL -1 day) order by %s desc limit 200", addslashes($this->startTimeField), addslashes($this->table), addslashes($this->usernameField), addslashes($_subscriber), addslashes($this->CanonicalURIField), addslashes($_subscriber), addslashes($this->startTimeField), addslashes($this->startTimeField) ); if (!$this->CDRdb->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->CDRdb->Error,$this->CDRdb->Errno); syslog(LOG_NOTICE,$log); print $log; return 0; } if (Date('d')== 1) { while ($this->CDRdb->next_record()) { $_last_sessions[]=array('duration' => $this->CDRdb->f($this->durationField), 'from' => $this->CDRdb->f($this->aNumberField), 'to' => $this->CDRdb->f($this->cNumberField), 'username' => $this->CDRdb->f($this->usernameField), 'canonical' => $this->CDRdb->f($this->CanonicalURIField), 'date' => getlocaltime($this->notifySubscribers[$_subscriber]['timezone'],$this->CDRdb->f('timestamp')) ); } if (preg_match("/^(\w+)(\d{4})(\d{2})$/",$this->table,$m)) { $previousTable=$m[1].date('Ym', mktime(0, 0, 0, $m[3]-1, "01", $m[2])); $query = sprintf("SELECT *, UNIX_TIMESTAMP(%s) as timestamp FROM %s where %s = '%s' and %s > DATE_ADD(NOW(), INTERVAL -1 day) order by %s desc limit 200", addslashes($this->startTimeField), addslashes($previousTable), addslashes($this->CanonicalURIField), addslashes($_subscriber), addslashes($this->startTimeField), addslashes($this->startTimeField) ); if (!$this->CDRdb->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->CDRdb->Error,$this->CDRdb->Errno); syslog(LOG_NOTICE,$log); print $log; return 0; } while ($this->CDRdb->next_record()) { $_last_sessions[]=array('duration' => $this->CDRdb->f($this->durationField), 'from' => $this->CDRdb->f($this->aNumberField), 'to' => $this->CDRdb->f($this->cNumberField), 'username' => $this->CDRdb->f($this->usernameField), 'canonical' => $this->CDRdb->f($this->CanonicalURIField), 'date' => getlocaltime($this->notifySubscribers[$_subscriber]['timezone'],$this->CDRdb->f('timestamp')) ); } } } else { while ($this->CDRdb->next_record()) { $_last_sessions[]=array('duration' => $this->CDRdb->f($this->durationField), 'from' => $this->CDRdb->f($this->aNumberField), 'to' => $this->CDRdb->f($this->cNumberField), 'username' => $this->CDRdb->f($this->usernameField), 'canonical' => $this->CDRdb->f($this->CanonicalURIField), 'date' => getlocaltime($this->notifySubscribers[$_subscriber]['timezone'],$this->CDRdb->f('timestamp')) ); } } if (!count($_last_sessions)) continue; $sessions=array('missed' => array(), 'received' => array(), 'diverted' => array() ); $have_sessions=0; foreach ($_last_sessions as $_s) { if ($_s['duration'] == 0 && $_s['canonical'] == $_subscriber) { $sessions['missed'][]=$_s; $have_sessions++; continue; } if ($_s['duration'] > 0 && $_s['canonical'] == $_subscriber) { $sessions['received'][]=$_s; $have_sessions++; continue; } if ($_s['from'] != $_subscriber && $_s['canonical'] != $_subscriber) { $sessions['diverted'][]=$_s; $have_sessions++; continue; } } if (!$have_sessions) continue;; if (count($sessions['missed'])) { // missed sessions $textBody .= sprintf ("Missed sessions\n\n Id,Date,From,Duration\n "); $htmlBody .= sprintf ("

Missed Calls

"); $i=0; foreach ($sessions['missed'] as $_session) { $i++; if ($i >= $count) break; $htmlBody.=sprintf ("", $i, $_session['date'], $_session['from'], $_session['from'] ); $txtBody.=sprintf ("%s,%s,%s,%s,%s\n", $i, $_session['date'], $_session['from'], $_session['to'] ); } $htmlBody.="
Date and Time Caller
%s%ssip:%s
"; } if (count($sessions['diverted'])) { // diverted sessions $textBody .= sprintf ("Diverted Calls\n\n Id,Date,From,Diverted to\n "); $htmlBody .= sprintf ("

Diverted Calls

"); $i=0; foreach ($sessions['diverted'] as $_session) { $i++; if ($i >= $count) break; $htmlBody.=sprintf ("", $i, $_session['date'], $_session['from'], $_session['from'], $_session['canonical'] ); $txtBody.=sprintf ("%s,%s,%s,%s\n", $i, $_session['date'], $_session['from'], $_session['canonical'] ); } $htmlBody.="
Date and Time Caller Diverted to
%s%ssip:%s%s
"; } if (count($sessions['received'])) { // received sessions $textBody .= sprintf ("Received Calls\n\n Id,Date,From,Duration\n"); $htmlBody .= sprintf ("

Received Calls

"); $i=1; foreach ($sessions['received'] as $_session) { if ($i >= $count) break; $htmlBody.=sprintf ("", $i, $_session['date'], $_session['from'], $_session['from'], $_session['duration'] ); $txtBody.=sprintf ("%s,%s,%s,%s\n", $i, $_session['date'], $_session['from'], $_session['duration'] ); $i++; } $htmlBody.="
Date and Time Caller Duration
%s%ssip:%s%s
"; } $htmlBody.="

This is an automatically generated message, do not reply."; $txtBody.="\nThis is an automatically generated message, do not reply.\n"; $crlf = "\n"; $hdrs = array( 'From'=> $this->CDRTool['provider']['fromEmail'], 'Subject' => sprintf("Incoming Calls for %s on %s",$_subscriber,date('Y-m-d')) ); $mime = new Mail_mime($crlf); $mime->setTXTBody($textBody); $mime->setHTMLBody($htmlBody); $body = $mime->get(); $hdrs = $mime->headers($hdrs); $mail =& Mail::factory('mail'); $mail->send($this->notifySubscribers[$_subscriber]['email'], $hdrs, $body); $log=sprintf("Notify %s at %s with last %d sessions\n", $_subscriber, $this->notifySubscribers[$_subscriber]['email'], count($_last_sessions)); print $log; syslog(LOG_NOTICE,$log); } $query=sprintf("update memcache set `value` = '%s' where `key` = '%s'",Date('Y-m-d'),'notifySessionsLastRun'); if (!$this->cdrtool->query($query)) { $log=sprintf("Database error for query %s: %s (%s)",$query,$this->cdrtool->Error,$this->cdrtool->Errno); print $log; syslog(LOG_NOTICE,$log); return false; } if (!$this->cdrtool->affected_rows()) { $query=sprintf("insert into memcache (`value`,`key`) values ('%s','%s')",Date('Y-m-d'),'notifySessionsLastRun'); if (!$this->cdrtool->query($query)) { if ($this->cdrtool->Errno != 1062) { $log=sprintf("Database error for query %s: %s (%s)",$query,$this->cdrtool->Error,$this->cdrtool->Errno); print $log; syslog(LOG_NOTICE,$log); return false; } } } } function getCallerId($account) { if (!$account) { return NULL; } if ($this->callerid_cache[$account]) { return $this->callerid_cache[$account]; } list($username,$domain) = explode('@',$account); if ($this->enableThor) { $query=sprintf("select * from sip_accounts where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return NULL; } if ($this->AccountsDB->num_rows()) { $this->AccountsDB->next_record(); $_profile=json_decode(trim($this->AccountsDB->f('profile'))); $this->callerid_cache[$account]=$_profile->rpid; return $_profile->rpid; } } else { $query=sprintf("select rpid from subscriber where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return NULL; } if ($this->AccountsDB->num_rows()) { $this->AccountsDB->next_record(); $rpid = $this->AccountsDB->f('rpid'); $this->callerid_cache[$account]=$rpid; return $rpid; } } return NULL; } function rate_on_net_enabled($username, $domain) { if ($this->enableThor) { $query=sprintf("select * from sip_accounts where username = '%s' and domain = '%s'",addslashes($username),addslashes($domain)); if (!$this->AccountsDB->query($query)) { $log=sprintf ("Database error for query %s: %s (%s)",$query,$this->AccountsDB->Error,$this->AccountsDB->Errno); syslog(LOG_NOTICE,$log); return false; } if ($this->AccountsDB->num_rows()) { while ($this->AccountsDB->next_record()) { $_profile=json_decode(trim($this->AccountsDB->f('profile'))); if (in_array($this->rate_on_net_group,$_profile->groups)) { return true; } } } } return false; } } class CDR_opensips extends CDR { function CDR_opensips($parent, $CDRfields) { $this->CDRS = $parent; $this->cdr_source = $this->CDRS->cdr_source; foreach (array_keys($this->CDRS->CDRFields) as $field) { $this->$field = $CDRfields[$this->CDRS->CDRFields[$field]]; } if ($this->CanonicalURI) { $this->CanonicalURI = quoted_printable_decode($this->CanonicalURI); } if ($this->RemoteAddress) { $this->RemoteAddress = quoted_printable_decode($this->RemoteAddress); } if ($this->BillingPartyId) { $this->BillingPartyId = quoted_printable_decode($this->BillingPartyId); } if ($this->aNumber) { $this->aNumber = quoted_printable_decode($this->aNumber); } if ($this->cNumber) { $this->cNumber = quoted_printable_decode($this->cNumber); } if ($this->SipRPID) { $this->SipRPID = quoted_printable_decode($this->SipRPID); } $this->buildMongoCDR(); if (!$this->application && $this->SipMethod) { $_method=strtolower($this->SipMethod); if ($_method == 'message') { $this->application = 'message'; $this->stopTimeNormalized=$this->startTime; } else { $this->application = 'audio'; } } if ($this->application == 'message') { $this->stopTimeNormalized=$this->startTime; } $this->application=strtolower($this->application); $this->application_print=quoted_printable_decode($this->application); $this->FromHeaderPrint = quoted_printable_decode($this->FromHeader); if (strstr($this->FromHeaderPrint,';')) { $_els=explode(";",$this->FromHeaderPrint); $this->FromHeaderPrint=$_els[0]; } $this->FromHeaderPrint = htmlentities($this->FromHeaderPrint); $this->UserAgentPrint = quoted_printable_decode($this->UserAgent); $app_prefix = preg_replace('/[.].*$/', '', $this->application); if (!in_array($app_prefix, $this->supportedApplicationTypes)) { $log=sprintf("Changing application from %s to %s\n", $this->application, $this->defaultApplicationType); syslog(LOG_NOTICE,$log); $this->application = $this->defaultApplicationType; } //$this->applicationNormalized=$this->application; if ($this->aNumber) { $NormalizedNumber = $this->CDRS->NormalizeNumber($this->aNumber,"source"); $this->aNumberPrint = $NormalizedNumber['NumberPrint']; $this->aNumberNormalized = $NormalizedNumber['Normalized']; $this->aNumberUsername = $NormalizedNumber['username']; $this->aNumberDomain = $NormalizedNumber['domain']; } if (!$this->BillingPartyId || $this->BillingPartyId == 'n/a') { $this->BillingPartyId=$this->aNumberPrint; } $this->ResellerId=0; // calculate reseller $_billing_party_els=explode("@",$this->BillingPartyId); if ($this->isBillingPartyLocal()) { $this->ResellerId = $this->CDRS->localDomains[$_billing_party_els[1]]['reseller']; } else { if (!strlen($_billing_party_els[0])) $this->BillingPartyId=$_billing_party_els[1]; if (count($_billing_party_els)==2) { if (!$this->domain) $this->domain=$_billing_party_els[1]; if ($this->CDRS->localDomains[$_billing_party_els[1]]['reseller']) { $this->ResellerId = $this->CDRS->localDomains[$_billing_party_els[1]]['reseller']; } else if ($this->CDRS->trustedPeers[$_billing_party_els[1]]['reseller']) { $this->ResellerId = $this->CDRS->trustedPeers[$_billing_party_els[1]]['reseller']; } } else if (count($_billing_party_els)==1) { $this->ResellerId=$this->CDRS->trustedPeers[$_billing_party_els[0]]['reseller']; } } if (!strlen($this->ResellerId)) { $this->ResellerId = 0; } $this->BillingPartyId=strtolower($this->BillingPartyId); $this->BillingPartyIdPrint=$this->BillingPartyId; $this->domainNormalized = $this->domain; if (is_array($this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation_SourceIP']) && isset($this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation_SourceIP'][$this->SourceIP]) && strlen($this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation_SourceIP'][$this->SourceIP])) { $this->domainNormalized=$this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation_SourceIP'][$this->SourceIP]; } else if (is_array($this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation']) && isset($this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation'][$this->domain]) && strlen($this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation'][$this->domain])) { $this->domainNormalized=$this->CDRS->DATASOURCES[$this->cdr_source]['domainTranslation'][$this->domain]; } $this->domainNormalized=strtolower($this->domainNormalized); $this->RemoteAddressPrint=quoted_printable_decode($this->RemoteAddress); $_timestamp_stop=$this->timestamp+$this->duration; $this->dayofweek = date("w",$this->timestamp); $this->hourofday = date("G",$this->timestamp); $this->dayofyear = date("Y-m-d",$this->timestamp); // Called Station ID or cNumber should not be used for rating purposes because // it is chosen by the subscriber but the Proxy rewrites it into a different // final destination (the Canonical URI) // Canonical URI is the final logical SIP destination after all // lookups like aliases, usrloc , call forwarding, ENUM // mappings or PSTN gateways but before the DNS lookup // Canonical URI must be saved in the SIP Proxy and added as an extra // Radius attribute in the Radius START packet if (!$this->CanonicalURI) { if ($this->RemoteAddress) { $this->CanonicalURI=$this->RemoteAddress; } else if ($this->cNumber) { $this->CanonicalURI=$this->cNumber; } } if ($this->CanonicalURI) { $this->CanonicalURIPrint = $this->CanonicalURI; $NormalizedNumber = $this->CDRS->NormalizeNumber($this->CanonicalURI,"destination",$this->BillingPartyId,$this->domain,$this->gateway,'',$this->ENUMtld,$this->ResellerId); $this->CanonicalURINormalized = $NormalizedNumber['Normalized']; $this->CanonicalURIUsername = $NormalizedNumber['username']; $this->CanonicalURIDomain = $NormalizedNumber['domain']; $this->CanonicalURIPrint = $NormalizedNumber['NumberPrint']; $this->CanonicalURIDelimiter = $NormalizedNumber['delimiter']; $this->CanonicalURIE164 = $NormalizedNumber['E164']; // Destination Id is used for rating purposes $this->DestinationId = $NormalizedNumber['DestinationId']; $this->destinationName = $NormalizedNumber['destinationName']; $this->region = $NormalizedNumber['region']; } if ($this->cNumber) { $NormalizedNumber = $this->CDRS->NormalizeNumber($this->cNumber,"destination",$this->BillingPartyId,$this->domain,$this->gateway,'',$this->ENUMtld,$this->ResellerId); $this->cNumberNormalized = $NormalizedNumber['Normalized']; $this->cNumberUsername = $NormalizedNumber['username']; $this->cNumberDomain = $NormalizedNumber['domain']; $this->cNumberPrint = $NormalizedNumber['username'].$NormalizedNumber['delimiter'].$NormalizedNumber['domain']; $this->cNumberDelimiter = $NormalizedNumber['delimiter']; $this->cNumberE164 = $NormalizedNumber['E164']; } if ($this->RemoteAddress) { // Next hop is the real destination after all lookups including DNS $NormalizedNumber = $this->CDRS->NormalizeNumber($this->RemoteAddress,"destination",$this->BillingPartyId,$this->domain,$this->gateway,'',$this->ENUMtld,$this->ResellerId); $this->RemoteAddressPrint = $NormalizedNumber['NumberPrint']; $this->RemoteAddressNormalized = $NormalizedNumber['Normalized']; $this->RemoteAddressDestinationId = $NormalizedNumber['DestinationId']; $this->RemoteAddressDestinationName = $NormalizedNumber['destinationName']; $this->RemoteAddressUsername = $NormalizedNumber['username']; $this->RemoteAddressDelimiter = $NormalizedNumber['delimiter']; $this->RemoteAddressE164 = $NormalizedNumber['E164']; $this->remoteGateway = $NormalizedNumber['domain']; $this->remoteUsername = $NormalizedNumber['username']; } $this->isCalleeLocal(); $this->isCallerLocal(); if ($this->CallerIsLocal) { if ($this->aNumberPrint == $this->BillingPartyId) { // call is not diverted if ($this->CalleeIsLocal) { $this->flow = 'on-net'; } else { $this->flow = 'outgoing'; } } else { // call is diverted if ($this->CalleeIsLocal) { $this->flow = 'on-net-diverted-on-net'; } else { $this->flow = 'on-net-diverted-off-net'; } } } else { if ($this->isBillingPartyLocal()) { // call is diverted by local user if ($this->CalleeIsLocal) { $this->flow = 'diverted-on-net'; } else { $this->flow = 'diverted-off-net'; } } else if ($this->CalleeIsLocal) { $this->flow = 'incoming'; } else { // transit from trusted peer $this->flow = 'transit'; } } if (($this->flow == 'on-net' || $this->flow == 'diverted-on-net' || $this->flow == 'on-net-diverted-on-net') && $this->application == 'audio' && $this->CDRS->rating_settings['rate_on_net_calls'] && $this->CDRS->rate_on_net_enabled($_billing_party_els[0], $_billing_party_els[1]) && !$this->DestinationId && $this->CalleeCallerId) { $_dest = preg_replace("/^\+(\d+)$/","00$1", $this->CalleeCallerId); $NormalizedNumber = $this->CDRS->NormalizeNumber($_dest,"destination",$this->BillingPartyId,$this->domain,$this->gateway,'',$this->ENUMtld,$this->ResellerId); $this->DestinationId = $NormalizedNumber['DestinationId']; $this->destinationName = $NormalizedNumber['destinationName']; } if ($this->CDRS->rating_settings['rate_on_net_calls'] && $this->CDRS->rating_settings['rate_on_net_diverted_calls'] && ($this->flow == 'on-net-diverted-off-net' || $this->flow == 'on-net-diverted-on-net' || $this->flow == 'diverted-on-net' || $this->flow == 'diverted-off-net') && !$this->normalized && $this->duration != '0' && $this->disconnect == $this->disconnectOrig) { $query = sprintf(" update %s set AcctStopTime ='%s', Normalized='0', AcctSessionTime='%s', SipResponseCode='200' where AcctSessionId='%s' and SipFromTag='%s' and SipToTag!='%s' and ( ServiceType='on-net' or ServiceType='on-net-diverted-on-net' or ServiceType='diverted-on-net' or ServiceType='incoming') and AcctSessionTime=''", $this->CDRS->table, $this->stopTime, $this->duration, $this->callId, $this->SipFromTag, $this->SipToTag); $this->tdb = new DB_radius; dprint($query); $this->tdb->query($query); } if ($this->application == "presence") { $this->destinationPrint = $this->cNumberUsername.$this->cNumberDelimiter.$this->cNumberDomain; $this->DestinationForRating = $this->cNumberNormalized; } else { if (!$this->DestinationId) { if ($this->CanonicalURIDomain) { $this->destinationPrint = $this->CanonicalURIUsername.$this->CanonicalURIDelimiter.$this->CanonicalURIDomain; } else { $this->destinationPrint = $this->cNumberUsername.$this->cNumberDelimiter.$this->cNumberDomain; } if (strstr($this->CanonicalURINormalized,'@')) { $this->DestinationForRating = $this->CanonicalURINormalized; } else { $this->DestinationForRating = $this->RemoteAddressNormalized; } } else { $this->DestinationForRating = $this->CanonicalURINormalized; $this->destinationPrint = $this->CanonicalURIPrint; } } if ($this->inputTraffic) { $this->inputTrafficPrint = number_format($this->inputTraffic/1024,2); } else { $this->inputTrafficPrint=0; } if ($this->outputTraffic) { $this->outputTrafficPrint = number_format($this->outputTraffic/1024,2); } else { $this->outputTrafficPrint=0; } if (!$CDRfields['skip_fix_prepaid_duration']) { if (!$this->normalized && $this->callId) { // fix the duration of prepaid sessions if the prepaid duration is different than radius calculated duration $query=sprintf("select duration from prepaid_history where session = '%s' and destination = '%s' order by id desc limit 1", addslashes($this->callId), addslashes($this->destinationPrint) // must be synced with maxsession time ); if ($this->CDRS->cdrtool->query($query)) { if ($this->CDRS->cdrtool->num_rows()) { $this->CDRS->cdrtool->next_record(); $this->durationNormalized = $this->CDRS->cdrtool->f('duration'); $this->durationPrint = sec2hms($this->durationNormalized); } else { $this->durationPrint = sec2hms($this->duration); } } else { $log=sprintf("Database error for query %s: %s (%s)",$query,$this->CDRS->cdrtool->Error,$this->CDRS->cdrtool->Errno); syslog(LOG_NOTICE,$log); } } else { $this->durationPrint = sec2hms($this->duration); } } else { $this->durationPrint = sec2hms($this->duration); } if ($this->disconnect) { $this->disconnectPrint = $this->NormalizeDisconnect($this->disconnect); } if ($this->disconnectOrig != $this->disconnect && $this->disconnect && $this->CDRS->rating_settings['rate_on_net_diverted_calls']) { $this->disconnectOrigPrint =$this->CDRS->disconnectCodesDescription[$this->disconnectOrig]." (".$this->disconnectOrig.")"; } $this->traceIn(); $this->traceOut(); $this->obfuscateCallerId(); if ($this->CDRS->rating) { global $perm; if (is_object($perm) && $perm->have_perm("showPrice")) { $this->pricePrint=$this->price; } else { $this->pricePrint='x.xxx'; } } } function buildMongoCDR() { # TODO = remove me $this->mongo_cdr = array(); $int_values = array('duration', 'inputTraffic', 'outputTraffic', 'timestamp', 'disconnect'); foreach (array_keys($this->CDRS->CDRFields) as $field) { if (in_array($field, $int_values)) { $this->mongo_cdr[$field] = intval($this->$field); } else { $this->mongo_cdr[$field] = $this->$field; } } if ($this->CanonicalURI) { $this->mongo_cdr['CanonicalURI'] = $this->CanonicalURI; } if ($this->RemoteAddress) { $this->mongo_cdr['RemoteAddress'] = $this->RemoteAddress; } if ($this->BillingPartyId) { $this->mongo_cdr['BillingPartyId'] = $this->BillingPartyId; } if ($this->aNumber) { $this->mongo_cdr['aNumber'] = $this->aNumber; } if ($this->cNumber) { $this->mongo_cdr['cNumber'] = $this->cNumber; } if ($this->SipRPID) { $this->mongo_cdr['SipRPID'] = $this->SipRPID; } } function buildCDRdetail() { global $perm; global $found; if (!is_object($perm)) return; $this->geo_location=$this->lookupGeoLocation($this->SourceIP); $this->cdr_details="

SIP Signalling
"; $this->cdr_details.= sprintf(" Click here to show only this call id ", $this->CDRS->url_run, urlencode($this->callId) ); if ($this->CDRS->sipTrace) { $trace_datasource = $this->CDRS->sipTrace; $callid_enc = urlencode(quoted_printable_decode($this->callId)); $fromtag_enc = urlencode(quoted_printable_decode($this->SipFromTag)); $totag_enc = urlencode(quoted_printable_decode($this->SipToTag)); - $this->traceLink="SipProxyServer', 'Trace', + $this->traceLink="SipProxyServer', '_blank', 'toolbar=0,status=0,menubar=0,scrollbars=1,resizable=1,width=1300px,height=600')\">Click here for the SIP trace  "; $this->cdr_details.= "
Call id:
$this->callId
"; } $this->cdr_details.= sprintf("
%s
", $this->traceLink); $this->cdr_details.= "
From tag:
$this->SipFromTag
To tag:
$this->SipToTag
Start Time:
$this->startTime $providerTimezone
Stop Time:
$this->stopTime
"; $this->cdr_details.= sprintf("
Country:
%s
",$this->geo_location); $this->cdr_details.= "
Method:
$this->SipMethod from $this->SourceIP:$this->SourcePort
From:
$this->aNumberPrint
From Header:
$this->FromHeaderPrint
User Agent:
$this->UserAgentPrint
Domain:
$this->domain
To (dialed URI):
$this->cNumberPrint
"; if ($this->CanonicalURI) { $this->cdr_details.= sprintf("
Canonical URI:
%s
",htmlentities($this->CanonicalURI)); } $this->cdr_details.= sprintf("
Next Hop URI:
%s
",htmlentities($this->RemoteAddress)); if ($this->DestinationId) { $this->cdr_details.= "
Destination:
$this->destinationName ($this->DestinationId)
"; } if ($this->ENUMtld && $this->ENUMtld != 'none' && $this->ENUMtld != 'N/A') { $this->cdr_details.= "
ENUM TLD:
$this->ENUMtld
"; } if ($this->SipRPID) { $this->cdr_details .= "
Caller ID:
$this->SipRPIDPrint
"; } if ($this->CalleeCallerId) { $this->cdr_details .= "
Called ID:
$this->CalleeCallerId
"; } $this->cdr_details.= "
Billing Party:
$this->BillingPartyIdPrint
Reseller:
$this->ResellerId
"; $this->cdr_details.= "
"; if ($this->application != 'message') { $this->cdr_details.= "
Media Streams
"; if ($this->CDRS->mediaTrace) { $media_trace_datasource = $this->CDRS->mediaTrace; - $this->mediaTraceLink="SipProxyServer', 'Trace', + $this->mediaTraceLink="SipProxyServer', '_blank', 'toolbar=0,status=0,menubar=0,scrollbars=1,resizable=1,width=800,height=730')\">Click here for media information  "; $this->cdr_details.= sprintf("
%s
", $this->mediaTraceLink); } $this->SipCodec = quoted_printable_decode($this->SipCodec); if ($this->SipCodec) { $this->cdr_details.= "
Codecs:
$this->SipCodec
"; } $this->cdr_details.= "
Caller RTP:
$this->inputTrafficPrint KB
Called RTP:
$this->outputTrafficPrint KB
"; if ($this->MediaInfo) { $this->cdr_details.= "
Media Info:
$this->MediaInfo
"; } $this->cdr_details.= "
Applications:
$this->application_print
"; } if ($this->SipUserAgents) { $this->SipUserAgents = quoted_printable_decode($this->SipUserAgents); $callerAgents=explode("+",$this->SipUserAgents); $callerUA=htmlentities($callerAgents[0]); $calledUA=htmlentities($callerAgents[1]); $this->cdr_details.= "
Caller SIP UA:
$callerUA
Called SIP UA:
$calledUA
"; } $this->cdr_details.= "
"; if ($perm->have_perm("showPrice") && $this->normalized) { $this->cdr_details.= "
Rating
"; if ($this->price > 0 || $this->rate) { $this->ratePrint=nl2br($this->rate); $this->cdr_details.= "
$this->ratePrint
"; } else { $this->cdr_details.= "
Free call
"; } $this->cdr_details.= "
"; } $this->cdr_details.= "
"; } function traceIn () { $datasource=$this->CDRS->traceInURL[$this->SourceIP]; global $DATASOURCES; if (!$datasource || !$DATASOURCES[$datasource]) { return; } $tplus = $this->timestamp+$this->duration+300; $tmin = $this->timestamp-300; $c_number = $this->remoteUsername; $cdr_table = Date('Ym',time($this->timestamp)); $this->traceIn= "". "In". ""; } function traceOut () { $datasource=$this->CDRS->traceOutURL[$this->remoteGateway]; global $DATASOURCES; if (!$datasource || !$DATASOURCES[$datasource]) { return; } $tplus = $this->timestamp+$this->duration+300; $tmin = $this->timestamp-300; $c_number = preg_replace("/^(0+)/","",$this->remoteUsername); $cdr_table = Date('Ym',time($this->timestamp)); $this->traceOut= "". "Out". ""; } function show() { $this->buildCDRdetail(); global $found; global $perm; $rr=floor($found/2); $mod=$found-$rr*2; if ($mod ==0) { $inout_color="#F9F9F9"; } else { $inout_color="white"; } $this->ratePrint=nl2br($this->rate); if ($this->CDRS->Accounts[$this->BillingPartyId]['timezone']) { $timezone_print=$this->CDRS->Accounts[$this->BillingPartyId]['timezone']; } else { $timezone_print=$this->CDRS->CDRTool['provider']['timezone']; } $found_print=$found; if ($this->normalized) $found_print.='N'; $providerTimezone=$this->CDRS->CDRTool['provider']['timezone']; print " $found_print $this->startTime $this->flow $this->aNumberPrint $this->geo_location $this->SipProxyServer $this->application $this->destinationPrint "; if ($this->DestinationId) { if ($this->DestinationId != $this->CanonicalURI) { print " ($this->destinationName $this->DestinationId)"; } else { print " ($this->destinationName)"; } } print ""; if (!$this->normalized){ if ($this->duration > 0 ) { print "$this->duration(s)"; } else { print "in progress"; } } else { print " $this->durationPrint $this->pricePrint $this->inputTrafficPrint $this->outputTrafficPrint "; } $SIPclass=substr($this->disconnect,0,1); if ($SIPclass=="6") { $status_color=""; } else if ($SIPclass=="5" ) { $status_color=""; } else if ($SIPclass=="4" ) { $status_color=""; } else if ($SIPclass=="3" ) { $status_color=""; } else if ($SIPclass=="2" ) { $status_color=""; } else { $status_color=""; } if ($this->disconnectOrig != $this->disconnect && $this->CDRS->rating_settings['rate_on_net_diverted_calls']) { $disclass=substr($this->disconnectOrig,0,1); if ($disclass == "6" || $disclass=="5") { $status1_color=""; } else if ($disclass=="4" ) { $status1_color=""; } else if ($disclass=="3" ) { $status1_color=""; } else if ($disclass=="2" ) { $status1_color=""; } else { $status1_color=""; } } print " $this->SipCodec $status_color $this->disconnectPrint"; if ($this->disconnectOrig != $this->disconnect && $this->CDRS->rating_settings['rate_on_net_diverted_calls']) { print "$status1_color $this->disconnectOrigPrint"; } print " $this->cdr_details "; } function export() { global $found; $disconnectName = $this->CDRS->disconnectCodesDescription[$this->disconnect]; $UserAgents = explode("+",$this->SipUserAgents); $CallingUserAgent = trim($UserAgents[0]); $CalledUserAgent = trim($UserAgents[1]); print "$found"; print ",$this->startTime"; print ",$this->stopTime"; print ",$this->BillingPartyIdPrint"; print ",$this->domain"; print ",$this->SipRPIDPrint"; print ",$this->aNumberPrint"; print ",$this->destinationPrint"; print ",$this->DestinationId"; print ",$this->destinationName"; print ",$this->RemoteAddressPrint"; print ",$this->CanonicalURIPrint"; print ",$this->duration"; print ",$this->price"; print ",$this->SipProxyServer"; print ",$this->inputTraffic"; print ",$this->outputTraffic"; printf(",%s",preg_replace("/,/","/",quoted_printable_decode($CallingUserAgent))); printf(",%s",preg_replace("/,/","/",quoted_printable_decode($CalledUserAgent))); print ",$this->disconnect"; print ",$disconnectName"; printf(",%s",preg_replace("/,/","/",quoted_printable_decode($this->SipCodec))); print ",$this->application"; print "\n"; } function showSubscriber() { $this->buildCDRdetail(); global $found; $rr=floor($found/2); $mod=$found-$rr*2; if ($mod ==0) { $inout_color="lightgrey"; } else { $inout_color="white"; } if (!$this->CDRS->export) { $timezone_print=$this->CDRS->CDRTool['provider']['timezone']; $found_print=$found; if ($this->normalized) $found_print.='N'; print " $found_print $this->startTime $timezone_print $this->aNumberPrint $this->geo_location $this->SipProxyServer $this->destinationPrint $this->destinationName $this->durationPrint "; if ($this->CDRS->rating) { print "$this->pricePrint"; } print " $this->inputTrafficPrint $this->outputTrafficPrint "; print " $this->cdr_details "; } else { $disconnectName=$this->CDRS->disconnectCodesDescription[$this->disconnect]; $UserAgents=explode("+",$this->SipUserAgents); $CallingUserAgent=trim($UserAgents[0]); $CalledUserAgent=trim($UserAgents[1]); print "$found,$this->startTime,$this->stopTime,$this->BillingPartyId,$this->domain,$this->aNumberPrint,$this->cNumberPrint,$this->DestinationId,$this->destinationName,$this->RemoteAddressPrint,$this->duration,$this->price,$this->SipProxyServer,$this->inputTraffic,$this->outputTraffic,$CallingUserAgent,$CalledUserAgent,$this->disconnect,$disconnectName,$this->SipCodec,$this->application\n"; } } function isBillingPartyLocal() { $els=explode("@",$this->BillingPartyId); if ($els[1] && isset($this->CDRS->localDomains[$els[1]])) { return true; } return false; } function isCallerLocal() { if (isset($this->CDRS->localDomains[$this->aNumberDomain])) { $this->CallerIsLocal=true; $this->SipRPID = $this->CDRS->getCallerId($this->BillingPartyId); $this->SipRPIDPrint = $this->SipRPID; #$this->SipRPIDPrint = quoted_printable_decode($this->SipRPID); } } function isCalleeLocal() { if (isset($this->CDRS->localDomains[$this->CanonicalURIDomain]) && !preg_match("/^0/",$this->CanonicalURIUsername)) { $this->CalleeIsLocal=true; $this->CalleeCallerId=$this->CDRS->getCallerId($this->CanonicalURI); } } function obfuscateCallerId() { global $obfuscateCallerId; if ($obfuscateCallerId) { //Caller party $caller_els=explode("@",$this->aNumberPrint); if (is_numeric($caller_els[0]) && strlen($caller_els[0]>3)) { $_user=substr($caller_els[0],0,strlen($caller_els[0])-3).'xxx'; } else { $_user='caller'; } if (count($caller_els)== 2) { $this->aNumberPrint=$_user.'@'.$caller_els[1]; } else { $this->aNumberPrint=$_user; } //Billing party $caller_els=explode("@",$this->BillingPartyIdPrint); if (is_numeric($caller_els[0]) && strlen($caller_els[0]>3)) { $_user=substr($caller_els[0],0,strlen($caller_els[0])-3).'xxx'; } else { $_user='party'; } $this->BillingPartyIdPrint=$_user.'@'.$caller_els[1]; // Destination $caller_els=explode("@",$this->destinationPrint); if (is_numeric($caller_els[0]) && strlen($caller_els[0]>3)) { $_user=substr($caller_els[0],0,strlen($caller_els[0])-3).'xxx'; } else { $_user='destination'; } if (count($caller_els)== 2) { $this->destinationPrint=$_user.'@'.$caller_els[1]; } else { $this->destinationPrint=$_user; } $caller_els=explode("@",$this->cNumberPrint); if (is_numeric($caller_els[0]) && strlen($caller_els[0]>3)) { $_user=substr($caller_els[0],0,strlen($caller_els[0])-3).'xxx'; } else { $_user='dialedNumber'; } if (count($caller_els)== 2) { $this->cNumberPrint=$_user.'@'.$caller_els[1]; } else { $this->cNumberPrint=$_user; } $caller_els=explode("@",$this->RemoteAddressPrint); if (is_numeric($caller_els[0]) && strlen($caller_els[0]>3)) { $_user=substr($caller_els[0],0,strlen($caller_els[0])-3).'xxx'; } else { $_user='remoteAddress'; } if (count($caller_els)== 2) { $this->RemoteAddressPrint=$_user.'@'.$caller_els[1]; } else { $this->RemoteAddressPrint=$_user; } // Canonical URI $caller_els=explode("@",$this->CanonicalURIPrint); if (is_numeric($caller_els[0]) && strlen($caller_els[0]>3)) { $_user=substr($caller_els[0],0,strlen($caller_els[0])-3).'xxx'; } else { $_user='canonicalURI'; } if (count($caller_els)== 2) { $this->CanonicalURIPrint=$_user.'@'.$caller_els[1]; } else { $this->CanonicalURIPrint=$_user; } if (is_numeric($this->SipRPIDPrint) && strlen($this->SipRPIDPrint) > 3) { $this->SipRPIDPrint=substr($this->SipRPID,0,strlen($this->SipRPID)-3).'xxx'; } else { $_user='callerId'; } // IP address $this->SourceIP='xxx.xxx.xxx.xxx'; } } } class CDRS_opensips_mongo extends CDRS_opensips { var $CDR_class = "CDR_opensips_mongo"; var $mongo_db_ro = NULL; var $mongo_db_rw = NULL; function getCDRtables() { if (!is_object($this->mongo_db_rw) && !$this->initDatabaseConnection) { return array(); } $_tables=array(); try { $_tables=$this->mongo_db_rw->listCollections(); } catch (Exception $e) { printf("

Caught Mongo exception in getCDRtables(): %s", $e->getMessage()); } $t=count($_tables); if ($this->table) $this->tables[]=$this->table; foreach ($_tables as $_table) { $_table=strval($_table); if (preg_match("/^.*\.(radacct\d{6})$/",$_table,$m)) { if ($list_t > 24) break; if (!in_array($m[1], $this->tables)) { $this->tables[]=$m[1]; } $list_t++; } $t--; } $this->tables=array_unique($this->tables); } function initDatabaseConnection() { if ($this->DATASOURCES[$this->cdr_source]['mongo_db']) { $mongo_db = $this->CDRTool['mongo_db'][$this->DATASOURCES[$this->cdr_source]['mongo_db']]; $mongo_uri = $mongo_db['uri']; $mongo_replicaSet = $mongo_db['replicaSet']; $mongo_database = $mongo_db['database']; try { $mongo_connection_ro = new Mongo("mongodb://$mongo_uri?readPreference=secondaryPreferred", array("replicaSet" => $mongo_replicaSet)); $this->mongo_db_ro = $mongo_connection_ro->selectDB($mongo_database); $mongo_connection_rw = new Mongo("mongodb://$mongo_uri?readPreference=primaryPreferred", array("replicaSet" => $mongo_replicaSet)); $this->mongo_db_rw = $mongo_connection_rw->selectDB($mongo_database); return true; } catch (Exception $e) { printf("

Caught exception in initDatabaseConnection(): %s", $e->getMessage()); return false; } } return true; } function getMongoTable($table, $rw=false) { try { if ($rw) { if (!$this->mongo_db_rw && !$this->initDatabaseConnection()) { return NULL; } $table = $this->mongo_db_rw->selectCollection($table); } else { if (!$this->mongo_db_ro && !$this->initDatabaseConnection()) { return NULL; } $table = $this->mongo_db_ro->selectCollection($table); } return $table; } catch (Exception $e) { printf("

Caught exception in getMongoTable(): %s", $e->getMessage()); } return NULL; } function initCDRFields() { // init names of CDR fields foreach (array_keys($this->CDRFields) as $field) { $mongo_field=$field; $_field=$field."Field"; $this->$_field=$mongo_field; } } function _readCDRFieldsFromDB($mongo_result) { foreach (array_keys($this->CDRFields) as $field) { $CDRStructure[$this->CDRFields[$field]] = $mongo_result[$field]; } return $CDRStructure; } function getUnNormalized($where="",$table) { # TODO return 0; } function show() { global $perm; foreach ($this->FormElements as $_el) { ${$_el} = trim($_REQUEST[$_el]); } if ($begin_time) { list($begin_hour,$begin_min)=explode(":",$begin_time); } if ($end_time) { list($end_hour,$end_min)=explode(":",$end_time); } if ($begin_date) { list($begin_year,$begin_month,$begin_day)=explode("-",$begin_date); } if ($end_date) { list($end_year,$end_month,$end_day)=explode("-",$end_date); } // overwrite some elements based on user rights if ($this->CDRTool['filter']['gateway']) { $gateway =$this->CDRTool['filter']['gateway']; } if (!$this->export) { if (!$begin_datetime) { $begin_datetime="$begin_year-$begin_month-$begin_day $begin_hour:$begin_min"; $begin_datetime_timestamp=mktime($begin_hour, $begin_min, 0, $begin_month,$begin_day,$begin_year); } else { $begin_datetime_timestamp=$begin_datetime; $begin_datetime=Date("Y-m-d H:i",$begin_datetime); } if (!$end_datetime) { $end_datetime_timestamp=mktime($end_hour, $end_min, 0, $end_month,$end_day,$end_year); $end_datetime="$end_year-$end_month-$end_day $end_hour:$end_min"; } else { $end_datetime_timestamp=$end_datetime; $end_datetime=Date("Y-m-d H:i",$end_datetime); } } else { $begin_datetime=Date("Y-m-d H:i",$begin_datetime); $end_datetime=Date("Y-m-d H:i",$end_datetime); } if (!$order_by || (!$group_by && $order_by == "group_by")) { $order_by=$this->idField; } $mongo_where = array(); if (!$cdr_table) $cdr_table=$this->table; $mongo_table_ro = $this->getMongoTable($cdr_table); $mongo_table_rw = $this->getMongoTable($cdr_table, true); $this->url=sprintf("?cdr_source=%s&cdr_table=%s",$this->cdr_source,$cdr_table); if ($this->CDRTool['filter']['domain']) { $this->url .= sprintf("&Realms=%s",urlencode($this->CDRTool['filter']['domain'])); $Realms = explode(" ",$this->CDRTool['filter']['domain']); } else if ($Realms) { $this->url .= sprintf("&Realms=%s",urlencode($Realms)); $Realms = explode(" ",$Realms); } if ($this->CDRTool['filter']['aNumber']) { $this->url .= sprintf("&UserName=%s",urlencode($this->CDRTool['filter']['aNumber'])); } if ($this->CDRTool['filter']['after_date']) { $mongo_where[$this->startTimeField] = array('$gte' => $this->CDRTool['filter']['after_date']); } if ($order_by) { $this->url.=sprintf("&order_by=%s&order_type=%s",addslashes($order_by),addslashes($order_type)); } $this->url.=sprintf("&begin_datetime=%s",urlencode($begin_datetime_timestamp)); $this->url.=sprintf("&end_datetime=%s",urlencode($end_datetime_timestamp)); if (!$call_id && $begin_datetime && $end_datetime) { $mongo_where[$this->startTimeField] = array('$gte' => $begin_datetime, '$lt' => $end_datetime); } else { $mongo_where[$this->startTimeField] = array('$gte' => '1970-01-01'); } if ($MONTHYEAR) { $mongo_where[$this->startTimeField] = new MongoRegex("/^$MONTHYEAR/"); $this->url.= sprintf("&MONTHYEAR=%s",urlencode($MONTHYEAR)); } if ($flow) { $this->url.=sprintf("&flow=%s",urlencode($flow)); $mongo_where[$this->flowField] = $flow; } if ($this->CDRTool['filter']['aNumber']) { // force user to see only CDRS with his a_numbers $mongo_where['$or'] = array(array($this->usernameField => $this->CDRTool['filter']['aNumber']), array($this->CanonicalURIField => $this->CDRTool['filter']['aNumber'])); $UserName_comp='equal'; $UserName=$this->CDRTool['filter']['aNumber']; } if ($UserName_comp == "empty") { $mongo_where[$this->usernameField] = ''; $this->url.=sprintf("&UserName_comp=%s",urlencode($UserName_comp)); } else if (strlen($UserName) && !$this->CDRTool['filter']['aNumber']) { if (!$UserName_comp) $UserName_comp='begin'; if ($UserName_comp=="begin") { $mongo_where[$this->usernameField] = new MongoRegex("/^$UserName/"); } elseif ($UserName_comp=="contain") { $mongo_where[$this->usernameField] = new MongoRegex("/$UserName/"); } elseif ($UserName_comp=="equal") { $mongo_where[$this->usernameField] = $UserName; } else { $mongo_where[$this->usernameField] = ''; } $this->url.=sprintf("&UserName=%s&UserName_comp=%s",urlencode($UserName),$UserName_comp); } $a_number=trim($a_number); if ($a_number_comp == "empty") { $mongo_where[$this->aNumberField] = ''; $this->url.=sprintf("&a_number_comp=%s",urlencode($a_number_comp)); } else if (strlen($a_number)) { $a_number=urldecode($a_number); if (!$a_number_comp) $a_number_comp="equal"; $this->url.=sprintf("&a_number=%s",urlencode($a_number)); if ($a_number_comp=="begin") { $mongo_where[$this->aNumberField] = new MongoRegex("/^$a_number/"); } elseif ($a_number_comp=="contain") { $mongo_where[$this->aNumberField] = new MongoRegex("/$a_number/"); } elseif ($a_number_comp=="equal") { $mongo_where[$this->aNumberField] = $a_number; } $this->url.=sprintf("&a_number_comp=%s",urlencode($a_number_comp)); } $c_number=trim($c_number); if ($c_number_comp == "empty") { $mongo_where[$this->CanonicalURIField] = ''; $this->url.=sprintf("&c_number_comp=%s",urlencode($c_number_comp)); } else if (strlen($c_number)) { $c_number=urldecode($c_number); if (!$c_number_comp) $c_number_comp="begin"; if (!$c_number_comp || $c_number_comp=="begin") { $mongo_where[$this->CanonicalURIField] = new MongoRegex("/^$c_number/"); } elseif ($c_number_comp=="contain") { $mongo_where[$this->CanonicalURIField] = new MongoRegex("/$c_number/"); } elseif ($c_number_comp=="equal") { $mongo_where[$this->CanonicalURIField] = $c_number; } $this->url.=sprintf("&c_number=%s&c_number_comp=%s",urlencode($c_number),urlencode($c_number_comp)); } $Realm=trim($Realm); if ($Realms) { $d_array=array(); foreach ($Realms as $realm) { $d_array[] = array($this->domainField => $realm); } $mongo_where['$or'] = $d_array; } else if ($Realm) { $Realm=urldecode($Realm); $mongo_where[$this->domainField] = $Realm; $this->url.=sprintf("&Realm=%s",urlencode($Realm)); } $BillingId=trim($BillingId); if (preg_match("/^\d+$/",$BillingId) && $this->BillingIdField) { $mongo_where[$this->BillingIdField] = $BillingId; $this->url.=sprintf("&BillingId=%s",urlencode($BillingId)); } if ($application) { $mongo_where[$this->applicationField] = new MongoRegex("/$application/"); $this->url.=sprintf("&application=%s",urlencode($application)); } if ($DestinationId) { if ($DestinationId=="empty") { $DestinationIdSQL=""; } else { $DestinationIdSQL=$DestinationId; } $mongo_where[$this->DestinationIdField] = $DestinationIdSQL; $this->url.=sprintf("&DestinationId=%s",urlencode($DestinationId)); } if (strlen(trim($ExcludeDestinations))) { # TODO: migrateb clause to mongo $ExcludeDestArray=explode(" ",trim($ExcludeDestinations)); foreach ($ExcludeDestArray as $exclDst) { if (preg_match("/^0+(\d+)$/",$exclDst,$m)) { $exclDest_id=$m[1]; } else { $exclDest_id=$exclDst; } $where .= " and ". $this->CanonicalURIField. " not like '". addslashes(trim($exclDst)). "'"; } $this->url.=sprintf("&ExcludeDestinations=%s",urlencode($ExcludeDestinations)); } $call_id=trim($call_id); if ($call_id) { $call_id=urldecode($call_id); $mongo_where[$this->callIdField] = $call_id; $this->url.=sprintf("&call_id=%s",urlencode($call_id)); } if ($sip_proxy) { $sip_proxy=urldecode($sip_proxy); $mongo_where[$this->SipProxyServerField] = $sip_proxy; $this->url.=sprintf("&sip_proxy=%s",urlencode($sip_proxy)); } if ($SipCodec) { $this->url.=sprintf("&SipCodec=%s",urlencode($SipCodec)); if ($SipCodec != "empty") { $mongo_where[$this->SipCodecField] = $SipCodec; } else { $mongo_where[$this->SipCodecField] = ''; } } if ($SipRPID) { $this->url.=sprintf("&SipRPID=%s",urlencode($SipRPID)); if ($SipRPID != "empty") { $mongo_where[$this->SipRPIDField] = $SipRPID; } else { $mongo_where[$this->SipRPIDField] = ''; } } if ($UserAgent) { $mongo_where[$this->UserAgentField] = $UserAgent; $this->url.=sprintf("&UserAgent=%s",urlencode($UserAgent)); } if (strlen($sip_status)) { $mongo_where[$this->disconnectField] = $sip_status; $this->url.=sprintf("&sip_status=%s",urlencode($sip_status)); } if ($sip_status_class) { $mongo_where[$this->disconnectField] = new MongoRegex("/^$sip_status_class/"); $this->url.=sprintf("&sip_status_class=%s",urlencode($sip_status_class)); } if ($this->CDRTool[filter]["gateway"]) { $mongo_where[$this->gatewayField] = $this->CDRTool[filter]["gateway"]; } else if ($gateway) { $gateway=urldecode($gateway); $mongo_where[$this->gatewayField] = $gateway; $this->url.=sprintf("&gateway=%s",$gateway); } if ($duration) { if (preg_match("/\d+/",$duration) ) { $mongo_where[$this->durationField] = array('$gt' => 0);; } elseif (preg_match("/onehour/",$duration) ) { $mongo_where[$this->durationField] = array('$lt' => 3610, '$gt' => 3530); } elseif ($duration == "zero") { $mongo_where[$this->durationField] = 0; } elseif ($duration == "zeroprice" && $this->priceField) { $mongo_where[$this->durationField] = array('$gt' => 0); $mongo_where[$this->priceField] = NULL; } elseif ($duration == "nonzero") { $mongo_where[$this->durationField] = array('$gt' => 0); } elseif ($duration == "onewaymedia") { $mongo_where['$or'] = array(array($this->outputTrafficField => 0), array($this->inputTrafficField => 0)); } elseif ($duration == "nomedia") { $mongo_where[$this->inputTrafficField] = 0; $mongo_where[$this->outputTrafficField] = 0; } $this->url.=sprintf("&duration=%s",urlencode($duration)); } if ($media_info) { $this->url.=sprintf("&media_info=%s",urlencode($media_info)); $mongo_where[$this->MediaInfoField] = $media_info; } $this->url.=sprintf("&maxrowsperpage=%s",addslashes($this->maxrowsperpage)); $url_calls = $this->scriptFile.$this->url."&action=search"; if ($group_by) { $this->url.=sprintf("&group_by=%s",urlencode($group_by)); } $this->url_edit = $this->scriptFile.$this->url."&action=edit"; $this->url_run = $this->scriptFile.$this->url."&action=search"; $this->url_export = $_SERVER["PHP_SELF"].$this->url."&action=search&export=1"; if ($duration == "unnormalized") { $mongo_where[$this->normalizedField] = '0'; } if ($duration == "unnormalized_duration") { $mongo_where[$this->normalizedField] = '0'; $mongo_where[$this->durationField] = array('$gt' => 0); } if ($group_by) { $this->group_byOrig=$group_by; if ($group_by=="hour") { $group_by="HOUR(AcctStartTime)"; } else if (preg_match("/^DAY/",$group_by)) { $group_by="$group_by(AcctStartTime)"; } else if (preg_match("/BYMONTH/",$group_by)) { $group_by="DATE_FORMAT(AcctStartTime,'%Y-%m')"; } else if (preg_match("/BYYEAR/",$group_by)) { $group_by="DATE_FORMAT(AcctStartTime,'%Y')"; } else if ($group_by=="UserAgentType") { $group_by="SUBSTRING_INDEX($this->SipUserAgentsField, ' ', '1')"; } $this->group_by=$group_by; if ($group_by==$this->callIdField) { $having=sprintf(" having count(%s) > 1 ", addslashes($group_by)); } $field = array_search($group_by, $this->CDRFields); $pipeline=array( array('$match' => $mongo_where), array('$group' => array("_id" => sprintf('$%s', $field), 'calls' => array('$sum' => 1))), array('$match' => array('calls' => array('$gte' => 0))) ); $rows = 0; if ($mongo_table_ro) { try { $group_results = $mongo_table_ro->aggregate($pipeline); $rows = count($group_results); } catch (Exception $e) { printf("

Caught Mongo exception in show(): %s", $e->getMessage()); } } } else { $rows = 0; if ($mongo_table_ro) { try { $rows = $mongo_table_ro->find($mongo_where)->slaveOkay()->count(); } catch (Exception $e) { printf("

Caught Mongo exception in show(): %s", $e->getMessage()); } } } dprint_r($mongo_where); $this->rows=$rows; if ($this->CDRTool['filter']['aNumber']) { $this->showResultsMenuSubscriber('0',$begin_datetime,$end_datetime); } else { $this->showResultsMenu('0',$begin_datetime,$end_datetime); } if (!$this->next) { $i=0; $this->next=0; } else { $i=$this->next; } $j=0; $z=0; if ($rows>0) { if ($call_id && $ReNormalize) { if ($mongo_table_rw) { $mongo_table_rw->update(array($this->normalizedField=>0), array('$set' => array($this->callIdField => $call_id))); } } if ($UnNormalizedCalls=$this->getUnNormalized($mongo_where,$cdr_table)) { if (!$this->DATASOURCES[$this->cdr_source]['skipNormalizeOnPageLoad']) { if ($UnNormalizedCalls < $this->maxCDRsNormalizeWeb) { $this->NormalizeCDRS($mongo_where,$cdr_table); if (!$this->export && $this->status['normalized'] ) { print "

"; printf ("%d CDRs normalized. ",$this->status['normalized']); if ($this->status['cached_keys']['saved_keys']) { printf ("Quota usage updated for %d accounts. ",$this->status['cached_keys']['saved_keys']); } print "
"; } } } } if ($rows > $this->maxrowsperpage) { $maxrows=$this->maxrowsperpage+$this->next; if ($maxrows > $rows) { $maxrows=$rows; $prev_rows=$maxrows; } } else { $maxrows=$rows; } if ($duration == "unnormalized") { // if display un normalized calls we must substract // the amount of calls normalized above $maxrows=$maxrows-$this->status['normalized']; } $mongo_order_by = '_id'; if ($order_type == DESC) { $mongo_order_type = -1; } else { $mongo_order_type = 1; } if ($group_by) { if ($order_by == "group_by") { $mongo_order_by = '_id'; } else { $_tmp = array_search($order_by, $this->CDRFields); if (in_array($_tmp, array('price', 'duration','inputTraffic', 'outputTraffic'))) { $mongo_order_by = $_tmp; } else { $mongo_order_by = 'calls'; } } $pipeline=array( array('$match' => $mongo_where), array('$group' => array('_id' => sprintf('$%s', $field), 'calls' => array( '$sum' => 1), 'duration' => array( '$sum' => '$duration'), 'inputTraffic' => array( '$sum' => '$inputTraffic'), 'outputTraffic' => array( '$sum' => '$outputTraffic'), 'price' => array( '$sum' => '$price'), 'zero' => array( '$sum' => array('$cond'=> array(array('$eq' => array('$duration', 0)), 1, 0 ))), 'nonzero' => array( '$sum' => array('$cond'=> array(array('$gt' => array('$duration', 0)), 1, 0 ))) ) ), array('$match' => array('calls' => array('$gte' => 0))), array('$sort' => array($mongo_order_by => $mongo_order_type)), array('$skip' => intval($i)), array('$limit' => intval($this->maxrowsperpage)) ); //dprint_r($pipeline); try { $group_results = $mongo_table_ro->aggregate($pipeline); } catch (Exception $e) { printf("

Caught Mongo exception in show(): %s", $e->getMessage()); } $this->showTableHeaderStatistics(); foreach ($group_results as $result) { $found=$i+1; $mygroup = $result['_id']; $calls = $result['calls']; $seconds = $result['duration']; $price = $result['price']; $zero = $result['zero']; $zeroP = $calls/$zero * 100; $nonzero = $result['nonzero']; $nonzeroP = $calls/$nonzero * 100; $seconds_print = number_format($seconds,0); $minutes = number_format($seconds/60,0,"",""); $minutes_print = number_format($seconds/60,0); $hours = sec2hms($seconds); $AcctInputOctets = number_format($result['inputTraffic'] * 2/ 1024/1024,2,".",""); $AcctOutputOctets = number_format($result['outputTraffic'] * 2/ 1024/1024,2,".",""); $NetRateIn = $result['inputTraffic']*8*2/1024/$seconds; $NetRateOut = $result['outputTraffic']*8*2/1024/$seconds; $success = number_format($nonzero/$calls*100,2,".",""); $failure = number_format($zero/$calls*100,2,".",""); $NetworkRateIn = number_format($NetRateIn,2); $NetworkRateOut = number_format($NetRateOut,2); $NetworkRate = max($NetworkRateIn,$NetworkRateOut); $rr=floor($found/2); $mod=$found-$rr*2; if ($mod ==0) { $inout_color="lightgrey"; } else { $inout_color="white"; } $traceValue=""; $mygroup_print=quoted_printable_decode($mygroup); if ($this->group_byOrig==$this->DestinationIdField) { if ($this->CDRTool['filter']['domain'] && $this->destinations[$this->CDRTool['filter']['domain']]) { list($_dst_id,$_dst_name)=$this->getPSTNDestinationId($mygroup,'',$this->CDRTool['filter']['domain']); $description=$_dst_name; } else { $description=$this->destinations[0]["default"][$mygroup]["name"]; } if ($mygroup) { $traceValue=$mygroup; } else { $traceValue="empty"; } } else if ($this->group_byOrig==$this->aNumberField) { # Normalize Called Station Id $N=$this->NormalizeNumber($mygroup); $mygroup_print=$N['username']."@".$N[domain]; $description=""; $traceField="a_number"; $traceValue=urlencode($mygroup); } else if ($this->group_byOrig==$this->CanonicalURIField) { $traceField="c_number"; $traceValue=urlencode($mygroup); } else if ($this->group_byOrig==$this->SipProxyServerField) { $traceField="sip_proxy"; $traceValue=urlencode($mygroup); } else if ($this->group_byOrig==$this->SipCodecField) { $traceField="SipCodec"; } else if (preg_match("/UserAgent/",$this->group_byOrig)) { $traceField="UserAgent"; } else if (preg_match("/^BY/",$this->group_byOrig)) { $traceField="MONTHYEAR"; } else if ($this->group_byOrig==$this->callIdField) { $traceField="call_id"; } else if ($this->group_byOrig=="SourceIP") { $traceField = "gateway"; } else if ($this->group_byOrig=="SipResponseCode") { $description = $this->disconnectCodesDescription[$mygroup]; $traceField="sip_status"; } else if ($this->group_byOrig=="SipApplicationType") { $traceField="application"; } else if ($this->group_byOrig=="ServiceType") { $traceField="flow"; } else { $description=""; } if (!$traceField) { $traceField = $group_by; } if (!$traceValue) { $traceValue = $mygroup; } if (!$traceValue) { $traceValue=""; $comp_type="empty"; } else { $comp_type="begin"; } $traceValue_enc=urlencode($traceValue); if (!$this->export) { print " $found $calls $seconds_print $minutes_print $hours "; if ($perm->have_perm("showPrice")) { $pricePrint=number_format($price,4,".",""); } else { $pricePrint='x.xxx'; } print " $pricePrint $AcctInputOctets $AcctOutputOctets $success% ($nonzero calls) $failure% ($zero calls) $mygroup_print $description "; printf("Display calls",$url_calls,$traceField,$traceValue_enc,$traceField,$comp_type); print " "; } else { print "$found,"; print "$calls,"; print "$seconds,"; print "$minutes,"; print "$hours,"; if ($perm->have_perm("showPrice")) { $pricePrint=$price; } else { $pricePrint='x.xxx'; } print "$pricePrint,"; print "$AcctInputOctets,"; print "$AcctOutputOctets,"; print "$success,"; print "$nonzero,"; print "$failure,"; print "$zero,"; print "$mygroup_print,"; print "$description"; print "\n"; } $i++; } if (!$this->export) { print " "; } } else { if (!$this->export) { // printf ("

For more information about each call click on its Id column.
"); } if ($order_by=="zeroP" || $order_by=="nonzeroP") { $order_by="timestamp"; } if ($mongo_table_ro) { $cursor = $mongo_table_ro->find($mongo_where)->sort(array($mongo_order_by=>$mongo_order_type))->skip($i)->limit($this->maxrowsperpage)->slaveOkay(); } else { $cursor = array(); } if ($this->CDRTool['filter']['aNumber']) { $this->showTableHeaderSubscriber(); } else { if (!$this->export) { $this->showTableHeader(); } else { $this->showExportHeader(); } } foreach ($cursor as $result) { global $found; $found=$i+1; $Structure=$this->_readCDRFieldsFromDB($result); $CDR = new $this->CDR_class($this, $Structure); if ($this->CDRTool['filter']['aNumber']) { $CDR->showSubscriber(); } else { if (!$this->export) { $CDR->show(); } else { $CDR->export(); } } $i++; } if (!$this->export) { print " "; } } $this->showPagination($this->next,$maxrows); } } } class CDR_opensips_mongo extends CDR_opensips { } class SIP_trace { var $enableThor = false; var $trace_array = array(); var $traced_ip = array(); var $SIPProxies = array(); var $mediaTrace = false; var $thor_nodes = array(); var $hostnames = array(); function SIP_trace ($cdr_source) { global $DATASOURCES, $auth; $this->cdr_source = $cdr_source; $this->cdrtool = new DB_CDRTool(); if (!is_array($DATASOURCES[$this->cdr_source])) { $log=sprintf("Error: datasource '%s' is not defined",$this->cdr_source); print $log; return 0; } if (strlen($DATASOURCES[$this->cdr_source]['enableThor'])) { $this->enableThor = $DATASOURCES[$this->cdr_source]['enableThor']; } if (strlen($DATASOURCES[$this->cdr_source]['mediaTrace'])) { $this->mediaTrace = $DATASOURCES[$this->cdr_source]['mediaTrace']; } if ($this->enableThor) { require("/etc/cdrtool/ngnpro_engines.inc"); require_once("ngnpro_soap_library.php"); if ($DATASOURCES[$this->cdr_source]['soapEngineId'] && in_array($DATASOURCES[$this->cdr_source]['soapEngineId'],array_keys($soapEngines))) { $this->soapEngineId=$DATASOURCES[$this->cdr_source]['soapEngineId']; $this->SOAPlogin = array( "username" => $soapEngines[$this->soapEngineId]['username'], "password" => $soapEngines[$this->soapEngineId]['password'], "admin" => true ); $this->SOAPurl=$soapEngines[$this->soapEngineId]['url']; $this->SoapAuth = array('auth', $this->SOAPlogin , 'urn:AGProjects:NGNPro', 0, ''); // Instantiate the SOAP client $this->soapclient = new WebService_NGNPro_SipPort($this->SOAPurl); $this->soapclient->setOpt('curl', CURLOPT_TIMEOUT, 5); $this->soapclient->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->soapclient->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); if (is_array($soapEngines[$this->soapEngineId]['hostnames'])) { $this->hostnames=$soapEngines[$this->soapEngineId]['hostnames']; } } else { printf ("

Error: soapEngineID not defined in datasource %s",$this->cdr_source); return false; } } else { $this->table = $DATASOURCES[$this->cdr_source]['table']; $db_class = $DATASOURCES[$this->cdr_source]['db_class']; $this->purgeRecordsAfter = $DATASOURCES[$this->cdr_source]['purgeRecordsAfter']; if (class_exists($db_class)) { $this->db = new $db_class; } else { printf("

Error: database class '%s' is not defined",$db_class); return false; } } if (is_object($auth)) $this->isAuthorized=1; if (is_array($DATASOURCES[$this->cdr_source]['SIPProxies'])) { $this->SIPProxies=$DATASOURCES[$this->cdr_source]['SIPProxies']; } } function isProxy($ip,$sip_proxy='') { if (!$ip) return false; if (!$this->enableThor) { if (!is_array($this->SIPProxies)) { return false; } if (in_array($ip,array_keys($this->SIPProxies))) { return true; } } else if ($sip_proxy) { if ($this->thor_nodes[$ip]) { return true; } else { if (isThorNode($ip,$sip_proxy)) { $this->thor_nodes[$ip]=1; return true; } else { return false; } } } return false; } function getTrace ($proxyIP,$callid,$fromtag,$totag) { if ($this->enableThor) { // get trace using soap request if (!$proxyIP || !$callid || !$fromtag) return false; if (!is_object($this->soapclient)) { print "Error: soap client is not defined."; return false; } $this->seen_ip=array(); $filter=array('nodeIp' => $proxyIP, 'callId' => $callid, 'fromTag' => $fromtag, 'toTag' => $totag ); $this->soapclient->addHeader($this->SoapAuth); $result = $this->soapclient->getSipTrace($filter); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault = $result->getFault(); $error_code = $result->getCode(); printf("Error from %s: %s (%s)",$this->SOAPurl, $error_fault->detail->exception->errorstring, $error_fault->detail->exception->errorcode ); return false; } $columns=0; $traces=json_decode($result); $trace_array=array(); foreach ($traces as $_trace) { if (preg_match("/^(udp|tcp|tls):(.*):(.*)$/",$_trace->to_ip,$m)) { $toip = $m[2]; $transport = $m[1]; $toport = $m[3]; } else if (preg_match("/^(.*):(.*)$/",$_trace->to_ip,$m)) { $toip = $m[1]; $transport = 'udp'; $toport = $m[2]; } else { $toip = $_trace->to_ip; $transport = 'udp'; $toport = '5060'; } if (preg_match("/^(udp|tcp|tls):(.*):(.*)$/",$_trace->from_ip,$m)) { $fromip = $m[2]; $fromport = $m[3]; } else if (preg_match("/^(.*):(.*)$/",$_trace->from_ip,$m)) { $fromip = $m[1]; $fromport = $m[2]; } else { $fromip = $_trace->from_ip; } if (!$this->seen_ip[$toip] && $this->isProxy($toip)) { $this->seen_ip[$toip]++; } if (!$this->seen_ip[$fromip] && $this->isProxy($fromip)) { $this->seen_ip[$fromip]++; } if (!$this->column[$fromip]) { $this->column[$fromip] = $columns+1; $this->column_port[$fromip]=$fromport; $columns++; } if (!$this->column[$toip]) { $this->column[$toip] = $columns+1; $this->column_port[$toip]=$toport; $columns++; } preg_match("/^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)$/",$_trace->time_stamp,$m); $timestamp = mktime($m[4],$m[5],$m[6],$m[2],$m[3],$m[1]); $idx=$proxyIP.'_'.$_trace->id; $trace_array[$idx]= array ( 'id' => $idx, 'direction' => $_trace->direction, 'fromip' => $fromip, 'toip' => $toip, 'fromport' => $fromport, 'toport' => $toport, 'method' => $_trace->method, 'transport' => $transport, 'date' => $_trace->time_stamp, 'status' => $_trace->status, 'timestamp' => $timestamp, 'msg' => $_trace->message, 'md5' => md5($_trace->message) ); } $this->trace_array=$trace_array; $this->rows = count($this->trace_array); } else { // get trace from SQL if (!is_object($this->db)) { print "

Error: no database connection defined"; return false; } $query=sprintf("select *,UNIX_TIMESTAMP(time_stamp) as timestamp from %s where callid = '%s' order by id asc", addslashes($this->table), addslashes($callid)); if (!$this->db->query($query)) { printf ("Database error for query %s: %s (%s)",$query,$this->db->Error,$this->db->Errno); return false; } $this->rows = $this->db->num_rows(); $columns = 0; while ($this->db->next_record()) { if (preg_match("/^(udp|tcp|tls):(.*):(.*)$/",$this->db->f('toip'),$m)) { $toip = $m[2]; $transport = $m[1]; $toport = $m[3]; } else if (preg_match("/^(.*):(.*)$/",$this->db->f('toip'),$m)) { $toip = $m[1]; $transport = 'udp'; $toport = $m[2]; } else { $toip = $this->db->f('toip'); $toport = '5060'; } if (preg_match("/^(udp|tcp|tls):(.*):(.*)$/",$this->db->f('fromip'),$m)) { $fromip = $m[2]; $fromport = $m[3]; } else if (preg_match("/^(.*):(.*)$/",$this->db->f('fromip'),$m)) { $fromip = $m[1]; $fromport = $m[2]; } else { $fromip = $this->db->f('fromip'); $transport = 'udp'; $fromport = '5060'; } if (!$this->seen_ip[$toip] && $this->isProxy($toip)) { $this->seen_ip[$toip]++; } if (!$this->seen_ip[$fromip] && $this->isProxy($fromip)) { $this->seen_ip[$fromip]++; } if (!$this->column[$fromip]) { $this->column[$fromip]=$columns+1; $this->column_port[$fromip]=$fromport; $columns++; } if (!$this->column[$toip]) { $this->column[$toip]=$columns+1; $this->column_port[$toip]=$toport; $columns++; } $this->trace_array[$this->db->f('id')]= array ( 'id' => $this->db->f('id'), 'direction' => $this->db->f('direction'), 'fromip' => $fromip, 'toip' => $toip, 'method' => $this->db->f('method'), 'fromport' => $fromport, 'toport' => $toport, 'transport' => $transport, 'date' => $this->db->f('time_stamp'), 'status' => $this->db->f('status'), 'timestamp' => $this->db->f('timestamp'), 'msg' => $this->db->f('msg'), 'md5' => md5($this->db->f('msg')) ); } } } function show($proxyIP,$callid,$fromtag,$totag) { $action = $_REQUEST['action']; $toggleVisibility = $_REQUEST['toggleVisibility']; if ($action=='toggleVisibility') { $this->togglePublicVisibility($callid,$fromtag,$toggleVisibility); } if ($_SERVER['HTTPS'] == "on") { $protocolURL = "https://"; } else { $protocolURL = "http://"; } $this->getTrace($proxyIP,$callid,$fromtag,$totag); if (!count($this->trace_array)) { print "

SIP trace for session id $callid is not available."; return; } print "

CDRTool SIP trace SIP session $callid $authorizei

"; // if ($this->isAuthorized) { // $key="callid-".trim($callid).trim($fromtag); // $query=sprintf("select * from memcache where `key` = '%s'",addslashes($key)); // $this->cdrtool->query($query); $basicURL = $protocolURL.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; // if ($this->cdrtool->num_rows()) { // $selected_toggleVisibility['public']="selected"; // $fullURL=$basicURL."&public=1"; // $color2="lightblue"; // } else { // $selected_toggleVisibility['private']="selected"; $fullURL=$basicURL; // } // print " // This SIP trace is visible // // // "; print "URLs for this trace: HTML | TEXT"; //} else { // print ""; //} if ($this->mediaTrace) { $this->mediaTraceLink=sprintf("

Click here for RTP media information

", $this->mediaTrace, urlencode($callid), urlencode($fromtag), urlencode($totag), $proxyIP ); } print "

Click on each packet to expand its body content

$this->mediaTraceLink
"; foreach (array_keys($this->trace_array) as $key) { if ($this->trace_array[$key]['direction'] == 'in') { if (is_array($this->SIPProxies)) { $thisIP=explode(":",$this->trace_array[$key]['fromip']); if ($this->isProxy($thisIP[0],$proxyIP)) { $this->trace_array[$key]['isProxy'] = 1; } } if ($this->trace_array[$key]['fromip'] == $this->trace_array[$key]['toip']) { $this->trace_array[$key]['arrow_align'] = "left"; $arrow_direction="loop"; } else if ($this->column[$this->trace_array[$key]['fromip']] < $this->column[$this->trace_array[$key]['toip']]) { $arrow_direction="right"; $this->trace_array[$key]['arrow_align'] = "right"; } else { $arrow_direction="left"; $this->trace_array[$key]['arrow_align'] = "left"; } $this->trace_array[$key]['msg_possition'] = $this->column[$this->trace_array[$key]['toip']]; $this->trace_array[$key]['arrow_possition'] = $this->column[$this->trace_array[$key]['fromip']]; $this->trace_array[$key]['arrow_direction'] = $arrow_direction; } else { if ($this->trace_array[$key]['fromip'] == $this->trace_array[$key]['toip']) { $this->trace_array[$key]['arrow_align'] = "left"; $arrow_direction="loop"; } else if ($this->column[$this->trace_array[$key]['fromip']] < $this->column[$this->trace_array[$key]['toip']]) { $this->trace_array[$key]['arrow_align'] = "left"; $arrow_direction="right"; } else { $this->trace_array[$key]['arrow_align'] = "right"; $arrow_direction="left"; } $this->trace_array[$key]['msg_possition'] = $this->column[$this->trace_array[$key]['fromip']]; $this->trace_array[$key]['arrow_possition'] = $this->column[$this->trace_array[$key]['toip']]; $this->trace_array[$key]['arrow_direction'] = $arrow_direction; } } //print_r($this->hostnames); print "

"; foreach (array_keys($this->column) as $_key) { $IPels=explode(":",$_key); if ($this->hostnames[$IPels[0]]) { $_hostname=$this->hostnames[$IPels[0]]; } else { $_hostname=$_key; } print ""; } print ""; $i=0; foreach (array_keys($this->trace_array) as $key) { $i++; $id = $this->trace_array[$key]['id']; $msg = $this->trace_array[$key]['msg']; $fromip = $this->trace_array[$key]['fromip']; $toip = $this->trace_array[$key]['toip']; $date = substr($this->trace_array[$key]['date'],11); $status = $this->trace_array[$key]['status']; $direction = $this->trace_array[$key]['direction']; $timestamp = $this->trace_array[$key]['timestamp']; $method = $this->trace_array[$key]['method']; $isProxy = $this->trace_array[$key]['isProxy']; $transport = $this->trace_array[$key]['transport']; $msg_possition = $this->trace_array[$key]['msg_possition']; $arrow_possition = $this->trace_array[$key]['arrow_possition']; $arrow_direction = $this->trace_array[$key]['arrow_direction']; $arrow_align = $this->trace_array[$key]['arrow_align']; $md5 = $this->trace_array[$key]['md5']; if ($i==1) $begin_timestamp = $timestamp; $timeline=$timestamp-$begin_timestamp; $sip_phone_img=getImageForUserAgent($msg); if ($seen_msg[$md5]) continue; $SIPclass=substr($status,0,1); if ($SIPclass=="6") { $status_color=""; } else if ($SIPclass=="5" ) { $status_color=""; } else if ($SIPclass=="4" ) { $status_color=""; } else if ($SIPclass=="3" ) { $status_color=""; } else if ($SIPclass=="2" ) { $status_color=""; } else if ($SIPclass=="1" ) { $status_color=""; } else { $status_color=""; } $_lines=explode("\n",$msg); if (preg_match("/^(.*) SIP/",$_lines[0],$m)) { $_lines[0]=$m[1]; } else if (preg_match("/^SIP\/2\.0 (.*)/",$_lines[0],$m)) { $_lines[0]=$m[1]; } unset($media); unset($diversions); $j=0; $media_index=0; $search_ice=0; $search_ip=0; $contact_header=''; foreach ($_lines as $_line) { if (preg_match("/^(Diversion: ).*;(.*)$/",$_line,$m)) { $diversions[]=$m[1].$m[2]; } if (preg_match("/^Cseq:\s*\d+\s*(.*)$/i",$_line,$m)) { $status_for_method=$m[1]; } if (preg_match("/^Contact:\s*.*@(.*:\d+).*$/i",$_line,$m)) { $contact_header=$m[1]; } if (preg_match("/^c=IN \w+ ([\d|\w\.]+)/i",$_line,$m)) { $media['ip']=$m[1]; } if (preg_match("/^m=(\w+) (\d+) /i",$_line,$m)) { $media_index++; $search_ice=1; $search_ip=1; $media['streams'][$media_index]=array('type' => $m[1], 'ip' => $media['ip'], 'port' => $m[2], 'ice' => '' ); } if ($search_ip && preg_match("/^c=IN \w+ ([\d|\w\.]+)/i",$_line,$m)) { $media['streams'][$media_index]['ip']=$m[1]; $search_ip=0; } if ($search_ice && preg_match("/^a=ice/i",$_line,$m)) { $media['streams'][$media_index]['ice']="ICE"; $search_ice=0; } $j++; } $_els=explode(";",$_lines[0]); $cell_content = " $status_color $_els[0] "; if ($status) $cell_content.=" for ".$status_for_method.""; if ($contact_header) { $cell_content.=sprintf("
Contact: %s",htmlspecialchars($contact_header)); } if (is_array($diversions)) { foreach ($diversions as $_diversion) { $cell_content.="
$_diversion"; } } if (is_array($media['streams'])) { foreach (array_keys($media['streams']) as $_key) { $_stream=sprintf("%s->%s:%s %s",$media['streams'][$_key]['type'], $media['streams'][$_key]['ip'], $media['streams'][$_key]['port'], $media['streams'][$_key]['ice'] ); if ($media['streams'][$_key]['port']) { $cell_content.="
$_stream"; } else { $cell_content.="
$_stream"; } } } $cell_content.="
"; print "
"; $column_current++; if ($arrow_direction=='loop') $seen_msg[$md5]++; } print ""; if (is_array($this->SIPProxies)) { $IPels=explode(":",$fromip); $justIP=$IPels[0]; foreach (array_keys($this->SIPProxies) as $localProxy) { if ($localProxy==$justIP) { $direction="out"; break; } } } $trace_span=count($this->column)+2; print " "; } print "
Packet Size Time"; if ($proxyIP != $IPels[0] && $this->isProxy($IPels[0],$proxyIP)) { - $trace_link=sprintf("%s:%s (Trace) ", urlencode($this->cdr_source), urlencode($callid), urlencode($fromtag), urlencode($totag), $IPels[0], $_hostname, $this->column_port[$_key] ); printf ("%s",$trace_link); } else { printf ("%s",$_hostname); } print "
"; if ($timeline && !$_seen_timeline[$timeline]) { printf ("%s+%ds ",$status_color,$timeline); $_seen_timeline[$timeline]++; } $len=strlen($msg); print " $status_color$i/$this->rows  $len bytes $status_color$date "; $column_current=1; while ($column_current <= count($this->column)) { if ($arrow_possition==$column_current) { if ($direction=='out') { if ($arrow_direction == 'left') { $arrow="green_arrow_left.png"; } else if ($arrow_direction == 'right') { $arrow="green_arrow_right.png"; } else if ($arrow_direction == 'loop'){ $arrow="LoopArrow.png"; } } else { if ($arrow_direction == 'left') { $arrow="blue_arrow_left.png"; } else if ($arrow_direction == 'right') { $arrow="blue_arrow_right.png"; } else if ($arrow_direction == 'loop'){ $arrow="LoopArrow.png"; } } } if ($arrow_possition==$column_current) { print ""; if ($arrow_direction == 'left') { print ""; if (!$isProxy && $direction=='in' && $sip_phone_img && $sip_phone_img!='unknown.png') print ""; } else { if (!$isProxy && $direction=='in' && $sip_phone_img && $sip_phone_img!='unknown.png') print ""; print ""; } print "
"; if ($transport == 'tls') print " "; if ($direction == 'in') { printf ("%s port %d",strtoupper($transport),$this->trace_array[$key]['fromport']); } else { printf ("%s port %d",strtoupper($transport),$this->trace_array[$key]['toport']); } } else { print "
"; } if ($msg_possition == $column_current) { print $cell_content; print "
"; if ($direction == 'in') { printf ("%s port %d",strtoupper($transport),$this->trace_array[$key]['toport']); } else { printf ("%s port %d",strtoupper($transport),$this->trace_array[$key]['fromport']); } } else { print " "; } print "
"; print "
"; if ($direction == "out") { print "

SIP Proxy

"; } else { if ($sip_phone_img && $sip_phone_img!='unknown.png') { print ""; } else { print ""; } } print "
"; if ($timeline > 0) { printf ("

+%s s
(%s)",$timeline,sec2hms($timeline)); } print "

"; $msg=nl2br(htmlentities($msg)); print " $status_color $msg
"; print "
"; } function showText($proxyIP,$callid,$fromtag,$totag) { $this->getTrace($proxyIP,$callid,$fromtag,$totag); print "

";
 
         if (!count($this->trace_array)) {
             print "SIP trace for session id $callid is not available.";
             return false;
         }
 
         printf ("SIP trace on proxy %s for session %s\n--\n\n",$proxyIP,$callid);
 
         foreach (array_keys($this->trace_array) as $key) {
             $i++;
             printf ("Packet %d at %s from %s to %s (%s)\n",
             $i,
             $this->trace_array[$key]['date'],
             $this->trace_array[$key]['fromip'],
             $this->trace_array[$key]['toip'],
             $this->trace_array[$key]['direction']);
             printf ("\n%s\n",htmlspecialchars($this->trace_array[$key]['msg']));
             print "---\n";
         }
         print "
"; } function togglePublicVisibility($callid,$fromtag,$public='0') { $key="callid-".trim($callid).trim($fromtag); if (!$public) { $query=sprintf("delete from memcache where `key` = '%s'",addslashes($key)); $this->cdrtool->query($query); } else { $query=sprintf("delete from memcache where `key` = '%s'",addslashes($key)); $this->cdrtool->query($query); $query=sprintf("insert into memcache values ('%s','public')",addslashes($key)); $this->cdrtool->query($query); } } function purgeRecords($days='') { if ($this->enableThor) { return true; } $b=time(); if ($days) { $this->purgeRecordsAfter=$days; } else if (!$this->purgeRecordsAfter) { $this->purgeRecordsAfter=15; } $beforeDate=Date("Y-m-d", time()-$this->purgeRecordsAfter*3600*24); $query=sprintf("select id as min, time_stamp from %s order by id ASC limit 1", addslashes($this->table)); if ($this->db->query($query)) { if ($this->db->num_rows()) { $this->db->next_record(); $min=$this->db->f('min'); $begindate=$this->db->f('date'); } else { $log=sprintf("No records found in %s\n",$this->table); print $log; syslog(LOG_NOTICE,$log); return false; } } else { $log=sprintf("Error: %s (%s)\n",$this->db->Error,$query); print $log; syslog(LOG_NOTICE,$log); return false; } $query=sprintf("select id as max from %s where time_stamp < '%s' order by id DESC limit 1", addslashes($this->table),addslashes($beforeDate)); if ($this->db->query($query) && $this->db->num_rows()) { $this->db->next_record(); $max=$this->db->f('max'); } else { $log=sprintf("No records found in %s before %s, records start after %s\n", $this->table,$beforeDate,$begindate); syslog(LOG_NOTICE,$log); print $log; return false; } $deleted=0; $i=$min; $interval=1000; $rows2delete=$max-$min; $found = 0; print "$rows2delete traces to delete between $min and $max\n"; while ($i<=$max) { $found=$found+$interval; if ($i + $interval < $max) { $top=$i; } else { $top=$max; } $query=sprintf("delete low_priority from %s where id >= '%d' and id <='%d'", addslashes($this->table),addslashes($min),addslashes($top)); if ($this->db->query($query)) { $deleted=$deleted+$this->db->affected_rows(); } else { $log=sprintf("Error: %s (%s)",$this->db->Error,$this->db->Errno); syslog(LOG_NOTICE,$log); return false; } if ($found > $progress*$rows2delete/100) { $progress++; if ($progress%10==0) { print "$progress% "; } flush(); } $i=$i+$interval; } print "\n"; $e =time(); $d =$e-$b; $rps=0; if ($deleted && $d) $rps=$deleted/$d; $log=sprintf("%s records before %s from %s deleted in %d s @ %.0f rps\n",$deleted,$beforeDate,$this->table,$d,$rps); syslog(LOG_NOTICE,$log); print $log; return true; } } class Media_trace { var $enableThor = false; var $table = 'media_sessions'; function Media_trace ($cdr_source) { global $DATASOURCES; $this->cdr_source = $cdr_source; $this->cdrtool = new DB_CDRTool(); if (!is_array($DATASOURCES[$this->cdr_source])) { $log=sprintf("Error: datasource '%s' is not defined",$this->cdr_source); print $log; return 0; } if (strlen($DATASOURCES[$this->cdr_source]['enableThor'])) { $this->enableThor = $DATASOURCES[$this->cdr_source]['enableThor']; } if ($this->enableThor) { require("/etc/cdrtool/ngnpro_engines.inc"); require_once("ngnpro_soap_library.php"); if ($DATASOURCES[$this->cdr_source]['soapEngineId'] && in_array($DATASOURCES[$this->cdr_source]['soapEngineId'],array_keys($soapEngines))) { $this->soapEngineId=$DATASOURCES[$this->cdr_source]['soapEngineId']; $this->SOAPlogin = array( "username" => $soapEngines[$this->soapEngineId]['username'], "password" => $soapEngines[$this->soapEngineId]['password'], "admin" => true ); $this->SOAPurl=$soapEngines[$this->soapEngineId]['url']; $this->SoapAuth = array('auth', $this->SOAPlogin , 'urn:AGProjects:NGNPro', 0, ''); // Instantiate the SOAP client $this->soapclient = new WebService_NGNPro_SipPort($this->SOAPurl); $this->soapclient->setOpt('curl', CURLOPT_TIMEOUT, 5); $this->soapclient->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->soapclient->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); } else { print "Error: soapEngineID not defined in datasource $this->cdr_source"; return false; } } else { if ($DATASOURCES[$this->cdr_source]['table']) { $this->table = $DATASOURCES[$this->cdr_source]['table']; } $db_class = $DATASOURCES[$this->cdr_source]['db_class']; if (class_exists($db_class)) { $this->db = new $db_class; } else { printf("

Error: database class %s is not defined in datasource %s",$db_class,$this->cdr_source); return false; } } } function getTrace ($proxyIP,$callid,$fromtag,$totag) { if ($this->enableThor) { // get trace using soap request if (!$proxyIP || !$callid || !$fromtag) { print "

Error: proxyIP or callid or fromtag are not defined"; return false; } if (!is_object($this->soapclient)) { print "

Error: soap client is not defined"; return false; } $filter=array('nodeIp' => $proxyIP, 'callId' => $callid, 'fromTag' => $fromtag, 'toTag' => $totag ); $this->soapclient->addHeader($this->SoapAuth); $result = $this->soapclient->getMediaTrace($filter); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault = $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != 1060) { printf("Error from %s: %s (%s)", $this->SOAPurl, $error_fault->detail->exception->errorstring, $error_fault->detail->exception->errorcode ); } return false; } $this->info = json_decode($result); } else { if (!is_object($this->db)) { print "

Error: no database connection defined"; return false; } // get trace from SQL $query=sprintf("select info from %s where call_id = '%s' and from_tag = '%s' and to_tag= '%s'", addslashes($this->table), addslashes($callid), addslashes($fromtag), addslashes($totag) ); if (!$this->db->query($query)) { printf ("

Database error for query %s: %s (%s)",$query,$this->db->Error,$this->db->Errno); return false; } if ($this->db->num_rows()) { $this->db->next_record(); $this->info = json_decode($this->db->f('info')); } } } function show($proxyIP,$callid,$fromtag,$totag) { if ($_SERVER['HTTPS'] == "on") { $protocolURL = "https://"; } else { $protocolURL = "http://"; } $this->getTrace($proxyIP,$callid,$fromtag,$totag); print "

"; if (!is_object($this->info)) { print "

No information available."; return false; } if (!count($this->info->streams)) { print "

No RTP media streams have been established"; return; } print "

CDRTool Media Trace Media Session $callid

"; foreach (array_values($this->info->streams) as $_val) { $_diff=$_val->end_time-$_val->timeout_wait; $seen_stamp[$_val->start_time]++; $seen_stamp[$_val->end_time]++; $seen_stamp[$_diff]++; $media_types[]=$_val->media_type; } print "

Media Information

"; print ""; printf ("",$this->info->duration); list($relay_ip,$relay_port)=explode(":",$this->info->streams[0]->caller_local); printf ("",$relay_ip); print "
Call duration%s
Media relay%s
"; print "

Media Streams

"; print ""; print ""; foreach (array_values($media_types) as $_type) { printf ("",ucfirst($_type)); } print ""; foreach ($this->info->streams[0] as $_val => $_value) { printf ("",ucfirst(preg_replace("/_/"," ",$_val))); $j=0; while ($j < count($media_types)) { printf ("",$this->info->streams[$j]->$_val); $j++; } printf ("\n"); } print "
%s
%s%s
"; print "

Stream Succession

"; $w_legend_bar=500; $w_text=30; $stamps=array_keys($seen_stamp); sort($stamps); $w_table=$w_legend_bar+$w_text; print ""; $j=0; $_index=0; foreach (array_values($this->info->streams) as $_val) { if ($_val->status == 'unselected ice candidate') continue; $_index=$_index+$_val->start_time; $_duration = $_val->end_time-$_val->start_time; $_timeout = $_val->timeout_wait; $duration_print= $_duration; if ($_val->status == 'conntrack timeout') { $w_duration = intval(($_duration-$_timeout)*$w_legend_bar/$this->info->duration); $w_timeout = intval($_timeout*$w_legend_bar/$this->info->duration); $duration_print = $_duration - $_timeout; } else if ($_val->status == 'no-traffic timeout') { $w_duration = intval($_duration*$w_legend_bar/$this->info->duration); $w_timeout = intval($_timeout*$w_legend_bar/$this->info->duration); } else if ($_val->status == 'closed' ) { $w_duration = intval($_duration * $w_legend_bar / $this->info->duration); $w_timeout = 0; } $w_start_time = intval($_index*$w_legend_bar/$this->info->duration); $w_rest = $w_legend_bar-$w_duration-$w_timeout-$w_start_time; $w_duration_p = ($w_legend_bar/$w_duration) * 100; $w_timeout_p = ($w_legend_bar/$w_timeout)* 100; $w_start_p = ($w_legend_bar/$w_start)* 100; //printf ("%s, %s, %s, %s
\n",$w_start_p,$w_duration_p,$w_timeout_p,$w_rest); if ($_val->caller_packets != '0' && $_val->callee_packets != '0'){ print ""; print ""; } elseif ( $_val->status == 'unselected ICE candidate') { print ""; } else { print ""; } } print "
$_val->media_type\n"; //print "\n"; print "
"; print "
\n"; print "
$duration_print
\n"; if ($_val->timeout_wait) { print "
$_timeout
\n"; } else { print "
\n"; } //print "
\n"; //print "
\n"; print "
ICE session
No stream data found
"; print "
Legend"; print "

Session data
Timeout period

"; } } include_once("phone_images.php"); function getImageForUserAgent($msg) { global $userAgentImages; $msg_lines=explode("\n",$msg); foreach($msg_lines as $line) { $els=explode(":",$line); if (strtolower($els[0]) == 'user-agent' || strtolower($els[0]) == 'server') { foreach ($userAgentImages as $agentRegexp => $image) { if (preg_match("/^(user-agent|server):.*$agentRegexp/i", $line)) { return $image; } } } } return "unknown.png"; } function isThorNode($ip,$sip_proxy) { if (!$ip || !$sip_proxy) return false; $socket = fsockopen($sip_proxy, 9500, $errno, $errstr, 1); if (!$socket) { return false; } $request=sprintf("is_online %s as sip_proxy",$ip); if (fputs($socket,"$request\r\n") !== false) { $ret = trim(fgets($socket,4096)); fclose($socket); } else { fclose($socket); return false; } if ($ret == 'Yes') { return true; } else { return false; } } ?> diff --git a/library/sip_settings.php b/library/sip_settings.php index 7f765ac..b00bf46 100644 --- a/library/sip_settings.php +++ b/library/sip_settings.php @@ -1,12469 +1,12469 @@ "; var $billing_email = "Billing "; var $sip_settings_page = "https://cdrtool.example.com/sip_settings.phtml"; var $xcap_root = "https://cdrtool.example.com/xcap-root"; var $pstn_access = false; var $sms_access = false; var $pstn_changes_allowed = false; var $prepaid_changes_allowed = false; var $sip_proxy = "proxy.example.com"; var $voicemail_server = "vm.example.com"; var $absolute_voicemail_uri = false; // use var $enable_thor = false; var $currency = "€"; // access numbers var $voicemail_access_number = "1233"; var $FUNC_access_number = "*21*"; var $FNOL_access_number = "*22*"; var $FNOA_access_number = "*23*"; var $FBUS_access_number = "*23*"; var $change_privacy_access_number = "*67"; var $check_privacy_access_number = "*68"; var $reject_anonymous_access_number = "*69"; var $show_barring_tab = false; var $show_payments_tab = false; var $show_tls_section = false; var $show_support_tab = false; var $show_did_tab = false; var $show_directory = false; var $first_tab = 'calls'; var $auto_refesh_tab = 0; // number of seconds after which to refresh tab content in the web browser var $payment_processor_class = false; var $did_processor_class = false; var $show_download_tab = 'Blink'; // set it to name of the tab or false to disable it var $digest_settings_page = "https://blink.sipthor.net/settings.phtml"; // end variables var $tab = "settings"; var $phonebook_img = ""; var $call_img = "
"; var $delete_img = "Delete"; var $plus_sign_img = "Add Contact"; var $embedded_img = ""; var $groups = array(); var $form_elements = array( 'mailto', 'free-pstn', 'blocked', 'sip_password', 'web_password', 'yubikey', 'first_name', 'last_name', 'quota', 'language', 'quota_deblock', 'voicemail', 'anonymous', 'advanced', 'rpid', 'timezone', 'accept', 'accept_temporary_group', 'accept_temporary_remain', 'web_timestamp', 'acceptDailyStartTime', 'acceptDailyStopTime', 'acceptDailyGroup', 'quickdial', 'delete_voicemail', 'voicemail_password', 'region', 'timeout', 'owner', 'mobile_number', 'extra_groups', 'show_barring_tab', 'ip_access_list', 'callLimit' ); var $disable_extra_groups=true; var $prepaid = 0; var $emergency_regions = array(); var $FNOA_timeoutDefault = 35; var $enums = array(); var $barring_prefixes = array(); var $SipUAImagesPath = "images"; var $SipUAImagesFile = "phone_images.php"; var $balance_history = array(); var $enrollment_url = false; var $sip_settings_api_url= false; var $journalEntries = array(); var $chat_replication_backend = 'mysql'; // mongo or mysql var $owner_information =array(); var $languages=array("en"=>array('name'=>"English", 'timezone'=>'' ), "ro"=>array('name'=>"Română", 'timezone' => 'Europe/Bucharest' ), "nl"=>array('name'=>"Nederlands", 'timezone' => 'Europe/Amsterdam' ), "es"=>array('name'=>"Español", 'timezone' => 'Europe/Madrid' ), "de"=>array('name'=>"Deutsch", 'timezone' => 'Europe/Berlin' ) ); var $pstn_termination_price_page = 'sip_rates_body.html'; var $append_domain_to_xcap_root = false; var $blink_download_url = "https://blink.sipthor.net/download.phtml?download"; var $ownerCredentials = array(); var $localGroups = array(); var $max_credit_per_day = 40; var $enrollment_configuration = "/etc/cdrtool/enrollment/config.ini"; var $require_proof_of_identity = true; var $call_limit_may_by_changed_by = 'reseller'; #subscriber, reseller, admin var $ip_access_list_may_by_changed_by = 'reseller'; #subscriber, reseller, admin var $create_certificate = false; function SipSettings($account,$loginCredentials=array(),$soapEngines=array()) { //define_syslog_variables(); $this->platform_call_limit = _('unlimited'); $this->soapEngines = $soapEngines; $debug=sprintf("

Initialize %s(%s)",get_class($this),$account); dprint($debug); //dprint_r($loginCredentials); $this->loginCredentials = &$loginCredentials; if ($this->isEmbedded()) { $this->login_type = 'subscriber'; } else { if ($loginCredentials['login_type']) { $this->login_type = $loginCredentials['login_type']; } else { $this->login_type = 'subscriber'; } } $this->reseller = $loginCredentials['reseller']; $this->customer = $loginCredentials['customer']; if (strlen($loginCredentials['sip_engine'])) { $this->sip_engine=$loginCredentials['sip_engine']; } else { print _("Error: missing sip_engine in login credentials"); return false; } $this->settingsPage = $_SERVER['PHP_SELF']; if ($_REQUEST['tab']) { $this->tab = $_REQUEST['tab']; } else { $this->tab = $this->first_tab; } $this->initSoapClient(); $this->getAccount($account); if ($this->tab=='calls' && !$_REQUEST['export']) { $this->auto_refesh_tab=180; } $this->admin_url = $this->settingsPage."?account=$this->account&adminonly=1&reseller=$this->reseller&sip_engine=$this->sip_engine"; $this->reseller_url = $this->settingsPage."?account=$this->account&reseller=$this->reseller&sip_engine=$this->sip_engine"; $this->admin_url_absolute = $this->sip_settings_page."?account=$this->account&adminonly=1&reseller=$this->reseller&sip_engine=$this->sip_engine"; if ($this->login_type == "admin") { $this->url=$this->admin_url; $this->hiddenElements=" account\"> reseller> sip_engine> "; } else if ($this->login_type == "reseller" || $this->login_type == "customer") { $this->url=$this->reseller_url; $this->hiddenElements=" account\"> reseller> sip_engine> "; } else { $this->url=$this->settingsPage; if (!$this->isEmbedded()) { $this->url.="?account=$this->account"; } else { $this->url.=sprintf("?1=1&realm=%s",urlencode($_REQUEST['realm'])); if ($_REQUEST['user_agent']) { $this->url.=sprintf("&user_agent=%s",urlencode($_REQUEST['user_agent'])); } } $this->hiddenElements=sprintf(" ", $this->account, $this->sip_engine, $_REQUEST['user_agent'], $_REQUEST['realm'] ); } $this->setLanguage(); if (!$this->username) { dprint ("Record not found."); return false; } $this->availableGroups['blocked'] = array("Group"=>"blocked", "WEBName" =>sprintf(_("Status")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>0, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->availableGroups['deny-password-change'] = array("Group"=>"deny-password-change", "WEBName" =>sprintf(_("Deny password change")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>0, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->getResellerSettings(); $this->getCustomerSettings(); if ($this->change_privacy_access_number) { $_comment=sprintf(_("Dial %s to change"),$this->change_privacy_access_number); } else { $_comment=''; } if ($this->change_privacy_access_number) { $_comment=sprintf(_("Dial %s to change"),$this->reject_anonymous_access_number); } else { $_comment=''; } $this->availableGroups['anonymous-reject']=array("Group"=>$this->anonymous-reject, "WEBName" =>sprintf (_("Reject Anonymous")), "WEBComment"=>$_comment, "SubscriberMaySeeIt"=>1, "SubscriberMayEditIt"=>1, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->availableGroups['missed-calls']=array("Group"=>'missed-calls', "WEBName" =>sprintf (_("Email Missed Calls")), "WEBComment"=>'', "SubscriberMaySeeIt"=>1, "SubscriberMayEditIt"=>1, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->availableGroups=array_merge($this->availableGroups, $this->localGroups); $this->pstnChangesAllowed(); $this->smsChangesAllowed(); $this->prepaidChangesAllowed(); $this->tabs=array('identity'=>_('Identity'), 'devices'=>_('Devices'), 'settings'=>_('Settings'), 'diversions'=>_('Forwarding'), 'accept' =>_("DND"), 'contacts'=>_("Contacts"), 'calls'=>_('History'), ); if (in_array("free-pstn",$this->groups)) { if ($this->show_barring_tab || $this->Preferences['show_barring_tab']) { $this->tabs['barring']=_("Barring"); } } if ($this->show_did_tab) { $this->tabs['did']=_("DID"); } if (!$this->isEmbedded() && $this->show_download_tab) { $this->tabs['download'] = $this->show_download_tab; } $this->acceptDailyProfiles=array('127' => _('Every day'), '31' => _('Weekday'), '96' => _('Weekend'), '1' => _('Monday'), '2' => _('Tuesday'), '4' => _('Wednesday'), '8' => _('Thursday'), '16' => _('Friday'), '32' => _('Saturday'), '64' => _('Sunday') ); $this->PhonebookGroups=array( "vip" =>sprintf(_("VIP")), "business" =>sprintf(_("Business")), "coworkers" =>sprintf(_("Coworkers")), "friends" =>sprintf(_("Friends")), "family" =>sprintf(_("Family")) ); $this->diversionType=array( "FUNC"=>sprintf(_("All Calls")), "FNOL"=>sprintf(_("If Not-Online")), "FBUS"=>sprintf(_("If Busy")), "FNOA"=>sprintf(_("If No-Answer")), "FUNV"=>sprintf(_("If Unavailable")) ); $this->diversionTypeUNV=array( "FUNV"=>sprintf(_("If Unavailable")) ); $this->VoicemaildiversionType=array( "FNOL"=>sprintf(_("If Not-Online")), "FBUS"=>sprintf(_("If Busy")), "FNOA"=>sprintf(_("If No-Answer")), "FUNV"=>sprintf(_("If Unavailable")) ); $this->access_numbers=array("FUNC"=>$this->FUNC_access_number, "FNOA"=>$this->FNOA_access_number, "FBUS"=>$this->FBUS_access_number, "FNOL"=>$this->FNOL_access_number ); if ($this->prepaid) { $this->tabs['credit']=_("Credit"); } $_protocol=preg_match("/^(https?:\/\/)/",$_SERVER['SCRIPT_URI'],$m); $this->absolute_url=$m[1].$_SERVER['HTTP_HOST'].$this->url; if ($this->prepaid && $this->show_payments_tab) { $this->tabs['payments']=_("Payments"); } if ($this->show_support_tab) { $this->tabs['support'] = 'Support'; } } function initSoapClient() { dprint("initSoapClient()"); // Sip, Voicemail and Customer ports share same login $this->SOAPurl=$this->soapEngines[$this->sip_engine]['url']; $this->SOAPversion=$this->soapEngines[$this->sip_engine]['version']; if ($this->soapEngines[$this->sip_engine]['enrollment_url']) { $this->enrollment_url =$this->soapEngines[$this->sip_engine]['enrollment_url']; } if ($this->soapEngines[$this->sip_engine]['chat_replication_backend']) { $this->chat_replication_backend = $this->soapEngines[$this->sip_engine]['chat_replication_backend']; } if ($this->soapEngines[$this->sip_engine]['mongo_db']) { $this->mongo_db = $this->soapEngines[$this->sip_engine]['mongo_db']; } if ($this->soapEngines[$this->sip_engine]['sip_settings_api_url']) { $this->sip_settings_api_url =$this->soapEngines[$this->sip_engine]['sip_settings_api_url']; } if (strlen($this->loginCredentials['soapUsername'])) { $this->SOAPlogin = array( "username" => $this->loginCredentials['soapUsername'], "password" => $this->loginCredentials['soapPassword'], "admin" => false ); $this->soapUsername = $this->loginCredentials['soapUsername']; } else { $this->SOAPlogin = array( "username" => $this->soapEngines[$this->sip_engine]['username'], "password" => $this->soapEngines[$this->sip_engine]['password'], "admin" => true, "impersonate" => intval($this->customer) ); $this->soapUsername = $this->soapEngines[$this->sip_engine]['username']; } $this->SoapAuth = array('auth', $this->SOAPlogin , 'urn:AGProjects:NGNPro', 0, ''); //print_r($this->SoapAuth); $this->SOAPloginAdmin = array( "username" => $this->soapEngines[$this->sip_engine]['username'], "password" => $this->soapEngines[$this->sip_engine]['password'], "admin" => true ); $this->SoapAuthAdmin = array('auth', $this->SOAPloginAdmin , 'urn:AGProjects:NGNPro', 0, ''); if (strlen($this->loginCredentials['customer_engine'])) { $this->customer_engine=$this->loginCredentials['customer_engine']; } else if (strlen($this->soapEngines[$this->sip_engine]['customer_engine'])) { $this->customer_engine=$this->soapEngines[$this->sip_engine]['customer_engine']; } else { $this->customer_engine=$this->sip_engine; } if (strlen($this->loginCredentials['voicemail_engine'])) { $this->voicemail_engine=$this->loginCredentials['voicemail_engine']; } else if (strlen($this->soapEngines[$this->sip_engine]['voicemail_engine'])) { $this->voicemail_engine=$this->soapEngines[$this->sip_engine]['voicemail_engine']; } else { $this->voicemail_engine=$this->sip_engine; } if (strlen($this->loginCredentials['enum_engine'])) { $this->enum_engine=$this->loginCredentials['enum_engine']; } else if (strlen($this->soapEngines[$this->sip_engine]['enum_engine'])) { $this->enum_engine=$this->soapEngines[$this->sip_engine]['enum_engine']; } else { $this->enum_engine=$this->sip_engine; } if (strlen($this->loginCredentials['rating_engine'])) { $this->rating_engine=$this->loginCredentials['rating_engine']; } else if (strlen($this->soapEngines[$this->sip_engine]['rating_engine'])) { $this->rating_engine=$this->soapEngines[$this->sip_engine]['rating_engine']; } else { $this->rating_engine=$this->sip_engine; } // overwrite default settings if (strlen($this->soapEngines[$this->sip_engine]['sip_proxy'])) { $this->sip_proxy = $this->soapEngines[$this->sip_engine]['sip_proxy']; } if (strlen($this->soapEngines[$this->sip_engine]['support_company'])) { $this->support_company = $this->soapEngines[$this->sip_engine]['support_company']; } if (strlen($this->soapEngines[$this->sip_engine]['support_web'])) { $this->support_web = $this->soapEngines[$this->sip_engine]['support_web']; } if (strlen($this->soapEngines[$this->sip_engine]['support_email'])) { $this->support_email = $this->soapEngines[$this->sip_engine]['support_email']; } if (strlen($this->soapEngines[$this->sip_engine]['billing_email'])) { $this->billing_email = $this->soapEngines[$this->sip_engine]['billing_email']; } if (strlen($this->soapEngines[$this->sip_engine]['sip_settings_page'])) { $this->sip_settings_page = $this->soapEngines[$this->sip_engine]['sip_settings_page']; } if (strlen($this->soapEngines[$this->sip_engine]['digest_settings_page'])) { $this->digest_settings_page = $this->soapEngines[$this->sip_engine]['digest_settings_page']; } if (strlen($this->soapEngines[$this->sip_engine]['xcap_root'])) { $this->xcap_root = $this->soapEngines[$this->sip_engine]['xcap_root']; } if (strlen($this->soapEngines[$this->sip_engine]['cdrtool_address'])) { $this->cdrtool_address = $this->soapEngines[$this->sip_engine]['cdrtool_address']; } if (strlen($this->soapEngines[$this->sip_engine]['msrp_relay'])) { $this->msrp_relay = $this->soapEngines[$this->sip_engine]['msrp_relay']; } if ($this->soapEngines[$this->sip_engine]['emergency_regions']) { $this->emergency_regions = $this->soapEngines[$this->sip_engine]['emergency_regions']; } if ($this->soapEngines[$this->sip_engine]['pstn_access']) { $this->pstn_access = $this->soapEngines[$this->sip_engine]['pstn_access']; } if ($this->soapEngines[$this->sip_engine]['call_limit']) { $this->platform_call_limit = $this->soapEngines[$this->sip_engine]['call_limit']; } if ($this->soapEngines[$this->sip_engine]['sms_access']) { $this->sms_access = $this->soapEngines[$this->sip_engine]['sms_access']; } if ($this->soapEngines[$this->sip_engine]['voicemail_server']) { $this->voicemail_server = $this->soapEngines[$this->sip_engine]['voicemail_server']; } if ($this->soapEngines[$this->sip_engine]['currency']) { $this->currency = $this->soapEngines[$this->sip_engine]['currency']; } if ($this->soapEngines[$this->sip_engine]['voicemail_access_number']) { $this->voicemail_access_number = $this->soapEngines[$this->sip_engine]['voicemail_access_number']; } if ($this->soapEngines[$this->sip_engine]['FUNC_access_number']) { $this->FUNC_access_number = $this->soapEngines[$this->sip_engine]['FUNC_access_number']; } if ($this->soapEngines[$this->sip_engine]['FNOA_access_number']) { $this->FNOA_access_number = $this->soapEngines[$this->sip_engine]['FNOA_access_number']; } if ($this->soapEngines[$this->sip_engine]['FBUS_access_number']) { $this->FBUS_access_number = $this->soapEngines[$this->sip_engine]['FBUS_access_number']; } if ($this->soapEngines[$this->sip_engine]['FNOL_access_number']) { $this->FNOL_access_number = $this->soapEngines[$this->sip_engine]['FNOL_access_number']; } if ($this->soapEngines[$this->sip_engine]['payment_processor_class']) { $this->payment_processor_class = $this->soapEngines[$this->sip_engine]['payment_processor_class']; } if ($this->soapEngines[$this->sip_engine]['change_privacy_access_number']) { $this->change_privacy_access_number = $this->soapEngines[$this->sip_engine]['change_privacy_access_number']; } if ($this->soapEngines[$this->sip_engine]['check_privacy_access_number']) { $this->check_privacy_access_number = $this->soapEngines[$this->sip_engine]['check_privacy_access_number']; } if ($this->soapEngines[$this->sip_engine]['reject_anonymous_access_number']) { $this->reject_anonymous_access_number = $this->soapEngines[$this->sip_engine]['reject_anonymous_access_number']; } if ($this->soapEngines[$this->sip_engine]['show_directory']) { $this->show_directory = $this->soapEngines[$this->sip_engine]['show_directory']; } if (isset($this->soapEngines[$this->sip_engine]['absolute_voicemail_uri'])) { $this->absolute_voicemail_uri = $this->soapEngines[$this->sip_engine]['absolute_voicemail_uri']; } if (isset($this->soapEngines[$this->sip_engine]['enable_thor'])) { $this->enable_thor=$this->soapEngines[$this->sip_engine]['enable_thor']; } if (isset($this->soapEngines[$this->sip_engine]['sip_accounts_lite'])) { $this->sip_accounts_lite=$this->soapEngines[$this->sip_engine]['sip_accounts_lite']; } if (strlen($this->soapEngines[$this->sip_engine]['timeout'])) { $this->soapTimeout=intval($this->soapEngines[$this->sip_engine]['timeout']); } if (strlen($this->soapEngines[$this->sip_engine]['store_clear_text_passwords'])) { $this->store_clear_text_passwords=$this->soapEngines[$this->sip_engine]['store_clear_text_passwords']; } if (isset($this->soapEngines[$this->sip_engine]['show_download_tab'])) { $this->show_download_tab=$this->soapEngines[$this->sip_engine]['show_download_tab']; } if (strlen($this->soapEngines[$this->sip_engine]['show_barring_tab'])) { $this->show_barring_tab=$this->soapEngines[$this->sip_engine]['show_barring_tab']; } if (isset($this->soapEngines[$this->sip_engine]['disable_extra_groups'])) { $this->disable_extra_groups=$this->soapEngines[$this->sip_engine]['disable_extra_groups']; } if ($this->loginCredentials['templates_path']) { $this->templates_path = $this->loginCredentials['templates_path']; } else if ($this->soapEngines[$this->sip_engine]['templates_path']) { $this->templates_path = $this->soapEngines[$this->sip_engine]['templates_path']; } // Instantiate the SOAP clients // sip $this->SipPort = new $this->soapClassSipPort($this->SOAPurl); $this->SipPort->_options['timeout'] = $this->soapTimeout; $this->SipPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->SipPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); if ($this->showSoapConnectionInfo) { printf ("

%s at %s as %s ",$this->soapClassSipPort,$this->SOAPurl,$this->SOAPurl,$this->soapUsername); } // voicemail $this->SOAPurlVoicemail = $this->soapEngines[$this->voicemail_engine]['url']; $this->SOAPloginVoicemail = array( "username" => $this->soapEngines[$this->voicemail_engine]['username'], "password" => $this->soapEngines[$this->voicemail_engine]['password'], "admin" => true, "impersonate" => intval($this->customer) ); $this->SoapAuthVoicemail = array('auth', $this->SOAPloginVoicemail , 'urn:AGProjects:NGNPro', 0, ''); $this->VoicemailPort = new $this->soapClassVoicemailPort($this->SOAPurlVoicemail); if (strlen($this->soapEngines[$this->voicemail_engine]['timeout'])) { $this->VoicemailPort->_options['timeout'] = intval($this->soapEngines[$this->voicemail_engine]['timeout']); } else { $this->VoicemailPort->_options['timeout'] = $this->soapTimeout; } $this->VoicemailPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->VoicemailPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); if ($this->showSoapConnectionInfo && $this->SOAPurlVoicemail != $this->SOAPurl) { printf ("
%s at %s as %s ",$this->soapClassVoicemailPort,$this->SOAPurlVoicemail,$this->SOAPurlVoicemail,$this->soapEngines[$this->voicemail_engine]['username']); } // enum $this->SOAPurlEnum = $this->soapEngines[$this->enum_engine]['url']; $this->SOAPloginEnum = array( "username" => $this->soapEngines[$this->enum_engine]['username'], "password" => $this->soapEngines[$this->enum_engine]['password'], "admin" => true, "impersonate" => intval($this->customer) ); $this->SoapAuthEnum = array('auth', $this->SOAPloginEnum , 'urn:AGProjects:NGNPro', 0, ''); $this->EnumPort = new $this->soapClassEnumPort($this->SOAPurlEnum); if (strlen($this->soapEngines[$this->enum_engine]['timeout'])) { $this->EnumPort->_options['timeout'] = intval($this->soapEngines[$this->enum_engine]['timeout']); } else { $this->EnumPort->_options['timeout'] = $this->soapTimeout; } $this->EnumPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->EnumPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); if ($this->showSoapConnectionInfo && $this->SOAPurlEnum != $this->SOAPurl) { printf ("
%s at %s as %s ",$this->soapClassEnumPort,$this->SOAPurlEnum,$this->SOAPurlEnum,$this->soapEngines[$this->enum_engine]['username']); } // rating $this->SOAPurlRating = $this->soapEngines[$this->rating_engine]['url']; $this->SOAPloginRating = array( "username" => $this->soapEngines[$this->rating_engine]['username'], "password" => $this->soapEngines[$this->rating_engine]['password'], "admin" => true, "impersonate" => intval($this->customer) ); $this->SoapAuthRating = array('auth', $this->SOAPloginRating , 'urn:AGProjects:NGNPro', 0, ''); $this->RatingPort = new $this->soapClassRatingPort($this->SOAPurlRating); if (strlen($this->soapEngines[$this->rating_engine]['timeout'])) { $this->RatingPort->_options['timeout'] = intval($this->soapEngines[$this->rating_engine]['timeout']); } else { $this->RatingPort->_options['timeout'] = $this->soapTimeout; } $this->RatingPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->RatingPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); if ($this->showSoapConnectionInfo && $this->SOAPurlRating != $this->SOAPurl) { printf ("
%s at %s as %s ",$this->soapClassRatingPort,$this->SOAPurlRating,$this->SOAPurlRating,$this->soapEngines[$this->rating_engine]['username']); } // customer $this->SOAPurlCustomer = $this->soapEngines[$this->customer_engine]['url']; $this->SOAPloginCustomer = array( "username" => $this->soapEngines[$this->customer_engine]['username'], "password" => $this->soapEngines[$this->customer_engine]['password'], "admin" => true ); $this->SoapAuthCustomer = array('auth', $this->SOAPloginCustomer , 'urn:AGProjects:NGNPro', 0, ''); $this->CustomerPort = new $this->soapClassCustomerPort($this->SOAPurlCustomer); if (strlen($this->soapEngines[$this->customer_engine]['timeout'])) { $this->CustomerPort->_options['timeout'] = intval($this->soapEngines[$this->customer_engine]['timeout']); } else { $this->CustomerPort->_options['timeout'] = $this->soapTimeout; } $this->CustomerPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $this->CustomerPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); if ($this->showSoapConnectionInfo && $this->SOAPurlCustomer != $this->SOAPurl) { printf ("
%s at %s as %s ",$this->soapClassCustomerPort,$this->SOAPurlCustomer,$this->SOAPurlCustomer,$this->soapEngines[$this->customer_engine]['username']); } } function getMongoJournalTable() { $this->mongo_table_ro = NULL; $this->mongo_table_rw = NULL; $this->mongo_exception = 'Mongo exception'; if (is_array($this->mongo_db)) { $mongo_uri = $this->mongo_db['uri']; $mongo_replicaSet = $this->mongo_db['replicaSet']; $mongo_database = $this->mongo_db['database']; $mongo_table = $this->mongo_db['table']; try { $mongo_connection = new Mongo("mongodb://$mongo_uri", array("replicaSet" => $mongo_replicaSet)); $mongo_db = $mongo_connection->selectDB($mongo_database); $this->mongo_table_ro = $mongo_db->selectCollection($mongo_table); $this->mongo_table_ro->setSlaveOkay(true); $this->mongo_table_rw = $mongo_db->selectCollection($mongo_table); return true; } catch (MongoException $e) { $this->mongo_exception=$e->getMessage(); return false; } catch (MongoConnectionException $e) { $this->mongo_exception=$e->getMessage(); return false; } catch (Exception $e) { $this->mongo_exception=$e->getMessage(); return false; } } return false; } function getAccount($account) { dprint("getAccount($account, engine=$this->sip_engine)"); list($username,$domain)=explode("@",trim($account)); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getAccount(array("username" =>$username,"domain" =>$domain)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } //print "

";
         dprint_r($result);
         $this->owner     = $result->owner;
 
         if (!is_array($result->properties))   $result->properties=array();
         if (!is_array($result->groups))       $result->groups=array();
 
         if (!$result->quota) $result->quota=0;
 
         foreach ($result->properties as $_property) {
             $this->Preferences[$_property->name]=$_property->value;
         }
 
         //dprint_r($this->Preferences);
 
         if (!$this->Preferences['language']) {
             $this->Preferences['language'] ='en';
         }
 
         if ( $this->Preferences['blocked_by'] && !in_array("blocked",$result->groups)) {
             $this->Preferences['blocked_by']='';
         }
 
         $this->username       = $result->id->username;
         $this->domain         = $result->id->domain;
         $this->password       = $result->password;
         $this->firstName      = $result->firstName;
         $this->lastName       = $result->lastName;
         $this->rpid           = $result->rpid;
         $this->owner          = $result->owner;
         $this->timezone       = $result->timezone;
         $this->email          = $result->email;
         $this->groups         = $result->groups;
         $this->createDate     = $result->createDate;
         $this->web_password   = $this->Preferences['web_password'];
         $this->quickdial = $result->quickdialPrefix;
         $this->timeout   = intval($result->timeout);
         $this->quota     = $result->quota;
         $this->prepaid   = intval($result->prepaid);
         $this->region    = $result->region;
 
         $this->account   = $this->username."@".$this->domain;
         $this->fullName  = $this->firstName." ".$this->lastName;
         $this->name      = $this->firstName; // used by smarty
 
         $this->yuibikey         = $result->Preferences['yubikey'];
 
         if ($this->soapEngines[$this->sip_engine]['call_limit']) {
             if ($result->callLimit) {
                 $this->callLimit   = $result->callLimit;
             } else  {
                 $this->callLimit = '';
             }
         }
 
         if ($this->soapEngines[$this->sip_engine]['ip_access_list']) {
             if (is_array($result->acl) and count($result->acl)) {
                 foreach (array_keys($result->acl) as $key) {
                     $this->ip_access_list .= sprintf("%s/%s ",$result->acl[$key]->ip, $result->acl[$key]->mask);
                 }
                 $this->ip_access_list = trim($this->ip_access_list);
             } else  {
                 $this->ip_access_list = $this->soapEngines[$this->sip_engine]['ip_access_list'];
             }
         }
 
         $this->sipId=array("username" => $this->username,
                            "domain" => $this->domain
                            );
 
         if (!$this->timeout) {
             $this->timeoutWasNotSet=1;
             $this->timeout=intval($this->FNOA_timeoutDefault);
         }
 
         if ($this->timeout > 900 ) {
             $this->timeoutWasNotSet=1;
             $this->timeout=intval(900);
         }
 
         $this->getOwnerSettings($this->owner);
 
         $this->getDomainOwner($this->domain);
 
         $this->getMobileNumber();
 
         if ($this->append_domain_to_xcap_root) {
         	$this->xcap_root     = rtrim($this->xcap_root,'/')."@".$this->domain."/";
         }
 
         $this->result    = $result;
 
     }
 
     function showAccount() {
         dprint('showAccount()');
 
         if (!$this->account) {
             print "";
             print _("Error: SIP Account information cannot be retrieved. ");
             return 0;
             print "";
         }
 
         print "
         
         ";
 
         $this->showHeader();
 
         $this->chapterTableStart();
 
     	$this->showAboveTabs();
         $this->showTabs();
     	$this->showUnderTabs();
 
         $this->showTitleBar();
 
         if (!array_key_exists($this->tab,$this->tabs)) $this->tab="settings";
 
 
         // show tab
         $tabFunctionName='show'.ucfirst($this->tab).'Tab';
 
         $this->$tabFunctionName();
 
         $this->showFooter();
 
     	$this->chapterTableStop();
     }
 
     function getDomainOwner ($domain='') {
         dprint("getdomainOwner($domain)");
 
         if (!$domain) return;
         // Filter
         $filter=array('domain'    => $domain);
 
         // Range
         $range=array('start' => 0,
                      'count' => 1
                      );
 
         $orderBy = array('attribute' => 'changeDate',
                          'direction' => 'DESC'
                          );
 
         // Compose query
         $Query=array('filter'     => $filter,
                      'orderBy' => $orderBy,
                      'range'   => $range
                      );
 
         //dprint_r($Query);
 
         // Call function
         $this->SipPort->addHeader($this->SoapAuth);
         $result     = $this->SipPort->getDomains($Query);
 
         if (PEAR::isError($result)) {
             $error_msg  = $result->getMessage();
             $error_fault= $result->getFault();
             $error_code = $result->getCode();
             printf ("

Error %s: %s (%s): %s",$this->SoapEngine->SOAPurl,$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { if ($result->domains[0]) { $this->reseller = $result->domains[0]->reseller; $this->customer = $result->domains[0]->customer; } } } function getMobileNumber() { //dprint('getMobileNumber()'); $this->mobile_number=''; if ($this->Preferences['mobile_number']) { $this->mobile_number=$this->Preferences['mobile_number']; } else if ($this->owner_information['mobile']) { $this->mobile_number=$this->owner_information['mobile']; } } function setLanguage() { dprint("setLanguage()"); if ($this->login_type == 'reseller' || $this->login_type == 'customer') { $lang = $this->ResellerLanguage; } else if ($this->login_type == 'subscriber') { if (!$this->Preferences['language']) { foreach (array_keys($this->languages) as $_lang) { if ($this->languages[$_lang]['timezone'] == $this->timezone) { $lang=$_lang; break; } } } $lang = $this->Preferences['language']; } else { $lang = "en"; } //print("Set language to $lang"); $this->changeLanguage($lang); } function getOwnerSettings($owner='') { dprint("getOwnerSettings($owner)"); if (!$owner) { return false; } $this->CustomerPort->addHeader($this->SoapAuthCustomer); $result = $this->CustomerPort->getAccount($owner); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (CustomerPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $this->owner_information=array( "username" => $result->username, "password" => $result->password, "firstName" => $result->firstName, "lastName" => $result->lastName, "organization" => $result->organization, "timezone" => $result->timezone, "address" => $result->address, "billingAddress" => $result->billingAddress, "city" => $result->city, "state" => $result->state, "country" => $result->country, "postcode" => $result->postcode, "tel" => $result->tel, "enum" => $result->enum, "mobile" => $result->mobile, "fax" => $result->fax, "email" => $result->email, "web" => $result->web ); //dprint_r($this->owner_information); } function getAliases() { // Get Aliases dprint("getAliases()"); $this->aliases=array(); $this->SipPort->addHeader($this->SoapAuth); // Filter $filter=array('targetUsername' => $this->username, 'targetDomain' => $this->domain ); // Range $range=array('start' => 0, 'count' => 20 ); // Order $orderBy = array('attribute' => 'aliasUsername', 'direction' => 'ASC' ); // Compose query $Query=array('filter' => $filter, 'orderBy' => $orderBy, 'range' => $range ); // Call function $result = $this->SipPort->getAliases($Query); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } //dprint_r($result); foreach ($result->aliases as $_alias) { $this->aliases[]=$_alias->id->username.'@'.$_alias->id->domain; } } function getRatingEntityProfiles() { dprint("getRatingEntityProfiles()"); $this->EntityProfiles=array(); $this->RatingPort->addHeader($this->SoapAuthRating); $entity="subscriber://".$this->username."@".$this->domain; $result = $this->RatingPort->getEntityProfiles($entiry); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (RatingPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $this->EntityProfiles=$result; } function setAliases() { dprint("setAliases()"); $aliases_new=$_REQUEST['aliases']; $this->getAliases(); $aliases_old=$this->aliases; $addAliases = array_unique(array_diff($aliases_new,$aliases_old)); $deleteAliases = array_unique(array_diff($aliases_old,$aliases_new)); foreach ($addAliases as $_alias) { $_alias=trim(strtolower($_alias)); if (!preg_match("/^[a-z0-9-_.@]+$/i",$_alias)) continue; $els=explode("@",$_alias); if (count($els) ==1 ) { $_alias_username=$_alias; $_alias_domain=$this->domain; } else if (count($els) ==2) { $_alias_username=$els[0]; $_alias_domain=$this->domain; } else { continue ; } $_aliasObject=array("id"=>array("username"=>strtolower($_alias_username), "domain"=>strtolower($_alias_domain) ), "owner"=>intval($this->owner), "target"=>$this->sipId ) ; $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->addAlias($_aliasObject); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } foreach ($deleteAliases as $_alias) { $_alias=trim($_alias); if (!strlen($_alias)) continue; $els=explode("@",$_alias); if (count($els) ==1 ) { $_alias_username=$_alias; $_alias_domain=$this->domain; } else if (count($els) == 2) { $_alias_username=$els[0]; $_alias_domain=$els[1]; } else { continue ; } $_aliasObject=array("username"=>$_alias_username, "domain" =>$_alias_domain ); dprint_r($_aliasObject); dprint("deleteAlias"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->deleteAlias($_aliasObject); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } unset($this->aliases); } function getVoicemail () { dprint("getVoicemail()"); $this->VoicemailPort->addHeader($this->SoapAuthVoicemail); $result = $this->VoicemailPort->getAccount($this->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "2000" && $error_fault->detail->exception->errorcode != "1010") { printf ("

Error (VoicemailPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { return true; } } if (!$result->mailbox) { dprint ("No voicemail account found"); return false; } $this->voicemail['Mailbox'] = $result->mailbox; $this->voicemail['Password'] = $result->password; $this->voicemail['Name'] = $result->name; $this->voicemail['Email'] = $result->email; $this->voicemail['Info'] = $result->info; $this->voicemail['Options'] = $result->options; $this->voicemail['Account'] = $result->mailbox.'@'.$this->voicemail_server; // used by template system $this->voicemailMailbox = $result->mailbox; //dprint_r($this->voicemail); return true; } function showTitleBar() { print "

"; printf (("%s <sip:%s@%s>"),$this->fullName,$this->username,$this->domain); print " "; if ($this->login_type == 'subscriber' && !$this->isEmbedded()) { print ""; print _("Logout"); print ""; } else { if ($this->enable_thor) { print " "; if ($this->isEmbedded()) { print " "; print _("Home Node"); } else { print ""; print _("SIP Thor Node"); print ""; } if ($this->homeNode=getSipThorHomeNode($this->account,$this->sip_proxy)) { printf (" %s",$this->homeNode); } else { print " "; print _("Unknown"); print ""; } } } print "
"; } function getDivertTargets () { dprint("getDivertTargets()"); $this->divertTargets[] = array("name" => _("No diversion"), "value" => "", "description" => "Disabled" ); if ($this->voicemail['Account']) { $vmf=$this->getVoicemailForwarding(); if (is_array($vmf)) { $this->divertTargets[]=$vmf; } } if ($this->owner) { if (in_array("free-pstn",$this->groups)) { if ($this->owner_information['tel']) { $tel = preg_replace("/[^\d+]/", "", $this->owner_information['tel']); $tel_enum = str_replace("+", "00", $tel); $telf = $tel_enum . "@" . $this->domain; if (!$seen[$tel_enum] && !in_array($tel_enum,$this->enums)) { $this->divertTargets[]=array("name" => sprintf (_("Tel %s"),$tel), "value" => $telf, "description" => "Tel"); } $seen[$tel_enum]++; } if ($this->owner_information['enum']) { $tel = preg_replace("/[^\d+]/", "", $this->owner_information['enum']); $tel_enum = str_replace("+", "00", $tel); $telf = $tel_enum . "@" . $this->domain; if (!$seen[$tel_enum] && !in_array($tel_enum,$this->enums)) { $this->divertTargets[]=array("name" => sprintf (_("Tel %s"),$tel), "value" => $telf, "description" => "ENUM"); } $seen[$tel_enum]++; } } } if ($this->mobile_number) { $tel = preg_replace("/[^\d+]/", "", $this->mobile_number); $tel_enum = str_replace("+", "00", $tel); $telf = $tel_enum . "@" . $this->domain; if (!$seen[$tel_enum] && !in_array($tel_enum,$this->enums)) { $this->divertTargets[] = array("name" => sprintf (_("Mobile %s"),$tel), "value" => $telf, "description" => "Mobile" ); } $seen[$tel_enum]++; } $this->divertTargets[]=array("name" => sprintf (_("Other")), "value" => "", "description" => "Other" ); //print_r($this->divertTargets); } function pstnChangesAllowed() { dprint("pstnChangesAllowed()"); if ($this->login_type == 'subscriber') { $this->pstn_changes_allowed = false; return; } else { // for a reseller we need to check if a subaccount is allowed if ($this->loginCredentials['customer'] == $this->loginCredentials['reseller']) { if ($this->resellerProperties['pstn_access']) { dprint("is reseller"); $this->pstn_changes_allowed = true; } return; } else if ($this->customerImpersonate == $this->loginCredentials['reseller']) { if ($this->resellerProperties['pstn_access']) { dprint("impersonate reseller"); $this->pstn_changes_allowed = true; } return; } else if ($this->resellerProperties['pstn_access'] && $this->customerProperties['pstn_access']) { $this->pstn_changes_allowed = true; return; } } $this->pstn_changes_allowed = false; return; } function smsChangesAllowed() { dprint("smsChangesAllowed()"); if ($this->login_type == 'subscriber') { $this->sms_changes_allowed = false; return; } else { // for a reseller we need to check if a subaccount is allowed if ($this->loginCredentials['customer'] == $this->loginCredentials['reseller']) { if ($this->resellerProperties['sms_access']) { dprint("is reseller"); $this->sms_changes_allowed = true; } return; } else if ($this->customerImpersonate == $this->loginCredentials['reseller']) { if ($this->resellerProperties['sms_access']) { dprint("impersonate reseller"); $this->sms_changes_allowed = true; } return; } else if ($this->resellerProperties['sms_access'] && $this->customerProperties['sms_access']) { $this->sms_changes_allowed = true; return; } } $this->sms_changes_allowed = false; return; } function prepaidChangesAllowed() { dprint("prepaidChangesAllowed()"); if ($this->login_type == 'subscriber') { $this->prepaid_changes_allowed = false; return; } else { // for a reseller we need to check if a subaccount is allowed if ($this->loginCredentials['customer'] == $this->loginCredentials['reseller']) { dprint("is reseller"); if ($this->resellerProperties['prepaid_changes']) { $this->prepaid_changes_allowed = true; } return; } else if ($this->customerImpersonate == $this->loginCredentials['reseller']) { dprint("impersonate reseller"); if ($this->resellerProperties['prepaid_changes']) { $this->prepaid_changes_allowed = true; } return; } else if ($this->resellerProperties['prepaid_changes'] && $this->customerProperties['prepaid_changes']) { $this->prepaid_changes_allowed = true; return; } } $this->prepaid_changes_allowed = false; return; } function getCustomerSettings () { dprint("getCustomerSettings()"); if (!$this->loginCredentials['customer']) return; $id=$this->loginCredentials['customer']; $this->CustomerPort->addHeader($this->SoapAuthCustomer); $result = $this->CustomerPort->getAccount(intval($this->loginCredentials['customer'])); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (CustomerPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } foreach ($result->properties as $_property) { $this->customerProperties[$_property->name]=$_property->value; } $this->customerImpersonate=$result->impersonate; //dprint_r($this->customerProperties); } function getResellerSettings () { dprint("getResellerSettings()"); $this->logoFile = $this->getFileTemplate("logo","logo"); $this->headerFile = $this->getFileTemplate("header.phtml"); $this->footerFile = $this->getFileTemplate("footer.phtml"); $this->cssFile = $this->getFileTemplate("main.css"); if (!$this->reseller) { if ($this->pstn_access) { $this->availableGroups['free-pstn'] = array("Group"=>"free-pstn", "WEBName" => sprintf(_("PSTN Access")), "WEBComment"=> sprintf(_("Caller-ID")), "SubscriberMayEditIt" => 0, "SubscriberMaySeeIt" => 1, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->availableGroups['anonymous']=array("Group"=>"anonymous", "WEBName" =>sprintf (_("PSTN Privacy")), "WEBComment"=>$_comment, "SubscriberMaySeeIt"=>1, "SubscriberMayEditIt"=>1, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->availableGroups['rate-on-net'] = array("Group"=>"rate-on-net", "WEBName" =>sprintf(_("Rate on net")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>0, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); if ($this->sms_access) { $this->availableGroups['sms'] = array("Group"=>"sms", "WEBName" =>sprintf(_("Mobile SMS")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>1, "ResellerMayEditIt"=>0, "ResellerMaySeeIt"=>1 ); } if ($this->require_proof_of_identity) { $this->availableGroups['payments'] = array("Group"=>"payments", "WEBName" =>sprintf(_("CC Payments")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>0, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); } } return true; } $this->CustomerPort->addHeader($this->SoapAuthCustomer); $result = $this->CustomerPort->getAccount(intval($this->reseller)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (CustomerPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } foreach ($result->properties as $_property) { $this->resellerProperties[$_property->name]=$_property->value; } $this->resellerProperties['language'] = $result->language; $this->resellerProperties['timezone'] = $result->timezone; // overwrite settings from soap engine if ($this->resellerProperties['sip_proxy']) { $this->sip_proxy = $this->resellerProperties['sip_proxy']; } if ($this->resellerProperties['store_clear_text_passwords']) { $this->store_clear_text_passwords = $this->resellerProperties['store_clear_text_passwords']; } if ($this->resellerProperties['support_company']) { $this->support_company = $this->resellerProperties['support_company']; } if ($this->resellerProperties['support_web']) { $this->support_web = $this->resellerProperties['support_web']; } if ($this->resellerProperties['support_email']) { $this->support_email = $this->resellerProperties['support_email']; } if ($this->resellerProperties['billing_email']) { $this->billing_email = $this->resellerProperties['billing_email']; } if (!$this->billing_email) { $this->billing_email=$this->support_email; } if ($this->resellerProperties['sip_settings_page']) { $this->sip_settings_page = $this->resellerProperties['sip_settings_page']; } if ($this->resellerProperties['digest_settings_page']) { $this->digest_settings_page = $this->resellerProperties['digest_settings_page']; } if ($this->resellerProperties['xcap_root']) { $this->xcap_root = rtrim($this->resellerProperties['xcap_root'],'/'); if ($this->append_domain_to_xcap_root) { $this->xcap_root .= "@".$this->domain."/"; } } if ($this->resellerProperties['cdrtool_address']) { $this->cdrtool_address = $this->resellerProperties['cdrtool_address']; } if ($this->resellerProperties['msrp_relay']) { $this->msrp_relay = $this->resellerProperties['msrp_relay']; } if (isset($this->resellerProperties['voicemail_server'])) { $this->voicemail_server = $this->resellerProperties['voicemail_server']; } if (isset($this->resellerProperties['voicemail_access_number'])) { $this->voicemail_access_number = $this->resellerProperties['voicemail_access_number']; } if (isset($this->resellerProperties['currency'])) { $this->currency = $this->resellerProperties['currency']; } if (isset($this->resellerProperties['FUNC_access_number'])) { $this->FUNC_access_number = $this->resellerProperties['FUNC_access_number']; } if (isset($this->resellerProperties['FNOA_access_number'])) { $this->FNOA_access_number = $this->resellerProperties['FNOA_access_number']; } if (isset($this->resellerProperties['FBUS_access_number'])) { $this->FBUS_access_number = $this->resellerProperties['FBUS_access_number']; } if (isset($this->resellerProperties['FNOL_access_number'])) { $this->FNOL_access_number = $this->resellerProperties['FNOL_access_number']; } if (isset($this->resellerProperties['payment_processor_class'])) { $this->payment_processor_class = $this->resellerProperties['payment_processor_class']; } if (isset($this->resellerProperties['change_privacy_access_number'])) { $this->change_privacy_access_number = $this->resellerProperties['change_privacy_access_number']; } if (isset($this->resellerProperties['check_privacy_access_number'])) { $this->check_privacy_access_number = $this->resellerProperties['check_privacy_access_number']; } if (isset($this->resellerProperties['reject_anonymous_access_number'])) { $this->reject_anonymous_access_number = $this->resellerProperties['reject_anonymous_access_number']; } if (isset($this->resellerProperties['absolute_voicemail_uri'])) { $this->absolute_voicemail_uri = $this->resellerProperties['absolute_voicemail_uri']; } if (isset($this->resellerProperties['pstn_access'])) { $this->pstn_access = $this->resellerProperties['pstn_access']; } if (isset($this->resellerProperties['sms_access'])) { $this->sms_access = $this->resellerProperties['sms_access']; } if ($this->pstn_access) { $this->availableGroups['free-pstn'] = array("Group"=>"free-pstn", "WEBName" => sprintf(_("PSTN Access")), "WEBComment"=> sprintf(_("Caller-ID")), "SubscriberMayEditIt" => "0", "SubscriberMaySeeIt" => 1, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); $this->availableGroups['anonymous']=array("Group"=>"anonymous", "WEBName" =>sprintf (_("PSTN Privacy")), "WEBComment"=>$_comment, "SubscriberMaySeeIt"=>1, "SubscriberMayEditIt"=>1, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); } $this->availableGroups['rate-on-net'] = array("Group"=>"rate-on-net", "WEBName" =>sprintf(_("Rate on net")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>0, "ResellerMayEditIt"=>1, "ResellerMaySeeIt"=>1 ); if ($this->sms_access) { $this->availableGroups['sms'] = array("Group"=>"sms", "WEBName" =>sprintf(_("Mobile SMS")), "SubscriberMayEditIt"=>0, "SubscriberMaySeeIt"=>1, "ResellerMayEditIt"=>0, "ResellerMaySeeIt"=>1 ); } } function getDiversions() { dprint("getDiversions()"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getCallDiversions($this->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } //print_r($result); reset($this->diversionType); foreach(array_keys($this->diversionType) as $condition) { $uri=$result->$condition; if (($uri == "" || $uri == "voice-mailbox") && $this->absolute_voicemail_uri) { $uri = $this->voicemail['Account']; } else if ($uri == "voice-mailbox") { $uri = ""; } if (preg_match("/^(sip:|sips:)(.*)$/i",$uri,$m)) { $uri=$m[2]; } $this->diversions[$condition]=$uri; } //print_r($this->diversions); } function getDeviceLocations() { dprint("getDeviceLocations()"); require_once($this->SipUAImagesFile); $this->userAgentImages = $userAgentImages; $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getSipDeviceLocations(array($this->sipId)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { foreach ($result[0]->locations as $locationStructure) { $contact=$locationStructure->address.":".$locationStructure->port; if ($locationStructure->publicAddress) { $publicContact=$locationStructure->publicAddress.":".$locationStructure->publicPort; } else { $publicContact=$contact; } $this->locations[]=array("contact" => $contact, "publicContact" => $publicContact, "expires" => $locationStructure->expires, "user_agent" => $locationStructure->userAgent, "transport" => $locationStructure->transport ); } } } function getVoicemailForwarding () { dprint("getVoicemailForwarding()"); if (!$this->voicemail['Account']) { return; } if ($this->absolute_voicemail_uri) { $value=$this->voicemail['Account']; } else { $value=""; } return array("name" => sprintf (_("Voice Mailbox")), "value" => $value, "description" => "Voicemail"); } function showAboveTabs() { print "

"; print "
"; } function showTabs() { print "
"; if ($this->isEmbedded()) { print $this->embedded_img;; } print "
    "; $items=0; while (list($k,$v)= each($this->tabs)) { if ($this->tab==$k) { $_class='active selected_tab'; } else { $_class='tabs'; } print "
  • $v
  • "; } print "
"; print "
"; } function showUnderTabs() { print "
"; print "
"; } function addInvoice() { // called after CC payment sucessfull } function showPaymentsTab() { if (!$this->show_payments_tab) { return false; } if ($this->login_type == 'subscriber' && in_array("blocked",$this->groups)) { return false; } if ($_REQUEST['task'] == 'showprices') { $chapter=sprintf(_("Price list")); $this->showChapter($chapter); include($this->pstn_termination_price_page); return true; } $chapter=sprintf(_("Payments")); $this->showChapter($chapter); if (!$this->owner) { print "

"; print _("You must set the Owner to enable Credit Card Payments. "); print " "; return false; } $this->getBalanceHistory(); $today_summary = $this->getTodayBalanceSummary(); if ($today_summary['credit'] >= $this->max_credit_per_day) { print " "; if ($account->login_type!='subscriber') { print "

"; printf ("Daily Credit Exceeded"); } else { print _("Page Not Available"); $log=sprintf("CC transaction is not allowed from %s for %s (%s)",$_SERVER['REMOTE_ADDR'],$account->account,$this->fraud_reason); syslog(LOG_NOTICE, $log); } print " "; return false; } if (!count($this->balance_history)) { $this->first_transaction=true; } else { $this->first_transaction=false; } print " "; printf (_("Calling to telephone numbers is possible at the costs set forth in the Price List. "),$this->url); print "

"; print _("You can purchase credit with a Credit Card. "); print " "; if ($this->require_proof_of_identity) { if ($this->login_type == 'subscriber') { if (!in_array("payments",$this->groups)) { $this->showIdentityProof(); } } else { $this->showIdentityProof(); } if (!in_array("payments",$this->groups)) { return false; } } $payment_processor = new $this->payment_processor_class($this); if ($payment_processor->fraudDetected()) { $chapter=sprintf(_("Payments")); $this->showChapter($chapter); print " "; if ($account->login_type!='subscriber') { print "

"; printf ("%s",$this->fraud_reason); } else { print _("Page Not Available"); $log=sprintf("CC transaction is not allowed from %s for %s (%s)",$_SERVER['REMOTE_ADDR'],$account->account,$this->fraud_reason); syslog(LOG_NOTICE, $log); } print " "; return false; } $credit_amount = 20; $basket = array('pstn_credit'=>array('price' => $credit_amount, 'description' => _('Prepaid Credit'), 'unit' => 'credit', 'duration' => 'N/A', 'qty' => 1 ) ); $payment_processor->doDirectPayment($basket); if ($payment_processor->transaction_results['success']) { // add PSTN credit $this->addBalanceReseller($credit_amount,sprintf("CC transaction %s",$payment_processor->transaction_results['id'])); } if ($this->first_transaction && $payment_processor->make_credit_checks) { // block account temporary to check the user $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->removeFromGroup(array("username" => $this->username,"domain"=> $this->domain),"free-pstn"); } } function showIdentityProof () { $max_file_size=1024000; $this->db = new DB_CDRTool(); $chapter=sprintf(_("Proof of Identity")); $this->showChapter($chapter); if ($_REQUEST['task'] == 'upload') { if (!$_FILES['tmpfile']['tmp_name']) { print ""; printf (_("Error: Please specify a file")); print ""; } else if (!$_REQUEST['name']) { print ""; printf (_("Error: Please enter the name printed on the Credit Card")); print ""; } else if (!preg_match("/^\d{4}$/",$_REQUEST['last_digits'])) { print ""; printf (_("Error: Last digits must be numeric")); print ""; } else if (!preg_match("/^\+[1-9][0-9]{7,14}$/",$_REQUEST['mobile_number'])) { print ""; printf (_("Error: Mobile Number must be in international format starting with +")); print ""; } else if ($_FILES['tmpfile']['size']['size'] > $max_file_size) { print ""; printf (_("Error: Maximum file size is %s"),$max_file_size); print ""; } else { $fp=fopen($_FILES['tmpfile']['tmp_name'], "r"); $content=fread($fp, $_FILES['tmpfile']['size']); fclose($fp); $query=sprintf("insert into subscriber_docs ( `name`, `username`, `domain`, `document`, `file_content`, `file_name`, `file_size`, `file_type`, `file_date`, `last_digits`, `mobile_number` ) values ( '%s', '%s', '%s', 'identity', '%s', '%s', '%s', '%s', NOW(), '%s', '%s' )", addslashes($_REQUEST['name']), addslashes($this->username), addslashes($this->domain), addslashes($content), addslashes($_FILES['tmpfile']['name']), addslashes($_FILES['tmpfile']['size']), addslashes($_FILES['tmpfile']['type']), addslashes($_REQUEST['last_digits']), addslashes($_REQUEST['mobile_number']) ); if (!$this->db->query($query)) { print ""; printf ("Error: Failed to save identity document %s (%s)", $this->db->Error,$this->db->Errno); print ""; } // send mail include_once('Mail.php'); include_once('Mail/mime.php'); $subject=sprintf ("%s requested CC Payments",$this->account); $hdrs = array( 'From' => $this->email, 'Subject' => $subject ); $crlf = "\n"; $mime = new Mail_mime($crlf); $mime->setTXTBody($subject); $mime->setHTMLBody($subject); $mime->addAttachment($content, $_FILES['tmpfile']['type'],$_FILES['tmpfile']['name'],'false'); $body = $mime->get(); $hdrs = $mime->headers($hdrs); $mail =& Mail::factory('mail'); $mail->send($this->billing_email, $hdrs, $body); } } if ($this->login_type != 'subscriber' && $_REQUEST['task'] == 'delete_identity_proof' && $_REQUEST['confirm']) { $query=sprintf("delete from subscriber_docs where username = '%s' and domain = '%s' and document = 'identity'", addslashes($this->username), addslashes($this->domain) ); if (!$this->db->query($query)) { print ""; printf ("Error deleting record: %s (%s)", $this->db->Error,$this->db->Errno); print ""; } } $query=sprintf("select * from subscriber_docs where username = '%s' and domain = '%s' and document = 'identity'", addslashes($this->username), addslashes($this->domain) ); if (!$this->db->query($query)) { print ""; printf ("Error for database query: %s (%s)", $this->db->Error,$this->db->Errno); print ""; } if ($this->db->num_rows()) { print " "; if (!in_array("payments",$this->groups)) { print "

"; print _("Credit Card payments will be activated after your identity is verified. "); } print "

"; print " "; printf ("", _("Name"), _("Document"), _("Type"), _("Size"), _("Date"), _("Last digits"), _("Mobile Number") ); if ($this->login_type != 'subscriber') { print ""; } printf (""); $this->db->next_record(); $download_url=$this->url.'&action=export_identity_proof'; printf ("", $this->db->f('name'), $download_url, $this->db->f('file_name'), $this->db->f('file_type'), number_format($this->db->f('file_size')/1024,2), $this->db->f('file_date'), $this->db->f('last_digits'), $this->db->f('mobile_number') ); if ($this->login_type != 'subscriber') { if ($_REQUEST['task'] == 'delete_identity_proof' && !$_REQUEST['confirm']){ $delete_url=$this->url.'&tab=payments&task=delete_identity_proof&confirm=1'; printf ("",$delete_url,_("Confirm")); } else { $delete_url=$this->url.'&tab=payments&task=delete_identity_proof'; printf ("",$delete_url,$this->delete_img); } } printf (""); print "
%s%s%s%s%s%s%s"; print _("Actions"); print "
%s%s %s %s KB %s%s%s%s%s
"; } else { print "

"; print _("Credit Card payments are available only to verified customers. "); print "

"; printf (_("To become verified, upload a copy of your passport or driving license that matches the Credit Card owner. "),$this->billing_email, $this->account, $this->billing_email); print "

"; printf (_("This copy will be kept on your profile until the credit card transaction has been approved. ")); print " "; print "

url method='post' enctype='multipart/form-data'> "; print " "; print _("Name printed on the Credit Card"); print " "; printf ("",$_REQUEST['name']); print " "; print " "; print _("Scanned copy of your Passport or Driver License"); print " "; printf (""); print " "; if (in_array("free-pstn",$this->groups)) { print " "; print _("Mobile Number"); print " "; printf(" %s",$_REQUEST['mobile_number'],_("International format starting with +")); print " "; } print " "; print _("Last 4 digits on your Credit Card"); print " "; printf("",$_REQUEST['last_digits']); print " "; print " "; print "
"; } } function exportIdentityProof() { $this->db = new DB_CDRTool(); $query=sprintf("select * from subscriber_docs where username = '%s' and domain = '%s' and document = 'identity'", addslashes($this->username), addslashes($this->domain) ); if (!$this->db->query($query)) { print ""; printf ("Error for database query: %s (%s)", $this->db->Error,$this->db->Errno); print ""; } if ($this->db->num_rows()) { $this->db->next_record(); $h=sprintf("Content-type: %s",$this->db->f('file_type')); Header($h); $h=sprintf("Content-Disposition: attachment; filename=%s",$this->db->f('file_name')); Header($h); $h=sprintf("Content-Length: %s",$this->db->f('file_size')); Header($h); $this->db->p('file_content'); } } function showIdentityTab() { $this->getEnumMappings(); $this->getAliases(); $chapter=sprintf(_("SIP Account")); $this->showChapter($chapter); print "
"; /* print " "; */ print " "; print " "; print " "; if ($this->xcap_root) { print " "; } print "
"; print _("SIP Address"); print " sip:$this->account
"; print _("Full Name"); print " $this->fullName
"; print _("Username"); print " $this->username
"; print _("Domain/Realm"); print " $this->domain
"; print _("Outbound Proxy"); print " $this->sip_proxy
"; print _("XCAP Root"); print " $this->xcap_root
"; if ($this->pstn_access && $this->rpid) { $chapter=sprintf(_("PSTN")); $this->showChapter($chapter); print "
"; $t=0; foreach($this->enums as $e) { $t++; $rr=floor($t/2); $mod=$t-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print " "; } print "
"; print _("Caller-ID"); print " $this->rpid
"; print _("Phone Number"); print " $e
"; } $chapter=sprintf(_("Aliases")); $this->showChapter($chapter); print "
"; printf (_("You may create new aliases for incoming calls")); printf ("
"); $t=0; print "
"; foreach($this->aliases as $a) { $t++; $rr=floor($t/2); $mod=$t-$rr*2; if ($mod ==0) { $_class='even'; } else { $_class='odd'; } print "
"; } print "
"; print "
"; print '
'; print $this->hiddenElements; print "
"; if (!$this->isEmbedded() && $this->show_tls_section) { if ($this->enrollment_url) { include($this->enrollment_configuration); if (is_array($enrollment)) { $chapter=sprintf(_("TLS Certificate")); $this->showChapter($chapter); print " "; print _("X.509 Format"); printf (" %s.crt ",$this->url, $this->account); /* print " "; print _("PKCS#12 store format"); printf (" %s.p12 ",$this->url, $this->account); */ } } } print "
"; print "
"; if ($this->email) { printf (_("Email SIP Account information to %s"),$this->email); print " "; } if ($this->sip_settings_page && $this->login_type != 'subscriber') { print "

"; printf (_("Login using SIP credentials at %s"),$this->sip_settings_page,$this->sip_settings_page); } print "

"; print $this->hiddenElements; print "
"; } function showDownloadTab() { $chapter=sprintf(_("SIP Client")); $this->showChapter($chapter); print " "; $this->render_download_applet(); print " "; } function showDIDTab() { if (class_exists($this->did_processor_class)) { $did_processor = new $this->did_processor_class(); } if (!$_REQUEST['ddi_action']) { $chapter=sprintf(_("Registered Numbers")); $this->showChapter($chapter); print " "; $numbers=$did_processor->getOrders($this->account); if (count($numbers)) { print ""; printf (""); foreach (array_keys($numbers) as $_number) { $t++; $rr=floor($t/2); $mod=$t-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } $form=sprintf(" "; $form.=$this->hiddenElements; $form.=sprintf ("",$_number); $form.=sprintf (""); $form.=sprintf (""); printf ("",$_number,$numbers[$_number]['country_name'],$numbers[$_number]['did_expire_date_gmt'],$numbers[$_number]['order_id'],$form); } print "
NumberCountryExpire DateOrderAction
+%s%s%s%s
%s
"; } print " "; } if ($prefixes = $did_processor->getPrefixes()) { if ($_REQUEST['ddi_action'] == 'register' && $_REQUEST['prefix'] && $_REQUEST['period']) { $chapter=sprintf(_("Register New Number")); $this->showChapter($chapter); print " "; $total=$prefixes[$_REQUEST['prefix']]['setup']+$prefixes[$_REQUEST['prefix']]['monthly']* $_REQUEST['period']; $basket = array('ddi_number' => array('price' => sprintf("%.2f",$total), 'description' => sprintf(_('Telephone Number (+%s %s) for %d months'),$_REQUEST['prefix'],$prefixes[$_REQUEST['prefix']]['country_name'],$_REQUEST['period']), 'unit' => 'number', 'duration' => 'N/A', 'qty' => 1 ) ); $this->hiddenElements=sprintf(" ", $_REQUEST['prefix'], $_REQUEST['period'] ); $data=array('customer_id' => $this->owner, 'country_iso' => $prefixes[$_REQUEST['prefix']]['country_iso'], 'city_prefix' => $prefixes[$_REQUEST['prefix']]['city_prefix'], 'period' => $_REQUEST['period'], 'map_data' => array( 'map_type' => 'URI', 'map_proto' => 'SIP', 'map_detail' => $this->account, 'map_pref_server' => 1 ), 'prepaid_funds' => "0", 'uniq_hash' => md5(mt_rand()) ); $did_processor->createOrder($data); /* if (class_exists($this->payment_processor_class)) { $payment_processor = new $this->payment_processor_class($this,$basket); } if ($payment_processor->transaction_results['success']) { if ($did_processor->createOrder($data)) { // add ENUM entry } else { // notify admin about payment without service fullfilment } } */ print " "; } else if ($_REQUEST['ddi_action'] == 'Renew' && $_REQUEST['number'] && $_REQUEST['period']) { $chapter=sprintf(_("Renew Number")); $this->showChapter($chapter); print " "; $data=array('customer_id' => $this->owner, 'did_number' => $_REQUEST['number'], 'period' => $_REQUEST['period'], 'uniq_hash' => md5(mt_rand()) ); print "Renewing number...."; $did_processor->renewOrder($data); print " "; } else if ($_REQUEST['ddi_action'] == 'Drop' && $_REQUEST['number']) { $chapter=sprintf(_("Cancel Number")); $this->showChapter($chapter); print " "; $data=array('customer_id' => $this->owner, 'did_number' => $_REQUEST['number'] ); $did_processor->cancelOrder($data); print " "; } else { $chapter=sprintf(_("Register New Number")); $this->showChapter($chapter); print " "; print "
"; print _("Select a region where you want to have a telephone number: "); print "

"; print ""; print "

"; print _("Select the duration for which you want to use the telephone number: "); print "

"; print ""; print $this->hiddenElements; print "

"; print ""; print ""; print "

"; } print " "; } else { print "

Error fetching DDI prefixes"; } print " "; } function showSupportTab() { $chapter=sprintf(_("Support")); $this->showChapter($chapter); print " "; print "

"; printf (_("To request support you may send an e-mail to %s"),$this->support_email); if ($this->support_web) { print "

"; printf (_("For more information visit %s"),$this->support_web); } print " "; } function render_download_applet() { $this->valid_os=array('nt','mac'); require("browser.php"); $os=browser_detection('os'); if ($this->create_certificate) { if ($_passport = $this->generateCertificate()) { $_account['passport'] = $_passport; } } $_account['sip_address'] = $this->account; $_account['display_name'] = sprintf("%s %s",$this->firstName,$this->lastName); $_account['password'] = $this->password; $_account['web_password'] = $this->Preferences['web_password']; $_account['email'] = $this->email; $_account['settings_url'] = $this->digest_settings_page; $_account['xcap_root'] = $this->xcap_root; $_account['outbound_proxy'] = $this->sip_proxy; if ($this->enrollment_url) { include($this->enrollment_configuration); if (is_array($enrollment)) { $_account['msrp_relay'] = $enrollment['msrp_relay']; $_account['conference_server'] = $enrollment['conference_server']; $_account['settings_url'] = $enrollment['settings_url']; if ($enrollment['ldap_hostname']) { $_account['ldap_hostname'] = $enrollment['ldap_hostname']; } if ($enrollment['ldap_dn']) { $_account['ldap_dn'] = $enrollment['ldap_dn']; } } } print ""; if (in_array($os,$this->valid_os)) { print ""; print ""; } else { print ""; } print ""; print ""; print "
"; printf (_("Download and install %s preconfigured with your SIP account:"), $this->blink_download_url, $this->show_download_tab); print "
"; printf (" ", rand(), $this->blink_download_url, urlencode(json_encode($_account)) ); print "
"; print "

"; printf (_("To download %s visit %s"),$this->show_download_tab, $this->blink_download_url, $this->blink_download_url); print "

"; printf (_("If you have already installed %s, you can configure it to use your SIP account:"), $this->show_download_tab); print "
"; printf (" ", rand(), $this->show_download_tab, urlencode(json_encode($_account)) ); print "
"; print "

"; printf ("Notes. "); print _("Java Runtime Environment (JRE) must be activated in the web browser. "); } function showFooter() { print "

"; if ($this->footerFile) { include ("$this->footerFile"); } else { print ""; } print "
"; } function showSettingsTab() { $use_yubikey=0; if (stream_resolve_include_path('Auth/Yubico.php')) { require_once 'Auth/Yubico.php'; $use_yubikey=1; } $this->getVoicemail(); print "
"; $chapter=sprintf(_("SIP Account")); $this->showChapter($chapter); if ($this->login_type != "subscriber" ) { print "
"; print "
firstName\">"; print "
"; print "
"; print "lastName\">"; print "
"; } print "
"; if ($this->login_type == 'subscriber' && in_array("deny-password-change",$this->groups)) { print _("Password can be changed only by the operator"); } else { print ""; print _("Enter text to change the current password"); printf ("\n\n\n\n",$this->password); } print "
"; print "
"; print ""; print _("Enter text to change the password to access this web page"); print "
"; if ($use_yubikey == 1 && !$this->isEmbedded()) { print "
"; print "Yubikey id to allow SIP Account + Yubikey login to access this webpage.

The Yubikey id is the first 12 digits of the string generated by the key.

It can be set by clicking in this text field and pressing your Yubikey."); printf ("\"name=yubikey value=\"%s\">",$this->Preferences['yubikey']) ; print _("Enter Yubikey id"); print "
"; //print '
';
             //print($this->Preferences['yubikey']);
             //print_r($this);
             //print '
'; } print "
"; print "
"; print "
"; $this->showTimezones('timezone',$this->timezone); print " "; $timestamp=time(); $LocalTime=getLocalTime($this->timezone,$timestamp); print ""; print _("Local Time"); print ": $LocalTime"; //dprint_r($this->availableGroups); print "
"; if (count($this->emergency_regions) > 0) { print "
"; print ""; print "
"; } if (in_array("free-pstn",$this->groups)) { if (in_array("quota",$this->groups)) { $_class="alert alert-error"; } else { $_class=""; } if ($this->pstn_changes_allowed) { print "
"; printf ("%s
",$this->currency,$this->quota); //print "
"; if ($this->quota || in_array("quota",$this->groups)) { $this->getCallStatistics(); if ($this->thisMonth['price']) { printf (_("This month usage: %.2f %s"),$this->thisMonth['price'], $this->currency); printf (" / %d ",$this->thisMonth['calls']); print _("Calls "); } } print " "; if ($this->pstn_changes_allowed) { print ""; } print "
"; } else if ($this->quota) { print "
"; printf ("%s %s ",$this->quota,$this->currency); $this->getCallStatistics(); if ($this->thisMonth['price']) { printf (_("This month usage: %.2f %s"),$this->thisMonth['price'], $this->currency); printf (" / %d ",$this->thisMonth['calls']); print _("Calls"); } print "
"; } } if ($this->pstn_access) { if ($this->prepaid) $checked_box_prepaid="checked"; if (!$this->prepaid_changes_allowed) $disabled_box_prepaid = "disabled=true"; print "
"; } foreach (array_keys($this->availableGroups) as $key) { unset($disabled_box); if ($this->login_type == 'subscriber' && !$this->availableGroups[$key]['SubscriberMaySeeIt']) { continue; } if ($this->login_type == 'reseller' && !$this->availableGroups[$key]['ResellerMaySeeIt']) { continue; } if (in_array($key,$this->groups)) { $checked_box[$key]="checked"; } $elementName = $this->availableGroups[$key]["WEBName"]; $elementComment = $this->availableGroups[$key]["WEBComment"]; if ($this->login_type == 'subscriber') { if ($this->availableGroups[$key]['SubscriberMayEditIt']) { $disabled_box = ""; } else { $disabled_box = "disabled=true"; } } elseif ($this->login_type == 'reseller') { if ($this->availableGroups[$key]['ResellerMayEditIt']) { $disabled_box = ""; } else { $disabled_box = "disabled=true"; } } if ($key=="free-pstn" && !$this->pstn_changes_allowed) { $disabled_box = "disabled=true"; } if ($key=="blocked" && $checked_box[$key]) { $_class="alert alert-error"; $_class1="error"; } else { $_class=""; $_class1=''; } print "
"; if ($key=="blocked") { if ($this->Preferences['blocked_by']) { $selected_blocked_by[$this->Preferences['blocked_by']]='selected'; } else if ($checked_box[$key]) { $selected_blocked_by['reseller']='selected'; } if ($this->login_type == 'admin' || $this->login_type == 'reseller') { if ($this->customer != $this->reseller || $selected_blocked_by['customer']) { printf (" ", $key, $selected_blocked_by['customer'], _("Blocked by Customer"), $this->customer, $selected_blocked_by['reseller'], _("Blocked by Reseller"), $this->reseller ); } else if ($this->reseller) { printf (" ", $key, _("Active"), $selected_blocked_by['reseller'], _("Blocked by Reseller"), $this->reseller ); } else { printf (" ", $key, _("Active"), $selected_blocked_by['reseller'], _("Blocked") ); } } else if ($this->login_type == 'customer' ) { if (in_array($key,$this->groups)) { if ($this->Preferences['blocked_by'] != 'reseller') { printf (" ", $key, _("Active"), $selected_blocked_by['customer'], _("Blocked") ); } else { print _("Blocked by Reseller"); } } else { printf (" ", $key, _("Active"), $selected_blocked_by['customer'], _("Blocked") ); } } else { if (in_array($key,$this->groups)) { print _("Blocked"); } else { print _("Active"); } } } else if ($key=="free-pstn") { if ($this->pstn_changes_allowed) { print " rpid\">"; } else { print ""; } else { print "$elementComment"; } } } else { print " "; } print "
"; } $this->showExtraGroups(); $this->showOwner(); $this->showQuickDial(); $this->showMobileNumber(); $this->showIPAccessList(); $this->showCallLimit(); print "
"); print "s",$this->timeout); print "
"; print "
"; if (in_array("free-pstn",$this->groups) && !$this->show_barring_tab) { if ($this->Preferences['show_barring_tab']){ $check_show_barring_tab="checked"; } else { $check_show_barring_tab=""; } printf ("\n",$check_show_barring_tab,_("Barring")); } print "
"; $this->showVoicemail(); $this->showBillingProfiles(); $chapter=sprintf(_("Notifications Address")); $this->showChapter($chapter); print "
email\">
"; print " "; print "
"; print "
"; print $this->hiddenElements; print " "; } function showDiversionsTab () { $this->getVoicemail(); $this->getEnumMappings(); $this->getDivertTargets(); $this->getDiversions(); print "
"; $chapter=sprintf(_("Call Forwarding")); $this->showChapter($chapter); $this->showDiversions(); print "
"; print " "; print "
"; print $this->hiddenElements; print "
"; } function showVoicemail() { if ($this->voicemail['Account']) { $checked_voicemail="checked"; } $chapter=sprintf(_("Voice Mailbox")); $this->showChapter($chapter); print "
"; if ($this->voicemail['Account']) { print "
"; if ($this->voicemail['Options']->delete=="True") { $checked_delete_voicemail="checked"; $selected_store_voicemail['email'] ="selected"; $selected_store_voicemail['server'] =""; } else { $selected_store_voicemail['email'] =""; $selected_store_voicemail['server'] ="selected"; } if (!$this->voicemail['DisableOptions']) { print ""; } else { printf (_("Voice messages are sent by email to %s"),$this->email); } print "
"; if (!$this->voicemail['DisableOptions']) { print "
"; printf ("",$this->voicemail['Password']); print "
"; if ($this->voicemail_access_number) { print "
"; printf(_("Dial %s to listen to your messages or change preferences. "),$this->voicemail_access_number); print "
"; } } } } function showOwner() { if ($this->login_type == 'subscriber') { //print "owner\">"; return true; } print "
owner\">"; print "
"; } function showDevicesTab() { $this->getDeviceLocations(); if (count($this->locations)) { $chapter=sprintf(_("SIP Devices")); $this->showChapter($chapter); $j=0; print "
"; foreach (array_keys($this->locations) as $location) { $j++; $contact = $this->locations[$location]['contact']; $publicContact = $this->locations[$location]['publicContact']; $expires = normalizeTime($this->locations[$location]['expires']); $user_agent = $this->locations[$location]['user_agent']; $transport = $this->locations[$location]['transport']; $UAImage = $this->getImageForUserAgent($user_agent); $rr=floor($j/2); $mod=$j-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print ""; print ""; print ""; } print "
"; printf ("",$this->SipUAImagesPath,$UAImage); print ""; print "$user_agent"; if ($transport == 'tls') print " "; print "
"; print _("Location"); print ""; print " "; if (strlen($transport)) print "$transport:"; print "$contact "; if ($publicContact != $contact) { print " ($publicContact) "; } if ($publicContact) { $_els=explode(":",$publicContact); if ($_loc=geoip_record_by_name($_els[0])) { $this->geo_location=$_loc['country_name'].'/'.utf8_encode($_loc['city']); } else if ($_loc=geoip_country_name_by_name($_els[0])) { $this->geo_location=$_loc; } else { $this->geo_location=''; } printf ("%s",$this->geo_location); } print "
$expires
"; } } function getBarringPrefixes() { dprint("getBarringPrefixes()"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getBarringPrefixes($this->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $this->barring_prefixes=$result; return true; } function setBarringPrefixes() { dprint("setBarringPrefixes"); $prefixes=array(); $barring_prefixes=$_REQUEST['barring_prefixes']; foreach ($barring_prefixes as $_prefix) { if (preg_match("/^\+[1-9][0-9]*$/",$_prefix)) { $prefixes[]=$_prefix; } } dprint("setBarringPrefixes"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setBarringPrefixes($this->sipId,$prefixes); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } function showBarringTab() { $chapter=sprintf(_("Barred Destinations")); $this->showChapter($chapter); print "

"; print "
"; print _("You can deny outbound calls to unwanted PSTN prefixes. "); print "
"; print "
"; print "
"; print ""; print _("Example"); print ": +31900"; print "
"; if ($this->getBarringPrefixes()) { foreach ($this->barring_prefixes as $_prefix) { $found++; $rr=floor($found/2); $mod=$found-$rr*2; if ($mod == 0) { $_class='odd'; } else { $_class='even'; } print "
"; print ""; print "
"; print "
"; } } print " "; print "
"; print "
"; print $this->hiddenElements; print " "; } function saveSettings() { $this->getVoicemail(); /* $this->getEnumMappings(); $this->getDivertTargets(); $this->getDiversions(); */ foreach ($this->form_elements as $el) { ${$el} = $_REQUEST[$el]; } $newACLarray = array(); $result = $this->result; if (!is_array($result->properties)) $result->properties=array(); if (!is_array($result->groups)) $result->groups=array(); if ($mailto && $this->email != $mailto) { $result->email=$mailto; $this->email=$mailto; $this->somethingChanged=1; $this->voicemailOptionsHaveChanged=1; } if ($this->login_type != "subscriber") { if ($first_name && $this->firstName != $first_name) { $result->firstName = $first_name; $this->firstName = $first_name; $this->somethingChanged=1; $this->voicemailOptionsHaveChanged=1; } if ($last_name && $this->lastName != $last_name) { $result->lastName = $last_name; $this->lastName = $last_name; $this->somethingChanged=1; } } $this->properties=$result->properties; $this->availableGroups['voicemail']=array("Group"=>"voicemail", "WEBName" =>sprintf (_("Voice Mailbox")), "SubscriberMayEditIt"=>"1", "SubscriberMaySeeIt"=>0 ); if (!$this->voicemail['Account'] && $voicemail) { if ($this->addVoicemail()) { $this->setVoicemailDiversions(); $this->createdVoicemailnow=1; } } else if ($this->voicemail['Account'] && !$voicemail) { if ($this->deleteVoicemail()) { $this->voicemail['Account']=""; $this->removeVoicemailDiversions(); } } if ($this->pstn_changes_allowed) { if (strcmp($quota,$this->quota) != 0) { if (!$quota) $quota=0; $result->quota=intval($quota); dprint ("change the quota"); $this->somethingChanged=1; } if ($quota_deblock) { $result->groups = array_unique(array_diff($this->groups,array('quota'))); $this->somethingChanged=1; $this->SipPort->addHeader($this->SoapAuth); $this->SipPort->removeFromGroup(array("username" => $this->username,"domain"=> $this->domain), "quota"); } $rpid=trim($rpid); if (strcmp($rpid,$this->rpid) != 0) { dprint ("change the rpid"); $result->rpid=$rpid; $this->somethingChanged=1; } } $owner=intval($owner); if ($owner != $this->owner && $this->login_type != 'subscriber') { dprint ("change the owner"); $result->owner=$owner; $this->somethingChanged=1; } else { $result->owner=$this->owner; } if ($this->prepaid_changes_allowed) { if(!$result->prepaid && $_REQUEST['prepaid']){ if ($result->quota) { $this->somethingChanged=1; } $this->somethingChanged=1; } else if ($result->prepaid && !$_REQUEST['prepaid']) { $this->somethingChanged=1; } $result->prepaid=intval($_REQUEST['prepaid']); } reset($this->availableGroups); foreach (array_keys($this->availableGroups) as $key) { // $val is set to 1 if web checkbox is ticked $val = $_REQUEST[$key]; if ($this->login_type != 'subscriber' || $this->availableGroups[$key]['SubscriberMayEditIt']) { if ($key == 'free-pstn') { if (in_array($key,$this->groups) && !$val) { if ($this->quota) { // we save quota for later use when pstn access is re-granted $this->somethingChanged=1; $this->setPreference('last_sip_quota',"$this->quota"); } $this->somethingChanged=1; } else if (!in_array($key,$this->groups) && $val) { if (!$this->prepaid_changes_allowed) { $this->somethingChanged=1; $result->prepaid=1; } } if (!in_array($key,$this->groups) && $val) { $this->setPreference('last_sip_quota',strval($this->quota)); $last_sip_quota=$this->Preferences['last_sip_quota']; if ($last_sip_quota) { $result->quota=intval($last_sip_quota); $this->somethingChanged=1; } } if ($this->pstn_changes_allowed) { if ($val) $newACLarray[]=trim($key); } else { if (in_array($key,$this->groups)) { $newACLarray[]=trim($key); } } } else if ($key == 'blocked') { if ($this->login_type == 'admin' || $this->login_type == 'reseller') { if ($val && $val != $this->Preferences['blocked_by']) { $this->setPreference('blocked_by',$val); $this->somethingChanged=1; } else if (!$val && in_array($key,$this->groups)) { $this->somethingChanged=1; $this->setPreference('blocked_by',''); } if ($val) $newACLarray[]=trim($key); } else if ($this->login_type == 'customer' ) { if ($this->Preferences['blocked_by'] != 'reseller') { if ($val && ($val != $this->Preferences['blocked_by'] || !in_array($key,$this->groups) )) { $this->setPreference('blocked_by',$val); $this->somethingChanged=1; $newACLarray[]=trim($key); } else if (!$val && in_array($key,$this->groups)) { $this->somethingChanged=1; $this->setPreference('blocked_by',''); } if ($val) $newACLarray[]=trim($key); } else { // copy old setting if exists if (in_array($key,$this->groups)) { $newACLarray[]=trim($key); } } } } else if ($key == 'sms') { if ($this->sms_changes_allowed) { if (!$val && in_array($key,$this->groups)) { $this->somethingChanged=1; } else if ($val && !in_array($key,$this->groups)) { $this->somethingChanged=1; } if ($val) $newACLarray[]=trim($key); } else { // copy old setting if exists if (in_array($key,$this->groups)) { $newACLarray[]=trim($key); } } } else { if ($val) $newACLarray[]=trim($key); } } else { // copy old setting if exists if (in_array($key,$this->groups)) { $newACLarray[]=trim($key); } } } $foundGroupInAvailableGroups=array(); $extra_groups=explode(' ',$_REQUEST['extra_groups']); foreach ($extra_groups as $_grp) { if (!in_array($_grp,array_keys($this->availableGroups))) { $newACLarray[]=$_grp; } } $grantACLarray = array_unique(array_diff($newACLarray,$this->groups)); $revokeACLarray = array_unique(array_diff($this->groups,$newACLarray)); /* dprint_r($this->groups); dprint_r($newACLarray); dprint_r($grantACLarray); dprint_r($revokeACLarray); */ if (count($revokeACLarray) || count($grantACLarray)) { $result->groups=$newACLarray; $this->somethingChanged=1; } if ($language && $language != $this->Preferences['language'] ) { if ($this->login_type == 'subscriber') {; //print("Set lang $language"); $this->changeLanguage($language); } $this->setPreference("language",$language); $this->somethingChanged=1; } if ($show_barring_tab != $this->Preferences['show_barring_tab'] ) { $this->setPreference("show_barring_tab",$show_barring_tab); $this->somethingChanged=1; } if ($this->login_type == 'subscriber' && in_array("deny-password-change",$this->groups)) { } else if ($sip_password) { if ($this->store_clear_text_passwords) { $result->password=$sip_password; } else { $md1=strtolower($this->username).':'.strtolower($this->domain).':'.$sip_password; $md2=strtolower($this->username).'@'.strtolower($this->domain).':'.strtolower($this->domain).':'.$sip_password; $result->password=md5($md1).':'.md5($md2); } $this->somethingChanged=1; } if ($web_password) { if ($this->store_clear_text_passwords) { $web_password_new=$web_password; } else { $md1=strtolower($this->username).':'.strtolower($this->domain).':'.$web_password; $md2=strtolower($this->username).'@'.strtolower($this->domain).':'.strtolower($this->domain).':'.$web_password; $web_password_new=md5($md1).':'.md5($md2); } $this->setPreference('web_password',$web_password_new); $this->somethingChanged=1; } if ($this->Preferences['yubikey'] != $yubikey && !$this->isEmbedded()) { $this->setPreference('yubikey',$yubikey); $this->somethingChanged=1; } if (is_array($result->acl) and count($result->acl)) { foreach (array_keys($result->acl) as $key) { if (isset($result->acl[$key]->tag) && $result->acl[$key]->tag == '') { unset($result->acl[$key]->tag); } } } if ($this->IPAccessListChangePolicy()) { if (isset($ip_access_list) and $this->ip_access_list != $ip_access_list) { $ip_access_list=preg_replace("/\s+/","\n", trim($ip_access_list)); $list=explode("\n", trim($ip_access_list)); $ip_access_list=array(); foreach ($list as $el) { list($ip,$mask) = explode("/",$el); if ($mask <0 or $mask > 32) { continue; } if (!preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/",$ip)) { continue; } $ip_access_list[]=array('ip'=>$ip, 'mask'=>intval($mask)); } $result->acl=$ip_access_list; $this->somethingChanged=1; } } if ($this->CallLimitChangePolicy()) { if ($this->soapEngines[$this->sip_engine]['call_limit']) { if (isset($callLimit) && $this->callLimit != $callLimit) { $result->callLimit=intval($callLimit); $this->somethingChanged=1; } } } if (!$result->password) unset($result->password); if ($timezone && $timezone != $this->timezone) { $result->timezone=$timezone; $this->somethingChanged=1; } if ($region != $this->region) { $result->region=$region; $this->somethingChanged=1; } if (strcmp($quickdial,$this->quickdial) != 0) { $result->quickdialPrefix=$quickdial; $this->somethingChanged=1; } $mobile_number = preg_replace("/[^\+0-9]/","",$mobile_number); if ($mobile_number && !preg_match("/^\+/",$mobile_number)) { $mobile_number='+'.$mobile_number; } if ($this->Preferences['mobile_number'] != $mobile_number) { $this->setPreference('mobile_number',$mobile_number); $this->somethingChanged=1; } if (!$this->createdVoicemailnow) { // moved to its own tab //$this->setDiversions(); } if ($this->timeoutWasNotSet || $timeout != $this->timeout) { $this->somethingChanged=1; $result->timeout=intval($timeout); } if ($result->owner == '') { $this->somethingChanged=1; $result->owner=0; } if ($result->callLimit == '') { $this->somethingChanged=1; $result->callLimit=0; } if ($result->quota == '') { $this->somethingChanged=1; $result->quota=0; } if ($result->timeout == '') { $this->somethingChanged=1; $result->timeout=35; } if ($result->timeout > 900) { $this->somethingChanged=1; $result->timeout=900; } if ($this->somethingChanged) { $result->properties=$this->properties; if (!$result->quota) $result->quota=0; //dprint_r($result); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->updateAccount($result); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { dprint("Call updateAccount"); } } if ($this->voicemail['Account'] && !$this->createdVoicemailnow) { $delete_voicemail = $_REQUEST['delete_voicemail']; //$log=sprintf("delete_voicemail_orig=%s",$this->voicemail['Options']->delete); //dprint($log); if (($delete_voicemail && !$this->voicemail['Options']->delete) || (!$delete_voicemail && $this->voicemail['Options']->delete)) { $this->voicemail['Options']=array("delete"=>intval($delete_voicemail)); $this->voicemailOptionsHaveChanged=1; } $voicemail_password=preg_replace("/[^0-9]/","",$voicemail_password); if ($this->voicemail['Password'] != $voicemail_password) { $this->voicemailOptionsHaveChanged=1; $this->voicemail['Password']=$voicemail_password; } if ($this->voicemailOptionsHaveChanged) { $this->updateVoicemail(); } } $this->updateBillingProfiles(); } function setDiversions() { dprint ("setDiversions()"); $this->getVoicemail(); $this->getEnumMappings(); $this->getDivertTargets(); $this->getDiversions(); foreach (array_keys($this->diversionType) as $condition) { $select_name = $condition."_select"; $selectedIdx = $_REQUEST[$select_name]; $textboxURI = $_REQUEST[$condition]; if ($textboxURI && $textboxURI != "" && !preg_match("/@/",$textboxURI)) { $textboxURI=$textboxURI."@".$this->domain; } if (preg_match("/^([\+|0].*)@/",$textboxURI,$m)) { $textboxURI=$m[1]."@".$this->domain; } $uri_description = $this->divertTargets[$selectedIdx]['description']; if ($uri_description == 'Other' || $textboxURI == "") { $selectedURI = $textboxURI; } else { $selectedURI = $this->divertTargets[$selectedIdx]['value']; } $uri = $selectedURI; if (!$this->voicemail['Account'] && $uri_description == 'Voicemail') { dprint("No voicemail account found"); $uri_description='Disabled'; } if ($this->diversions[$condition]) { if ($uri_description=='Disabled' && $this->CallPrefUriType[$condition]!='Disabled') { $diversions[$condition]=""; } else if ($uri_description != 'Disabled' && $selectedURI) { if (checkURI($selectedURI)) { if ($this->CallPrefUriType[$condition]=='Disabled') { $diversions[$condition]=""; } else { if ($this->diversions[$condition] != $uri) { $diversions[$condition]=$uri; } else { $diversions[$condition]=$this->diversions[$condition]; } } } else { $diversions[$condition]=$this->diversions[$condition]; dprint("Failed to check address $selectedURI"); } } } else if ($uri_description!='Disabled' && $selectedURI) { if (checkURI($selectedURI)) { $diversions[$condition]=$uri; } else { dprint("Failed to check address $condition=\"$selectedURI\""); $diversions[$condition]=$this->diversions[$condition]; } } if (!$uri_description) $uri_description="Other"; if ($uri_description == 'Other') { $last_other=$uri; } else { $last_other = $this->CallPrefLastOther[$condition]; } $_prefLast = $condition."_lastOther"; if ($uri_description=='Other' && $this->Preferences[$_prefLast] != $last_other ) { $this->setPreference($_prefLast,$last_other); } } foreach(array_keys($this->diversions) as $key) { if ($this->diversions[$key] != $diversions[$key]) { //$log=sprintf("Diversion %s changed from %s to %s",$key,htmlentities($this->diversions[$key]),htmlentities($diversions[$key])); dprint($log); $divert_changed=1; } if ($diversions[$key]) { if ($diversions[$key] == "") { if ($this->absolute_voicemail_uri) { $diversionsSOAP[$key] = 'sip:'.$this->voicemail['Account']; } else { $diversionsSOAP[$key] = $diversions[$key]; } } else { $diversionsSOAP[$key]='sip:'.$diversions[$key]; } } else { if ($diversions[$key]) $diversionsSOAP[$key]=$diversions[$key]; } } if (!is_array($diversionsSOAP) || count($diversionsSOAP) == 0) { $diversionsSOAP=array("nocondition"=>"empty"); } if ($divert_changed) { $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setCallDiversions($this->sipId,$diversionsSOAP); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error2 (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { $this->diversions=$diversions; } } } function setDiversion($condition,$uri) { dprint ("setDiversion($condition,$uri)"); $condition=trim($condition); $uri=trim($uri); $this->getVoicemail(); $this->getDivertTargets(); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getCallDiversions($this->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $_uri_saved=$uri; if ($_uri_saved == "voicemail") { $uri=""; foreach ($this->divertTargets as $target) { if ($target['description'] == 'Voicemail') { $uri=$target['value']; break; } } } if ($_uri_saved == "mobile") { $uri=""; foreach ($this->divertTargets as $target) { dprint_r($target); if ($target['description'] == 'Mobile') { $uri=$target['value']; break; } } } if ($_uri_saved == "other" && $this->CallPrefLastOther[$condition]) { $uri=$this->CallPrefLastOther[$condition]; } if (strlen($uri)) { if ($uri != "") { if (!preg_match("/^(sip:|sips:)/",$uri)) $uri="sip:".$uri; } } else { $uri=NULL; } reset($this->diversionType); foreach(array_keys($this->diversionType) as $_condition) { $uri=$result->$_condition; if ($this->absolute_voicemail_uri && $uri == "") { $uri = $this->voicemail['Account']; } if (preg_match("/^(sip:|sips:)(.*)$/i",$uri,$m)) { $uri=$m[2]; } //if (!$uri) $uri=NULL; $this->diversions[$condition]=$uri; } dprint_r($this->diversions); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setCallDiversions($this->sipId,$result); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } function setVoicemailDiversions() { dprint ("setVoicemailDiversions()"); if ($this->getVoicemail()) { if (!$this->absolute_voicemail_uri) { $diversions['FBUS']=""; $diversions['FNOA']=""; $diversions['FNOL']=""; } else { $diversions['FBUS']="sip:".$this->voicemail['Account']; $diversions['FNOA']="sip:".$this->voicemail['Account']; $diversions['FNOL']="sip:".$this->voicemail['Account']; } $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setCallDiversions($this->sipId,$diversions); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } } function removeVoicemailDiversions() { dprint ("removeVoicemailDiversions()"); $this->getDiversions(); $diversions=array(); foreach (array_keys($this->diversionType) as $key) { if ($this->diversions[$key]=="" || preg_match("/voicemail_server/",$this->diversions[$key])) { $diversions_have_changed=true; } else { if ($this->diversions[$key]) { $diversions[$key]=$this->diversions[$key]; } } } if (!count($diversions)) { $diversions['nocondition']='empty'; } if ($diversions_have_changed) { $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setCallDiversions($this->sipId,$diversions); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } else { return true; } } function updateVoicemail() { dprint("updateVoicemail()"); $account=array("sipId" => $this->sipId, "email" => $this->email, "name" => $this->firstName.' '.$this->lastName, "password" => $this->voicemail['Password'], "options" => $this->voicemail['Options'] ); dprint_r($account); $this->VoicemailPort->addHeader($this->SoapAuthVoicemail); $result = $this->VoicemailPort->updateAccount($account); if (PEAR::isError($result)) { $error_msg=$result->getMessage(); $error_fault=$result->getFault(); $error_code=$result->getCode(); print "$error_msg\n"; printf ("

Error (VoicemailPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function addVoicemail() { dprint("addVoicemail()"); $password=$this->RandomPassword(); $_account = array("sipId" => $this->sipId, "name" => $this->fullName, "password" => $password, "email" => $this->email, "options" => array("delete"=>1) ); $this->VoicemailPort->addHeader($this->SoapAuthVoicemail); $result = $this->VoicemailPort->addAccount($_account); if (PEAR::isError($result)) { $error_msg=$result->getMessage(); $error_fault=$result->getFault(); $error_code=$result->getCode(); print "$error_msg\n"; printf ("

Error (VoicemailPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function deleteVoicemail() { dprint("deleteVoicemail()"); $this->VoicemailPort->addHeader($this->SoapAuthVoicemail); $result = $this->VoicemailPort->deleteAccount($this->sipId); if (PEAR::isError($result)) { $error_msg=$result->getMessage(); $error_fault=$result->getFault(); $error_code=$result->getCode(); print "$error_msg\n"; printf ("

Error (VoicemailPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function setPreference($name,$value) { dprint("setPreference($name,$value)"); if (!$name) return; if (!is_array($this->properties)) { $this->properties=array(); } foreach (array_keys($this->properties) as $_key) { $_prop=$this->properties[$_key]; if ($_prop->name == $name) { if (strlen($value)) { $newProperties[]=array('name'=> $name, 'value' => $value); } $found=1; } else { $newProperties[]=$_prop; } } if (!$found) { $newProperties[]=array('name' => $name, 'value' => $value); } if ($this->properties!=$newProperties) $this->somethingChanged=1; if (!$newProperties) $newProperties = array(); $this->properties=$newProperties; //dprint_r($this->properties); } function showCreditTab() { if ($this->login_type == 'subscriber' && in_array("blocked",$this->groups)) { return false; } $task = $_REQUEST['task']; $issuer = $_REQUEST['issuer']; $prepaidCard = $_REQUEST['prepaidCard']; $prepaidId = $_REQUEST['prepaidId']; $_done = false; if ($issuer) { print " "; if ($issuer=='subscriber'){ if ($prepaidCard && $prepaidId) { if ($result = $this->addBalanceSubscriber($prepaidCard,$prepaidId)) { print "

"; printf (_("Old balance was %s, new balance is %s. "),$result->old_balance, $result->new_balance); print ""; $_done=true; } } } else if ($issuer=='reseller' || $issuer=='admin') { if ($_REQUEST['task'] == 'change_balance') { $description = $_REQUEST['description']; $value = $_REQUEST['value']; if (strlen($value) && $result = $this->addBalanceReseller($value,$description)) { print "

"; printf (_("Old balance was %s, new balance is %s. "),$result->old_balance, $result->new_balance); print ""; $_done=true; } } else if ($_REQUEST['task'] == 'refund') { $transaction = json_decode(base64_decode($_REQUEST['transaction'])); printf ("Refunding transaction id %s in value of %s", $transaction->id, $transaction->value); require('cc_processor.php'); $ccp = new CreditCardProcessor(); $refund_results = $ccp->refundPayment($transaction->id); if(count($refund_results['error']) > 0 ){ printf ("

Error %d: %s (%s)",$refund_results['error']['error_code'], $refund_results['error']['desc'], $refund_results['error']['short_message']); } else { printf ("

Transaction %s refunded with %s: %s",$transaction->id, $refund_results['success']['desc']->RefundTransactionID,$refund_results['success']['desc']->GrossRefundAmount->_value); $description=sprintf("Refund %s with %s",$transaction->id, $refund_results['success']['desc']->RefundTransactionID); if ($result = $this->addBalanceReseller(-$transaction->value,$description)) { print "

"; printf (_("Old balance was %s, new balance is %s. "),$result->old_balance, $result->new_balance); print ""; $_done=true; } } } } if ($_done && $_REQUEST['notify']) { $subject=sprintf ("SIP Account %s balance update",$this->account); $body="Your SIP Account balance has been updated. ". "For more details go to $this->sip_settings_page?tab=credit"; if (mail($this->email, $subject, $body, "From: $this->support_email")) { printf (_("Subscriber has been notified at %s."), $this->email); } } print " "; } $this->getPrepaidStatus(); if ($this->prepaidAccount) { $chapter=sprintf(_("Current Balance")); $this->showChapter($chapter); print "

"; print _("Your current balance is"); print ": "; printf ("%.2f %s ",$this->prepaidAccount->balance,$this->currency); print "
"; $this->showChangeBalanceReseller(); $this->showChangeBalanceSubscriber(); $this->showBalanceHistory(); } } function showChangeBalanceReseller () { if (!$this->prepaid_changes_allowed) return false; $chapter=sprintf(_("Add Balance")); $this->showChapter($chapter); print "
url method=post>
"; print " "; print ""; print " "; print "
"; $transactions = $this->getPaymentIds(); if (count($transactions)) { $chapter=sprintf(_("Refund Transaction")); $this->showChapter($chapter); print "
url method=post> "; print _("Transaction Id"); print " "; print " Notify
"; } } function showChangeBalanceSubscriber () { $this->showPrepaidVoucherForm(); } function showPrepaidVoucherForm () { if ($this->isEmbedded()) return true; $chapter=sprintf(_("Prepaid Card")); $this->showChapter($chapter); print "
"; printf (_("To add Credit to your account using a Prepaid Card enter it below. ")); print "
"; print "
url method=post>
"; print " "; print ""; if ($this->login_type != 'subscriber') { print " "; } print "
"; } function getPrepaidStatus() { dprint("getPrepaidStatus()"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getPrepaidStatus(array($this->sipId)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); unset($this->prepaidAccount); return false; } else { $this->prepaidAccount=$result[0]; return true; } } function addBalanceSubscriber($prepaidCard,$prepaidId) { dprint("addBalanceSubscriberLocal($prepaidCard,$prepaidId)"); $card = array('id' => intval($prepaidId), 'number' => $prepaidCard ); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->addBalanceFromVoucher($this->sipId,$card); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { return $result; } } function addBalanceReseller($value=0,$description='') { $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->addBalance($this->sipId,floatval($value),$description); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { return $result; } } function getBalanceHistory() { dprint("getBalanceHistory()"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getCreditHistory($this->sipId,200); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "2000") { printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); } } $this->balance_history=$result->entries; } function getPaymentIds() { $transactions = array(); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getCreditHistory($this->sipId,200); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "2000") { printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); } } $refunded_transactions=array(); $credit_transactions=array(); foreach ($result->entries as $entry) { if (preg_match("/^CC transaction (.*)$/",$entry->description,$m)) { $credit_transactions[$m[1]]=$entry->value; } if (preg_match("/^Refund (.*) with (.*)$/",$entry->description,$m)) { $refunded_transactions[]=$m[1]; } } foreach (array_keys($credit_transactions) as $tran) { if (!in_array($tran, $refunded_transactions)) { $transactions[$tran] = $credit_transactions[$tran]; } } return $transactions; } function getTodayBalanceSummary() { $total_debit = 0; $total_credit = 0; foreach ($this->balance_history as $_line) { $value=$_line->value; if (substr($_line->date,0,10) != date("Y-m-d")) { break; } if ($value <0) { $total_debit+=$value; } if ($value >0) { $total_credit+=$value; } } $total = array('debit' => $total_debit, 'credit' => $total_credit ); return $total; } function showBalanceHistory() { $this->getBalanceHistory(); if (!count($this->balance_history)) { return; } $chapter=sprintf(_("Balance History")); $this->showChapter($chapter); print "

"; $today_summary = $this->getTodayBalanceSummary(); if ($today_summary['credit'] >= $max_credit_per_day) { print "

"; printf (_("Today's transactions: %.2f credit, %.2f debit"), $today_summary['credit'],$today_summary['debit']); } print "

"; print ""; print ""; print ""; print ""; print ""; print ""; print ""; print ""; print ""; print ""; foreach ($this->balance_history as $_line) { if (strstr($_line->description,'Session')) { if (!$_line->value) continue; $value=$_line->value; if ($this->cdrtool_address && !$this->isEmbedded()) { $description=sprintf("$_line->description",$this->cdrtool_address,urlencode($_line->session)); } else { $description=$_line->description; } } else { $description=$_line->description; $value=$_line->value; } if ($value <0) { $total_debit+=$value; } if ($value >0) { $total_credit+=$value; } $found++; $rr=floor($found/2); $mod=$found-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print " "; printf (" ",$found, $_line->date, $_line->action, $description, number_format($value,4), number_format($_line->balance,4) ); } print " "; if (strlen($total_credit)) { printf (" ", _("Total Credit"), number_format($total_credit,4) ); } if (strlen($total_debit)) { printf (" ", _("Total Debit"), number_format($total_debit,4) ); } print "
"; print ""; print _("Date and Time"); print ""; print _("Action"); print ""; print _("Description"); print ""; print _("Value"); print ""; print _("Balance"); print "
%d %s %s %s %s %s
%s %s
%s %s
"; if ($found) { if (!$this->isEmbedded()) { print "

url&tab=credit&action=get_balance_history&csv=1 target=_new data-original-title='"; print _("Export"); print "' data-content='"; print _("Export balance history in CSV format"); print "' rel='popover' onclick=\"window.open('$this->url&tab=credit&action=get_balance_history&csv=1]')\">"; print _("Export"); print "

"; } else { print "

url&tab=credit&action=get_balance_history&csv=1 data-original-title='"; print _("Export"); print "' data-content='"; print _("Export balance history in CSV format"); print "' onclick=\"location.href='$this->url&tab=credit&action=get_balance_history&csv=1';\">"; print _("Export"); print "

"; } } print ""; } function exportBalanceHistory() { Header("Content-type: text/csv"); $h=sprintf("Content-Disposition: inline; filename=%s-prepaid-history.csv",$this->account); Header($h); print _("Id"); print ","; print _("Account"); print ","; print _("Date"); print ","; print _("Action"); print ","; print _("Description"); print ","; print _("Value"); print ","; print _("Final Balance"); print ("\n"); foreach ($this->balance_history as $_line) { if (strstr($_line->description,'Session') && !$_line->value) continue; $found++; printf ("%s,%s,%s,%s,%s,%s,%s\n", $found, $this->account, $_line->date, $_line->action, $_line->description, $_line->value, $_line->balance); } } function showDiversions($conditions=array()) { // for busy not online or unconditional foreach (array_keys($this->diversionType) as $condition) { $_prefName = $condition."_lastOther"; $this->CallPrefLastOther[$condition]= $this->Preferences[$_prefName]; } if (!count($conditions)) { $conditions=$this->diversionType; } foreach (array_keys($conditions) as $condition) { $found++; $rr=floor($found/2); $mod=$found-$rr*2; $pref_name = $conditions[$condition]; $pref_value = $this->diversions[$condition]; $select_name=$condition."_select"; $set_uri_java="set_uri_" . $condition; $update_text_java="update_text_" . $condition; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print "
"; $phoneValues = array(); foreach ($this->divertTargets as $phones) { $phoneValues[] = $phones['value']; } $lastOther = $this->CallPrefLastOther[$condition]; $otherIdx = count($this->divertTargets) - 1; $phoneValues[$otherIdx] = $lastOther; $targets = sprintf("'%s'", join("', '", $phoneValues)); print " "; print ""; if ($this->CallPrefUriType[$condition]=='Other') $style = "visible"; else $style = "hidden"; $pref_value=$this->diversions[$condition]; print " "; if ($condition=="FUNV" && $this->FUNC_access_number) { print "
"; printf (_("Dial %s2*X where X = Number of Minutes, 0 to Reset"), $this->access_numbers['FUNC']); print "
"; } print "
"; } } function showHeader() { /*print "
";*/ print "
"; if ($this->logoFile) { print "logoFile border=0>"; } print "
"; /* print "
"; */ } function chapterTableStart() { } function chapterTableStop() { } function getEnumMappings () { dprint("getEnumMappings()"); $this->enums=array(); $filter=array( 'type' => 'sip', 'mapto' => $this->account, 'owner' => intval($this->owner) ); // Range $range=array('start' => 0, 'count' => 10 ); // Order $orderBy = array('attribute' => 'changeDate', 'direction' => 'ASC' ); // Compose query $Query=array('filter' => $filter, 'orderBy' => $orderBy, 'range' => $range ); // Insert credetials $this->EnumPort->addHeader($this->SoapAuthEnum); $result = $this->EnumPort->getNumbers($Query); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (EnumPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } foreach($result->numbers as $_number) { $enum='+'.$_number->id->number; $this->voicemailUsernameOptions[]=$enum; if (!in_array($enum,$this->enums)) $this->enums[]=$enum; } } function enum2tel($enum_text) { // transform enum style domain name in forward telephone number $enum_text=trim($enum_text); if (preg_match("/^\+\d+$/",$enum_text)) { return $enum_text; } $z=0; $tel_text=""; while ($z < strlen($enum_text)) { $char = substr($enum_text,$z,1); if (preg_match("/[a-zA-Z]/",$char)) { break; } else if (preg_match("/[0-9]/",$char)) { $tel_text=$char.$tel_text; $z++; } else { $z++; } } if ($tel_text) { $tel_text="+".$tel_text; return ($tel_text); } else { return $enum_text; } } function showTimezones($name,$value) { if (!$fp = fopen("timezones", "r")) { print _("Failed to open timezone file."); return false; } printf (""; } function showQuickDial() { if (!preg_match("/^\d+$/",$this->username)) return 1; print "

quickdial\">"; if ($this->quickdial && preg_match("/^$this->quickdial/",$this->username)) { $dial_suffix=strlen($this->username) - strlen($this->quickdial); } printf (_("Prefix to auto-complete short numbers"),$dial_suffix); print "
"; } function showMobileNumber() { if (in_array("free-pstn",$this->groups)) { print "
%s
",$this->Preferences['mobile_number'],_("International format starting with +")); } } function CallLimitChangePolicy() { if ($this->login_type == 'subscriber' and $this->call_limit_may_by_changed_by == 'reseller') { return false; } if ($this->login_type == 'subscriber' and $this->call_limit_may_by_changed_by == 'customer') { return false; } if ($this->login_type == 'subscriber' and $this->call_limit_may_by_changed_by == 'admin') { return false; } if ($this->login_type == 'customer' and $this->call_limit_may_by_changed_by == 'reseller') { return false; } if ($this->login_type == 'customer' and $this->call_limit_may_by_changed_by == 'admin') { return false; } if ($this->login_type == 'reseller' and $this->call_limit_may_by_changed_by == 'admin') { return false; } return true; } function IPAccessListChangePolicy() { if ($this->login_type == 'subscriber' and $this->ip_access_list_may_by_changed_by == 'reseller') { return false; } if ($this->login_type == 'subscriber' and $this->ip_access_list_may_by_changed_by == 'customer') { return false; } if ($this->login_type == 'subscriber' and $this->ip_access_list_may_by_changed_by == 'admin') { return false; } if ($this->login_type == 'customer' and $this->ip_access_list_may_by_changed_by == 'reseller') { return false; } if ($this->login_type == 'customer' and $this->ip_access_list_may_by_changed_by == 'admin') { return false; } if ($this->login_type == 'reseller' and $this->ip_access_list_may_by_changed_by == 'admin') { return false; } return true; } function showIPAccessList() { if (!$this->soapEngines[$this->sip_engine]['ip_access_list']) { return; } if (!$this->IPAccessListChangePolicy()) { print "
%s
",$this->ip_access_list); } else { print "
",$this->ip_access_list); } } function showCallLimit() { if (!$this->soapEngines[$this->sip_engine]['call_limit']) { return; } if (!in_array("free-pstn",$this->groups)) { return; } $limit_text = sprintf(_("Default is %s"), $this->platform_call_limit); if (strlen($this->callLimit)) { $limit_text_ro=$this->callLimit; } else { $limit_text_ro=$this->platform_call_limit; } if (!$this->CallLimitChangePolicy()) { print "
%s
",$limit_text_ro); } else { print "
%s
",$this->callLimit, $limit_text); } } function showCallsTab() { $this->getHistory(); if ($this->calls) { $chapter=sprintf(_("Call Statistics")); $this->showChapter($chapter); $calltime=normalizeTime($this->duration); print " "; if ($this->cdrtool_address) { print "cdrtool_address target=cdrtool>"; print _("Summary"); print ""; } else { print _("Usage Data"); } print " "; printf (_("%s calls / %s / %s / %.2f %s"), $this->calls, $calltime,$this->trafficPrint,$this->price,$this->currency); print " "; print " "; print _("First / Last Call"); print " $this->firstCall / $this->lastCall "; } if ($this->enable_thor) { $cdr_source = 'sipthor'; } else { $cdr_source = 'sip_trace'; } if (count($this->calls_received)) { $chapter=sprintf(_("Incoming")); $this->showChapter($chapter); $j=0; print ""; foreach (array_keys($this->calls_received) as $call) { $j++; $uri = $this->calls_received[$call]['remoteParty']; $media=""; foreach ($this->calls_received[$call]['media'] as $m) { $media.="$m,"; } $media=quoted_printable_decode($media); $media=rtrim($media,","); $duration = normalizeTime($this->calls_received[$call]['duration']); $dialURI = $this->PhoneDialURL($uri) ; $htmlDate = $this->colorizeDate($this->calls_received[$call]['startTime']); $htmlURI = $this->htmlURI($uri); $urlURI = urlencode($this->normalizeURI($uri)); $sessionId = urlencode($this->calls_received[$call]['sessionId']); $fromTag = urlencode($this->calls_received[$call]['fromTag']); $toTag = urlencode($this->calls_received[$call]['toTag']); $proxyIP = urlencode($this->calls_received[$call]['proxyIP']); - $trace_link = "Server Logs"; if (!$this->calls_received[$call]['duration']) { $htmlURI = "$htmlURI"; } $rr=floor($j/2); $mod=$j-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print " "; print ""; print ""; print " "; } print "
$htmlDate $dialURI $duration $htmlURI ($media)$trace_linkurl&tab=contacts&task=add&uri=$urlURI&search_text=$urlURI>$this->phonebook_img
"; } if (count($this->calls_placed)) { $chapter=sprintf(_("Outgoing")); $this->showChapter($chapter); $j=0; print ""; foreach (array_keys($this->calls_placed) as $call) { $j++; if ($this->calls_placed[$call]['to'] == "sip:".$this->voicemail['Account'] ) { continue; } $uri = $this->calls_placed[$call]['remoteParty']; $media = ""; foreach ($this->calls_placed[$call]['media'] as $m) { $media.="$m,"; } $media=rtrim($media,","); $price = $this->calls_placed[$call]['price']; $status = $this->calls_placed[$call]['status']; $rateinfo = $this->calls_placed[$call]['rateInfo']; $duration = normalizeTime($this->calls_placed[$call]['duration']); $dialURI = $this->PhoneDialURL($uri) ; $htmlDate = $this->colorizeDate($this->calls_placed[$call]['startTime']); $stopTime = $this->calls_placed[$call]['stopTime']; $htmlURI = $this->htmlURI($uri); $urlURI = urlencode($this->normalizeURI($uri)); $sessionId = urlencode($this->calls_placed[$call]['sessionId']); $fromTag = urlencode($this->calls_placed[$call]['fromTag']); $toTag = urlencode($this->calls_placed[$call]['toTag']); $proxyIP = urlencode($this->calls_placed[$call]['proxyIP']); - $trace_link = "Server Logs"; if ($price) { $price_print =sprintf(" (%s %s)",$price,$this->currency); } else { $price_print = ''; } $rr=floor($j/2); $mod=$j-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } if (!$stopTime) { $duration = _('In progress'); } print " "; print ""; print ""; print " "; } print "
$htmlDate $dialURI $duration $htmlURI ($media) $price_print$trace_linkurl&tab=contacts&task=add&uri=$urlURI&search_text=$urlURI>$this->phonebook_img
"; } } function getHistory ($status='all') { dprint("getHistory()"); $fromDate=time()-3600*24*14; // last two weeks $toDate=time(); $CallQuery=array("fromDate"=>$fromDate, "toDate"=>$toDate, "limit"=>50 ); $CallsQuery=array("placed"=>$CallQuery, "received"=>$CallQuery ); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getCalls($this->sipId,$CallsQuery); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } // received calls foreach ($result->received as $callStructure) { $media = array(); $apps = explode(",",quoted_printable_decode($callStructure->applicationTypes[0])); foreach ($apps as $app) { $media[]=trim($app); } if (!$callStructure->stopTime && $status == 'completed') { continue; } $this->calls_received[]=array( "remoteParty" => quoted_printable_decode($callStructure->fromURI), "startTime" => getLocalTime($this->timezone,$callStructure->startTime), "stopTime" => getLocalTime($this->timezone,$callStructure->stopTime), "timezone" => $this->timezone, "duration" => $callStructure->duration, "status" => $callStructure->status, "sessionId" => quoted_printable_decode($callStructure->sessionId), "fromTag" => quoted_printable_decode($callStructure->fromTag), "toTag" => quoted_printable_decode($callStructure->toTag), "proxyIP" => $callStructure->proxyIP, "media" => $media ); } // placed calls foreach ($result->placed as $callStructure) { if ($callStructure->status == 435) continue; $media = array(); $apps = explode(",",quoted_printable_decode($callStructure->applicationTypes[0])); foreach ($apps as $app) { $media[]=trim($app); } if (!$callStructure->stopTime && $status == 'completed') { continue; } $this->calls_placed[]=array( "remoteParty" => quoted_printable_decode($callStructure->toURI), "startTime" => getLocalTime($this->timezone,$callStructure->startTime), "stopTime" => getLocalTime($this->timezone,$callStructure->stopTime), "timezone" => $this->timezone, "duration" => $callStructure->duration, "status" => $callStructure->status, "price" => $callStructure->price, "sessionId" => quoted_printable_decode($callStructure->sessionId), "fromTag" => quoted_printable_decode($callStructure->fromTag), "toTag" => quoted_printable_decode($callStructure->toTag), "proxyIP" => $callStructure->proxyIP, "media" => $media ); } $this->call_history=array('placed'=>$this->calls_placed, 'received'=>$this->calls_received ); } function getCallStatistics () { dprint("getCallStatistics()"); $fromDate=mktime(0, 0, 0, date("m"), "01", date("Y")); $toDate=time(); $CallQuery=array("fromDate"=>$fromDate, "toDate"=>$toDate ); $CallQuery=array("limit"=>1 ); $CallsQuery=array("placed"=>$CallQuery); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getCallStatistics($this->sipId,$CallsQuery); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } //dprint_r($result); $this->thisMonth['calls'] = $result->placed->calls; $this->thisMonth['price'] = $result->placed->price; } function addPhonebookEntry() { dprint("addPhonebookEntry()"); $uri = strtolower(trim($_REQUEST['uri'])); $name = trim($_REQUEST['name']); $group = trim($_REQUEST['group']); if (!strlen($uri)) return false; $phonebookEntry=array( 'uri' => $uri, 'name' => $name, 'group' => $group ); dprint("addPhonebookEntry"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->addPhoneBookEntry($this->sipId,$phonebookEntry); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s
",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function updatePhonebookEntry() { dprint("updatePhonebookEntry()"); $uri = strtolower(trim($_REQUEST['uri'])); $group = trim($_REQUEST['group']); $name = trim($_REQUEST['name']); $phonebookEntry=array('name' => $name, 'uri' => $uri, 'group' => $group ); //dprint_r($phonebookEntry); dprint("updatePhonebookEntry"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->updatePhoneBookEntry($this->sipId,$phonebookEntry); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function deletePhonebookEntry() { dprint("deletePhonebookEntry()"); $uri = strtolower($_REQUEST['uri']); dprint("deletePhonebookEntry"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->deletePhoneBookEntry($this->sipId,$uri); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function getPhoneBookEntries() { dprint("getPhoneBookEntries()"); if ($_REQUEST['task'] == 'search') { $search_text = trim($_REQUEST['uri']); } $group = trim($_REQUEST['group']); if (!strlen($search_text)) $search_text="%" ; $match=array('uri' => '%'.$search_text.'%', 'name' => '%'.$search_text.'%' ); if (strlen($group)) { if ($group=="empty") { $match['group']=''; } else { $match['group']=$group; } } $range=array('start'=>0, 'count'=>100); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getPhoneBookEntries($this->sipId,$match,$range); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $this->PhonebookEntries=$result->entries; //dprint_r($this->PhonebookEntries); } function showContactsTab() { dprint("showContactsTab()"); if ($this->show_directory) { $chapter=sprintf(_("Directory")); $this->showChapter($chapter); print "

"; print _("To find other SIP Addresses fill in the First Name or the Last Name and click the Search button. "); print "
"; $this->showSearchDirectory(); print "
"; } if ($this->rows || $_REQUEST['task']=='directory') { // hide local contacts if we found a global contact return true; } $chapter=sprintf(_("Don't Disturb")).' '.sprintf(_("Groups")); $this->showChapter($chapter); print "
"; print _("You can organize contacts into groups that can be used to accept incoming calls in Don't Disturb section. "); print "
"; $adminonly = $_REQUEST['adminonly']; $accept = $_REQUEST['accept']; // selected search group; $task = $_REQUEST['task']; //if ($task == "search" ){ $search_text = $_REQUEST['uri']; // } $confirm = $_REQUEST['confirm']; $group = $_REQUEST['group']; $uri = $_REQUEST['uri']; $name = $_REQUEST['name']; if ($task=="deleteContact" && $confirm) { $this->deletePhonebookEntry(); unset($task); unset($confirm); } else if ($task=="update") { $this->updatePhonebookEntry(); unset($task); } else if ($task=="add") { $this->addPhonebookEntry(); unset($task); } $this->getPhoneBookEntries(); $maxrowsperpage=250; $url_string=$this->url."&tab=contacts"; print "
url method=post>
"; if (count($this->PhonebookEntries) || $task=="search"){ $selected[$group]="selected"; print ""; print ""; } print "
"; print _("(wildcard %)"); print "
"; print "
"; if (count($this->PhonebookEntries)){ print "

"; print ""; print ""; print ""; print ""; foreach(array_keys($this->PhonebookEntries) as $_entry) { $found=$i+1; $rr=floor($found/2); $mod=$found-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print " url&tab=$this->tab\"> $this->hiddenElements tab\"> "; printf ("",$this->PhonebookEntries[$_entry]->uri); print " "; if ($task=="deleteContact" && $uri==$this->PhonebookEntries[$_entry]->uri) { print " "; $i++; } print "
"; print ""; print _("SIP Address"); print ""; print ""; print ""; print _("Display Name"); print ""; print _("Group"); print ""; print _("Action"); print "
$found "; print $this->PhonebookEntries[$_entry]->uri; if (preg_match("/\%/",$this->PhonebookEntries[$_entry]->uri)) { printf (" "); } else { printf (" %s ", $this->PhoneDialURL($this->PhonebookEntries[$_entry]->uri)); } printf ("
",$this->PhonebookEntries[$_entry]->name); printf ("%s
",_("Update")); print "
"; printf (""; print " "; printf ("",$url_string,urlencode($this->PhonebookEntries[$_entry]->uri),urlencode($search_text)); print _("Confirm"); } else { print " "; printf ("",$url_string,urlencode($this->PhonebookEntries[$_entry]->uri),urlencode($search_text)); if ($this->delete_img) { //print $this->delete_img; print ""; } else { print _("Delete"); } } print ""; print "
"; print " "; } } function exportPhonebook($userAgent) { dprint("exportPhonebook()"); $this->getPhonebookEntries(); $this->contentType="Content-type: text/csv"; if (!is_array($this->PhonebookEntries) || !count($this->PhonebookEntries)) return true; if (!$userAgent) $userAgent='snom'; if ($userAgent=='snom') { $this->export_filename="tbook.csv"; $phonebook.=sprintf("Name,Address,Group\n"); } else if ($userAgent == 'eyebeam') { $phonebook.=sprintf("Name,Group Name,SIP URL,Proxy ID\n"); } else if ($userAgent == 'csco') { $this->contentType="Content-type: text/xml"; $this->export_filename="directory.xml"; $phonebook.=sprintf ("\n\t%s\n\tDirectory\n",$this->account); } else if ($userAgent == 'unidata') { $this->export_filename="phonebook.csv"; $phonebook.=sprintf("Index,Name,,,,\n"); $phonebook.=sprintf("0,Undefined,,,,\n"); $z=1; foreach($this->PhonebookGroups as $_group) { $this->groupIndex[$_group]=$z; $phonebook.=sprintf ("%s,%s,,,,\n",$z,$_group); $z++; } $phonebook.=sprintf("\nIndex,Name,RdNm,Tel,Group\n"); } $found=0; foreach (array_keys($this->PhonebookEntries) as $_entry) { $fname = $this->PhonebookEntries[$_entry]->firstName; $lname = $this->PhonebookEntries[$_entry]->lastName; $uri = $this->PhonebookEntries[$_entry]->uri; $group = $this->PhonebookEntries[$_entry]->group; if (!preg_match("/[_%]/",$uri)) { $uri=substr($uri,4); $els=explode("@",$uri); if ($els[1]==$this->domain) $uri=$els[0]; if ($userAgent=='snom') { $phonebook.=sprintf ("%s %s,%s,%s\n",$fname,$lname,$uri,$this->PhonebookGroups[$group]); } else if ($userAgent == 'unidata' && $fname && $lname) { $phonebook.=sprintf ("%s,%s,%s %s,%s,%s\n",$found,$fname,$fname,$lname,$uri,$this->PhonebookGroups[$group]); } else if ($userAgent == 'eyebeam') { $phonebook.=sprintf ("%s %s,%s,1\n",$fname,$lname,$this->PhonebookEntries[$_entry]->uri,$this->PhonebookGroups[$group]); } else if ($userAgent == 'csco') { $phonebook.=sprintf ("\n\t\n\t%s %s\n\t%s\n\t\n",$fname,$lname,$uri); } $found++ ; } } if ($userAgent == 'csco') { $phonebook.=sprintf ("\n\n"); } Header($this->contentType); $_header=sprintf("Content-Disposition: inline; filename=%s",$this->export_filename); Header($_header); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Pragma: no-cache"); print $phonebook; } function getRejectMembers() { dprint("getRejectMembers()"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getRejectMembers($this->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $this->rejectMembers=$result; //dprint_r($this->rejectMembers); return true; } function setRejectMembers() { $members=array(); $rejectMembers=$_REQUEST['rejectMembers']; foreach ($rejectMembers as $_member) { if (strlen($_member) && !preg_match("/^sip:/",$_member)) { $_member = 'sip:'.$_member; } if (strlen($_member)) $members[]=$_member; } dprint("setRejectMembers"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setRejectMembers($this->sipId,$members); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } function getJournalEntries() { $this->journalEntries['success'] = false; $this->journalEntries['error_message'] = NULL; $this->journalEntries['results'] = array(); $return_summary = $_REQUEST['summary']; if ($this->chat_replication_backend == 'mysql') { $this->db = new DB_CDRTool(); $where=""; if ($_REQUEST['except_uuid']) { $where.= sprintf(" and uuid <> '%s'", addslashes($_REQUEST['except_uuid'])); } if ($_REQUEST['after_id']) { $after_id = intval($_REQUEST['after_id']); } else { $after_id = 0; } $where.= sprintf(" and id > %d", addslashes($after_id)); if ($_REQUEST['after_timestamp']) { $where.= sprintf(" and timestamp > '%s'", addslashes($_REQUEST['after_timestamp'])); } if ($_REQUEST['limit'] and intval($_REQUEST['limit']) < 5000) { $limit = intval($limit); } else { $limit = 5000; } $query=sprintf("select * from client_journal where account = '%s' %s order by timestamp ASC limit %d", addslashes($this->account), $where, $limit); if (!$this->db->query($query)) { $this->journalEntries['error_message'] = 'Database Failure'; $this->journalEntries['rows'] = 0; return false; } else { $this->journalEntries['success'] = true; $this->journalEntries['rows'] = $this->db->num_rows(); } if ($this->db->num_rows()) { while ($this->db->next_record()) { $entry = array( 'id' => $this->db->f('id'), 'source' => 'default', 'timestamp' => $this->db->f('timestamp'), 'account' => $this->db->f('account'), 'uuid' => $this->db->f('uuid'), 'ip_address' => $this->db->f('ip_address'), 'data' => $this->db->f('data') ); $this->journalEntries['results'][]=$entry; } } } else { if (!$this->getMongoJournalTable()) { $result['success'] = false; $result['error_message'] = $this->mongo_exception; return $result; } $mongo_where=array(); $mongo_where['account'] = $this->account; if ($_REQUEST['except_uuid']) { $mongo_where['uuid'] = array('$ne' => $_REQUEST['except_uuid']); } if ($_REQUEST['after_timestamp']) { $mongo_where['timestamp'] = array('$gt' => intval($_REQUEST['after_timestamp'])); } if ($_REQUEST['limit'] and intval($_REQUEST['limit']) < 5000) { $limit = intval($limit); } else { $limit = 5000; } $cursor = $this->mongo_table_ro->find($mongo_where)->sort(array('timestamp'=>1))->limit($limit)->slaveOkay(); $this->journalEntries['success'] = true; $this->journalEntries['rows'] = $cursor->count(); foreach ($cursor as $result) { $entry = array( 'id' => strval($result['_id']), 'source' => 'default', 'timestamp' => $result['timestamp'], 'account' => $result['account'], 'uuid' => $result['uuid'], 'ip_address' => $result['ip_address'], 'data' => $result['data'] ); $this->journalEntries['results'][]=$entry; } if ($return_summary) { $mongo_where=array(); $mongo_where['account'] = $this->account; if ($_REQUEST['except_uuid']) { $mongo_where['uuid'] = array('$ne' => $_REQUEST['except_uuid']); } if ($_REQUEST['limit'] and intval($_REQUEST['limit']) < 5000) { $limit = intval($limit); } else { $limit = 5000; } $cursor = $this->mongo_table_ro->find($mongo_where)->sort(array('timestamp'=>1))->limit($limit)->slaveOkay(); foreach ($cursor as $result) { $entry = array( 'journal_id' => strval($result['_id']), 'timestamp' => $result['timestamp'], ); $this->journalEntries['summary'][]=$entry; } } } return True; } function putJournalEntries() { $result['results'] = array(); if (strlen($_REQUEST['uuid'])) { $uuid = $_REQUEST['uuid']; } else { $result['success'] = false; $result['error_message'] = 'Missing uuid'; return $result; } if (strlen($_REQUEST['data'])) { $data = $_REQUEST['data']; } else { $result['success'] = false; $result['error_message'] = 'Missing data'; return $result; } if ($this->chat_replication_backend == 'mysql') { $this->db = new DB_CDRTool(); } else if ($this->chat_replication_backend == 'mongo') { if (!$this->getMongoJournalTable()) { $result['success'] = false; $result['error_message'] = $this->mongo_exception; return $result; } } if ($rows=json_decode($data)) { foreach ($rows as $row) { if (!property_exists($row, 'data')) { continue; } $entry = $row->data; if (property_exists($row, 'action')) { $action = $row->action; } else { $action = 'add'; } if ($this->chat_replication_backend == 'mysql') { $query=sprintf("insert into client_journal (timestamp, account, uuid, data, ip_address) values (NOW(),'%s', '%s', '%s', '%s')", addslashes($this->account), addslashes($uuid), addslashes($entry), addslashes($_SERVER['REMOTE_ADDR'])); if (!$this->db->query($query)) { $result['results'][]=array('id' => $row->id, 'journal_id' => NULL, 'source' => 'default' ); } else { $query="select LAST_INSERT_ID() as id"; $this->db->query($query); $this->db->next_record(); $id = $this->db->f('id'); $result['results'][]=array('id' => $row->id, 'journal_id' => $id, 'source' => 'default' ); } } else if ($this->chat_replication_backend == 'mongo') { if ($action == 'add') { $timestamp = time(); $mongo_query=array('timestamp' => $timestamp, 'datetime' => Date("Y-m-d H:i:s", $timestamp), 'account' => $this->account, 'uuid' => $uuid, 'data' => $entry, 'ip_address' => $_SERVER['REMOTE_ADDR'] ); $this->mongo_table_rw->insert($mongo_query); if ($mongo_query['_id']) { $mongo_id = strval($mongo_query['_id']); $result['results'][]=array('id' => $row->id, 'journal_id' => $mongo_id, 'source' => 'default' ); } else { $result['results'][]=array('id' => $row->id, 'journal_id' => NULL, 'source' => 'default' ); } } else if ($action == 'remove') { if (property_exists($row, 'journal_id')) { $mongo_query=array( 'account' => $this->account, 'journal_id' => $row->journal_id ); $this->mongo_table_rw->remove($mongo_query); $result['results'][]=array('id' => NULL, 'journal_id' => $row->journal_id ); } } } } $result['success'] = true; } else { $result['success'] = false; $result['error_message'] = 'Json decode error'; } return $result; } function deleteJournalEntries() { if (strlen($_REQUEST['data'])) { $data = $_REQUEST['data']; $entries = json_decode($data); } else { if (strlen($_REQUEST['journal_id'])) { $entries=array($_REQUEST['journal_id']); } else { $result['success'] = false; $result['error_message'] = 'Missing data'; return $result; } } if ($this->chat_replication_backend == 'mysql') { $this->db = new DB_CDRTool(); } else if ($this->chat_replication_backend == 'mongo') { if (!$this->getMongoJournalTable()) { $result['success'] = false; $result['error_message'] = $this->mongo_exception; return $result; } } if ($entries) { if ($this->chat_replication_backend == 'mysql') { $journal_id_sql=""; foreach ($entries as $entry) { $journal_id_sql.=sprintf("'%s',",$entry); } $journal_id_sql = rtrim($journal_id_sql,","); $query=sprintf("delete from client_journal where account in '%s' and journal_id in (%s)", addslashes($this->account), addslashes($journal_id_sql)); if (!$this->db->query($query)) { $result['error_message'] = 'database error'; } else { $result['success'] = true; } } else if ($this->chat_replication_backend == 'mongo') { $id_entries=array(); foreach ($entries as $entry) { $id_entries[] = new MongoId($entry); } $mongo_query=array('account' => $this->account, '_id' => array('$in'=> $id_entries) ); $this->mongo_table_rw->remove($mongo_query); $result['success'] = true; } } else { $result['success'] = false; $result['error_message'] = 'No journal entries provided'; } return $result; } function getAcceptRules() { dprint("getAcceptRules()"); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->getAcceptRules($this->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } foreach(array_keys($result->rules->persistent) as $_rule) { $_key=$result->rules->persistent[$_rule]->days; $this->acceptRules['persistent'][$_key]=array('start' =>$result->rules->persistent[$_rule]->start, 'stop' =>$result->rules->persistent[$_rule]->stop, 'groups'=>$result->rules->persistent[$_rule]->groups); } $this->acceptRules['temporary']=array('groups' => $result->rules->temporary->groups, 'duration'=> $result->rules->temporary->duration ); $this->acceptRules['groups'] = $result->nonEmptyGroups; //dprint_r($this->acceptRules); return true; } function setAcceptRules() { dprint("setAcceptRules()"); $persistentAcceptArray=array(); $temporaryAcceptArray=array(); foreach (array_keys($this->acceptDailyProfiles) as $profile) { unset($groups); $radio_persistentVarName='radio_persistent_'.$profile; $radio_persistent=$_REQUEST[$radio_persistentVarName]; if ($radio_persistent=="0") { $groups[]='everybody'; } else if ($radio_persistent=="1") { $groups[]='nobody'; } else if ($radio_persistent=="2") { $groupsVarName='groups_'.$profile; $groups=$_REQUEST[$groupsVarName]; } $startVarName='start_'.$profile; $start=$_REQUEST[$startVarName]; $stopVarName='stop_'.$profile; $stop=$_REQUEST[$stopVarName]; if (!preg_match("/^[0-2][0-9]:[0-5][0-9]$/",$start) || !preg_match("/^[0-2][0-9]:[0-5][0-9]$/",$stop) || ($start=="00:00" && $stop=="00:00") || !$start || !$stop || ($radio_persistent=="2" && (!is_array($groups) || !count($groups) )) ) { continue; } $persistentAcceptArray[]=array('start' => $start, 'stop' => $stop, 'groups' => $groups, 'days' => intval($profile) ); } // temporary $radio_temporary=$_REQUEST['radio_temporary']; unset($groups_temporary); if ($radio_temporary=="0") { $groups_temporary[]='everybody'; } else if ($radio_temporary=="1") { $groups_temporary[]='nobody'; } else if ($radio_temporary=="2") { $groups_temporary=$_REQUEST['groups_temporary']; } if (!is_array($groups_temporary)) $groups_temporary=array(); $duration=$_REQUEST['duration']; $temporaryAccept=array("groups" => $groups_temporary, "duration"=> intval($duration) ); // combine persistent and temporary $rules=array("persistent" =>$persistentAcceptArray, "temporary" =>$temporaryAccept); $this->SipPort->addHeader($this->SoapAuth); $result = $this->SipPort->setAcceptRules($this->sipId,$rules); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } return true; } function showAcceptTab() { $chapter=sprintf(_("Do Not Disturb")); $this->showChapter($chapter); $this->getAcceptRules(); $this->getVoicemail(); $this->getDivertTargets(); $this->getDiversions(); print "

"; print "

"; print _("You can reject calls depending on the time of day and Caller-ID. "); print _("You can create custom groups in the Contacts page like Family or Coworkers. "); print "

"; print _("Rejected calls are diverted based on the Unavailable condition in the Call Forwarding page. "); print "

"; print "

"; printf (_("Your current time is: %s"),$this->timezone); $timestamp=time(); $LocalTime=getLocalTime($this->timezone,$timestamp); print " $LocalTime"; print "

"; // $chapter=sprintf(_("Rules")); // $this->showChapter($chapter); /* print "
"; print _("This will override the permanent rules for the chosen duration. "); print "
"; */ if ($this->acceptRules['temporary']['duration']) { $class_e='error'; } else { $class_e=''; } // print "
// //"; // print ""; // print _("minute(s)"); // print ""; //print "
//
//"; $chapter=sprintf(_("Rules")); $this->showChapter($chapter); print "
"; print ""; print ""; print ""; $_name="radio_temporary"; $_checked_everybody=""; $_checked_nobody=""; $_checked_groups=""; if (is_array($this->acceptRules['temporary']['groups']) &&in_array("everybody",$this->acceptRules['temporary']['groups'])) { $_checked_everybody="checked"; } else if (is_array($this->acceptRules['temporary']['groups']) && in_array("nobody",$this->acceptRules['temporary']['groups'])) { $_checked_nobody="checked"; } else if (!in_array('everybody',$this->acceptRules['temporary']['groups']) && !in_array('nobody',$this->acceptRules['temporary']['groups']) && count($this->acceptRules['temporary']['groups'])) { $_checked_groups="checked"; } if ($_checked_nobody) { $class_nobody="checked_groups"; } else { $class_nobody="note"; } printf (" ",$_name,$_checked_everybody,_("Everybody")); printf ("",$_name,$_checked_nobody,_("Nobody")); $c=count($this->acceptRules['groups']); if ($_checked_groups) { $class_groups="checked_groups"; } else { $class_groups="note"; } print ""; print " "; foreach (array_keys($this->acceptDailyProfiles) as $profile) { if ($this->acceptRules['persistent'][$profile]['start'] || $this->acceptRules['persistent'][$profile]['stop']) { $class="checked_groups"; $class2="label label-info"; } else { $class="mhj"; $class2=''; } if ($profile==1) { print ""; } print " "; unset($selected_StartTime); $selected_StartTime[$this->acceptRules['persistent'][$profile]['start']]="selected"; printf ("",$_name,$_checked_everybody,_("Everybody")); printf ("",$_name,$_checked_nobody,_("Nobody")); $c=count($this->acceptRules['groups']); if ($_checked_groups) { $class_groups="checked_groups"; } else { $class_groups="note"; } print " "; } print "
"; print _("Temporary"); print "
"; print _("Duration"); print ""; if ($this->acceptRules['temporary']['duration']) { printf (' ',$this->acceptRules['temporary']['duration']); print " acceptRules['temporary']['duration']; print "\" disabled=true>"; print " acceptRules['temporary']['duration']; print "\"> "; } else { print " "; print _("Minute(s)"); print ""; } print " %s %s "; if (count($this->acceptRules['groups'])>2) { printf ("",$_name,$_checked_groups); $i=0; foreach(array_keys($this->acceptRules['groups']) as $_group) { $i++; if (preg_match("/(everybody|nobody)/",$this->acceptRules['groups'][$_group])) continue; if (in_array($this->acceptRules['groups'][$_group],$this->acceptRules['temporary']['groups'])) { $_checked="checked"; } else { $_checked=""; } $_name="groups_temporary[]"; printf (" %s\n", $_name, $this->acceptRules['groups'][$_group], $_checked, $this->PhonebookGroups[$this->acceptRules['groups'][$_group]] ); } } print "
"; print _("Permanent"); print "
"; print _("Days"); print " "; print _("Time Interval"); print " "; print _("Groups"); print "
"; printf ("%s",$this->acceptDailyProfiles[$profile]); print ""; unset($selected_StopTime); $selected_StopTime[$this->acceptRules['persistent'][$profile]['stop']]="selected"; printf (""; $_name="radio_persistent_".$profile; $_checked_everybody=""; $_checked_nobody=""; $_checked_groups=""; if (is_array($this->acceptRules['persistent'][$profile]['groups']) && in_array("everybody",$this->acceptRules['persistent'][$profile]['groups'])) { $_checked_everybody="checked"; } else if (is_array($this->acceptRules['persistent'][$profile]['groups']) && in_array("nobody",$this->acceptRules['persistent'][$profile]['groups'])) { $_checked_nobody="checked"; } else if (!in_array('everybody',$this->acceptRules['persistent'][$profile]['groups']) && !in_array('nobody',$this->acceptRules['persistent'][$profile]['groups']) && count($this->acceptRules['persistent'][$profile]['groups'])) { $_checked_groups="checked"; } else { $_checked_everybody="checked"; } if ($_checked_nobody) { $class_nobody="checked_groups"; } else { $class_nobody="note"; } printf (" %s %s"; if (count($this->acceptRules['groups'])>2) { printf ("",$_name,$_checked_groups); $i=0; foreach(array_keys($this->acceptRules['groups']) as $_group) { $i++; if (preg_match("/(everybody|nobody)/",$this->acceptRules['groups'][$_group])) continue; if (in_array($this->acceptRules['groups'][$_group],$this->acceptRules['persistent'][$profile]['groups'])) { $_checked="checked"; } else { $_checked=""; } $_name="groups_".$profile."[]"; printf (" %s ", $_name, $this->acceptRules['groups'][$_group], $profile, $_checked, $this->PhonebookGroups[$this->acceptRules['groups'][$_group]] ); } } print "
"; print "
"; print " "; print "
"; print $this->hiddenElements; print " "; $chapter=sprintf(_("Rejected Callers")); $this->showChapter($chapter); print "
"; print "
"; print _("Use %Number@% to match PSTN numbers and user@domain to match SIP Addresses"); print "
"; if ($this->getRejectMembers()) { foreach ($this->rejectMembers as $_member) { $j++; $rr=floor($j/2); $mod=$j-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } print "
"; print ""; print "
"; print "
"; } } print "
"; print ""; print "
"; print "
"; print "
"; print " "; print "
"; print " "; print $this->hiddenElements; print " "; } function sendEmail($skip_html=False) { dprint ("SipSettings->sendEmail($this->email)"); $this->getVoicemail(); $this->getEnumMappings(); $this->getAliases(); $this->countAliases=count($this->aliases); if (!$this->email && !$skip_html) { print "

"; print _("Please fill in the e-mail address. "); print ""; return false; } $subject = sprintf("SIP Account settings %s",$this->account); //if ($_REQUEST['sip_filter'] == '1') { // $identifier = $this->RandomIdentifier(); //} $tpl = $this->getEmailTemplate($this->reseller, $this->Preferences['language']); if (!$tpl && !$skip_html) { print "

"; print _("Error: no email template found"); print ""; return false; } $tpl_html = $this->getEmailTemplateHTML($this->reseller, $this->Preferences['language']); //if (!$tpl_html && !$skip_html) { // print "

"; // print _("Error: no HTML email template found"); // print ""; //} if (in_array("free-pstn",$this->groups)) $this->allowPSTN=1; // used by smarty define("SMARTY_DIR", "/usr/share/php/smarty/libs/"); include_once(SMARTY_DIR . 'Smarty.class.php'); $smarty = new Smarty; $smarty->template_dir = '.'; //$smarty->use_sub_dirs = true; //$smarty->cache_dir = 'templates_c'; $smarty->assign('client', $this); $bodyt = $smarty->fetch($tpl); if ($tpl_html) { $bodyhtml = $smarty->fetch($tpl_html); } include 'Mail.php'; include 'Mail/mime.php' ; $hdrs = array( 'From' => $this->support_email, 'Subject' => $subject ); $crlf = "\n"; $mime = new Mail_mime($crlf); $mime->setTXTBody($bodyt); if ($tpl_html) { $mime->setHTMLBody($bodyhtml); } $body = $mime->get(); $hdrs = $mime->headers($hdrs); $mail =& Mail::factory('mail'); //dprint_r($_REQUEST); if ($mail->send($this->email, $hdrs, $body)) { if (!$skip_html) { print "

"; printf (_("SIP settings have been sent to %s"), $this->email); } if ($_REQUEST['password_reset'] == 'on') { $this->sendPasswordReset($skip_html); } return 1; } } function sendPasswordReset($skip_html=False) { dprint ("SipSettings->sendPasswordEmail($this->email)"); $identifier = RandomIdentifier(); $this->db = new DB_CDRTool(); $this->ip = $_SERVER['REMOTE_ADDR']; $insert_data = array ( 'sip_account' => $this->account, 'email' => $this->email, 'ip' => $this->ip ); $this->expire=date("Y-m-d H:i:s",strtotime("+30 minutes")); $query=sprintf("insert into memcache set `key`='email_%s', `value`='%s', `expire`='%s'", $identifier, json_encode($insert_data), $this->expire ); $this->db->query($query); $this->identifier = $identifier; dprint("$query
Identifier: $identifier"); if (!$this->email && !$skip_html) { print "

"; print _("Please fill in the e-mail address. "); print ""; return false; } $subject = sprintf("Password reset for %s",$this->account); $tpl_html = $this->getEmailPasswordTemplateHTML($this->reseller, $this->Preferences['language']); define("SMARTY_DIR", "/usr/share/php/smarty/libs/"); include_once(SMARTY_DIR . 'Smarty.class.php'); $smarty = new Smarty; $smarty->template_dir = '.'; //$smarty->use_sub_dirs = true; //$smarty->cache_dir = 'templates_c'; $smarty->assign('client', $this); $bodyhtml = $smarty->fetch($tpl_html); include_once 'Mail.php'; include_once 'Mail/mime.php' ; $hdrs = array( 'From' => $this->support_email, 'Subject' => $subject ); $crlf = "\n"; $mime = new Mail_mime($crlf); $mime->setHTMLBody($bodyhtml); $body = $mime->get(); $hdrs = $mime->headers($hdrs); $mail =& Mail::factory('mail'); //dprint_r($_REQUEST); if ($mail->send($this->email, $hdrs, $body) && !$skip_html) { print "

  • "; printf (_("Password reset has been sent to %s"), $this->email); print "
  • "; } return 1; } function checkSettings() { dprint ("checkSettings()"); foreach ($this->form_elements as $el) { ${$el}=trim($_REQUEST[$el]); } if ($accept_temporary_remain && !is_numeric($accept_temporary_remain)) { $this->error=_("Invalid Expiration Period"); return false; } if ($quota && !is_numeric($quota) && !is_float($quota)) { $this->error=_("Invalid Quota"); return false; } if (!$timezone && !$this->timezone) { $this->error=_("Missing Timezone"); return false; } if (!$this->checkEmail($mailto)) { $this->error=_("Invalid E-mail Address"); return false; } $rpid=preg_replace("/[^0-9\x]/","",$rpid); if (preg_match("/^0+([1-9]\d*)$/",$rpid,$m)) $rpid=$m[1]; $quickdial=preg_replace("/[^0-9]/","",$quickdial); if (!strlen($accept_temporary_group)) $accept_temporary_remain=0; if (!$accept_temporary_remain) $accept_temporary_group=""; if (!$anonymous) $anonymous="0"; return true; } function RandomPassword($len=6) { $alf=array("1","2","3","4","5","6","7","8","9"); $i=0; while($i < $len) { srand((double)microtime(true)*1000000); $randval = rand(0,8); $string="$string"."$alf[$randval]"; $i++; } return $string; } function cleanURI($uri) { $uri=preg_replace("/.*sips?:([^;><=]+).*/", "\$1", $uri); return urlencode($uri); } function showUpgradeTab () { } function PhoneDialURL($uri) { $uri=$this->normalizeURI($uri); if (!preg_match("/^sip:/",$uri)) { $uri="sip:".$uri; } $uri_print="$this->call_img"; return $uri_print; } function showChapter($chapter) { print "

    "; print $chapter; print "

    "; } function normalizeURI($uri) { $uri=quoted_printable_decode($uri); $uri=preg_replace("/.*(sips?:[^;><=]+).*/", "\$1", $uri); if (preg_match("/^(sips?:.*):/", $uri, $m)) $uri=$m[1]; if (preg_match("/^(.*sips?:0\d+)@(.*)(>?)$/",$uri,$m)) { $uri=$m[1]."@".$this->domain.$m[3]; } return $uri; } function htmlURI($uri) { if (preg_match("/^sips?:00(\d+)@/",$uri,$m)) { $uri="+".$m[1]; } return htmlentities($uri); } function colorizeDate($call_date) { list($date,$time)=explode(" ",$call_date); if ($date== Date("Y-m-d",time())) { $datePrint="".sprintf(_("Today"))." ".$time; } else if ($date== Date("Y-m-d",time()-3600*24)) { $datePrint="".sprintf(_("Yesterday"))." ".$time; } else { $datePrint=$call_date; } return $datePrint; } function checkEmail($email) { dprint ("checkEmail($email)"); $regexp = "/^([a-z0-9][a-z0-9_.-]*)@([a-z0-9][a-z0-9-]*\.)+([a-z]{2,})$/i"; if (stristr($email,"-.") || !preg_match($regexp, $email)) { return false; } return true; } function getFileTemplate($name, $type="file") { dprint("getFileTemplate(name=$name, type=$type, path=$this->templates_path)"); if ($type=='logo') { $extensions=array('png','gif','jpg'); foreach ($extensions as $_ext) { $file=$this->templates_path.'/'.$this->reseller.'/'.$name.'.'.$_ext; if (file_exists($file)) { return $file; } } foreach ($extensions as $_ext) { if (file_exists("$this->templates_path/default/$name.$_ext")) { return "$this->templates_path/default/$name.$_ext"; } } return false; } else { if (file_exists("$this->templates_path/$this->reseller/$name")) { return "$this->templates_path/$this->reseller/$name"; } elseif (file_exists("$this->templates_path/default/$name")) { return "$this->templates_path/default/$name"; } else { return false; } } } function getEmailTemplate($reseller, $language='en') { $file = "sip_settings_email_$language.tpl"; $file2 = "sip_settings_email.tpl"; //print("templates_path = $this->templates_path"); if (file_exists("$this->templates_path/$this->reseller/$file")) { return "$this->templates_path/$this->reseller/$file"; } elseif (file_exists("$this->templates_path/$this->reseller/$file2")) { return "$this->templates_path/$this->reseller/$file2"; } elseif (file_exists("$this->templates_path/default/$file")) { return "$this->templates_path/default/$file"; } elseif (file_exists("$this->templates_path/default/$file2")) { return "$this->templates_path/default/$file2"; } else { return false; } } function getEmailTemplateHTML($reseller, $language='en') { $file = "sip_settings_email_$language.html.tpl"; $file2 = "sip_settings_email.html.tpl"; //print("templates_path = $this->templates_path"); if (file_exists("$this->templates_path/$this->reseller/$file")) { return "$this->templates_path/$this->reseller/$file"; } elseif (file_exists("$this->templates_path/$this->reseller/$file2")) { return "$this->templates_path/$this->reseller/$file2"; } elseif (file_exists("$this->templates_path/default/$file")) { return "$this->templates_path/default/$file"; } elseif (file_exists("$this->templates_path/default/$file2")) { return "$this->templates_path/default/$file2"; } else { return false; } } function getEmailPasswordTemplateHTML($reseller, $language='en') { $file = "password_reminder_$language.html.tpl"; $file2 = "password_reminder.html.tpl"; //print("templates_path = $this->templates_path"); if (file_exists("$this->templates_path/$this->reseller/$file")) { return "$this->templates_path/$this->reseller/$file"; } elseif (file_exists("$this->templates_path/$this->reseller/$file2")) { return "$this->templates_path/$this->reseller/$file2"; } elseif (file_exists("$this->templates_path/default/$file")) { return "$this->templates_path/default/$file"; } elseif (file_exists("$this->templates_path/default/$file2")) { return "$this->templates_path/default/$file2"; } else { return false; } } function getBillingProfiles() { dprint("getBillingProfiles()"); // Get getBillingProfiles $this->RatingPort->addHeader($this->SoapAuthRating); $result = $this->RatingPort->getEntityProfiles("subscriber://".$this->account); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "4001") { printf ("

    Error (Rating): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } $this->billingProfiles=$result; } function showBillingProfiles() { if ($this->login_type != 'reseller' && $this->login_type != 'admin') { return false; } if (!$this->pstn_changes_allowed) { return false; } $this->getBillingProfiles(); $chapter=sprintf(_("Billing Profiles")); $this->showChapter($chapter); print "

    / ", $this->billingProfiles->profileWeekday, $this->billingProfiles->profileWeekdayAlt ); print "
    "; print "
    / ", $this->billingProfiles->profileWeekend, $this->billingProfiles->profileWeekendAlt ); print "
    "; print "
    "); if ($this->billingProfiles->timezone) { $_timezone=$this->billingProfiles->timezone; } else { $_timezone=$this->resellerProperties['timezone']; } $this->showTimezones('profileTimezone',$_timezone); print "
    "; } function updateBillingProfiles() { if ($this->login_type != 'reseller' && $this->login_type != 'admin') { return false; } if (!$this->pstn_changes_allowed) { return true; } $this->RatingPort->addHeader($this->SoapAuthRating); $result = $this->RatingPort->getEntityProfiles("subscriber://".$this->account); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "4001") { printf ("

    Error (Rating): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } $this->billingProfiles=$result; $profiles=array("entity" =>'subscriber://'.$this->account , "profileWeekday" => trim($_REQUEST['profileWeekday']), "profileWeekdayAlt" => trim($_REQUEST['profileWeekdayAlt']), "profileWeekend" => trim($_REQUEST['profileWeekend']), "profileWeekendAlt" => trim($_REQUEST['profileWeekendAlt']), "timezone" => trim($_REQUEST['profileTimezone']) ); //print_r($profiles); $this->RatingPort->addHeader($this->SoapAuthRating); if ($this->billingProfiles->profileWeekday && !$profiles['profileWeekday']) { // delete profile $result = $this->RatingPort->deleteEntityProfiles('subscriber://'.$this->account); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "4001") { printf ("

    Error (Rating): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } } else if ($profiles['profileWeekday']) { // update profile $result = $this->RatingPort->setEntityProfiles($profiles); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode != "4001") { printf ("

    Error (Rating): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } } } } function getImageForUserAgent($agent) { // array with mappings between User Agents and images foreach ($this->userAgentImages as $agentRegexp => $image) { if (preg_match("/$agentRegexp/i", $agent)) { return $image; } } return "unknown.png"; } function showExtraGroups () { if ($this->disable_extra_groups) return true; $foundGroupInAvailableGroups=array(); foreach ($this->groups as $_grp) { foreach (array_keys($this->availableGroups) as $a_grp) { if ($_grp == $a_grp) $foundGroupInAvailableGroups[]=$_grp; continue; } } $extraGroups = array_unique(array_diff($this->groups,$foundGroupInAvailableGroups)); foreach ($extraGroups as $_eg) { $extraGroups_text.=$_eg.' '; } if ($this->login_type == 'subscriber') { printf ("",trim($extraGroups_text)); } else { print "

    "; printf ("",trim($extraGroups_text)); print "
    "; } } function generateCertificate() { global $enrollment; include("/etc/cdrtool/enrollment/config.ini"); if (!is_array($enrollment)) { print _("Error: missing enrollment settings"); return false; } if (!$enrollment['ca_conf']) { //print _("Error: missing enrollment ca_conf settings"); return false; } if (!$enrollment['ca_crt']) { //print _("Error: missing enrollment ca_crt settings"); return false; } if (!$enrollment['ca_key']) { //print _("Error: missing enrollment ca_key settings"); return false; } $config = array( 'config' => $enrollment['ca_conf'], 'digest_alg' => 'md5', 'private_key_bits' => 1024, 'private_key_type' => OPENSSL_KEYTYPE_RSA, 'encrypt_key' => false, ); $dn = array( "countryName" => "NL", "stateOrProvinceName" => "Noord Holland", "localityName" => "Haarlem", "organizationName" => "AG Projects", "organizationalUnitName" => "Blink", "commonName" => $this->account, "emailAddress" => $this->email ); $this->key = openssl_pkey_new($config); if ($this->key==FALSE) { while (($e = openssl_error_string()) !== false) { echo $e . "\n"; print "

    "; } return false; } $this->csr = openssl_csr_new($dn, $this->key); if (!$this->csr) { while (($e = openssl_error_string()) !== false) { echo $e . "\n"; print "

    "; } return false; } $ca="file://".$enrollment['ca_crt']; $this->crt = openssl_csr_sign($this->csr, $ca, $enrollment['ca_key'], 3650, $config); if ($this->crt==FALSE) { while (($e = openssl_error_string()) !== false) { echo $e . "\n"; print "

    "; } return false; } openssl_csr_export ($this->csr, $this->csr_out); openssl_pkey_export ($this->key, $this->key_out, $this->password, $config); openssl_x509_export ($this->crt, $this->crt_out); openssl_pkcs12_export ($this->crt, $this->p12_out, $this->key, $this->password); $ret=array( 'csr' => $this->csr_out, 'crt' => $this->crt_out, 'key' => $this->key_out, 'pkey'=> $public_key, 'p12' => $this->p12_out, 'ca' => file_get_contents($enrollment['ca_crt']) ); return $ret; } function exportCertificateX509() { Header("Content-type: application/x-crt"); $header=sprintf("Content-Disposition: inline; filename=%s.crt",$this->account); Header($header); $cert=$this->generateCertificate(); $crt=$cert['crt'].$cert['key']; print $crt; } function exportCertificateP12() { $cert=$this->generateCertificate(); Header("Content-type: application/x-p12"); $header=sprintf("Content-Disposition: inline; filename=%s.p12",$this->account); Header($header); print $cert['p12']; } function isEmbedded() { // return true if page was loaded from non-session based web session if ($_SERVER['SSL_CLIENT_CERT'] || $_SERVER['PHP_AUTH_DIGEST']) { return true; } return false; } function changeLanguage($lang='en',$domain='cdrtool') { // run dpkg-reconfigure locales and select support languages .utf8 $lang = $this->languageCodeFor(isset($lang) ? $lang : 'en'); $lang.='.utf8'; setlocale(LC_ALL, $lang); bindtextdomain($domain, '/var/www/CDRTool/po/locale'); bind_textdomain_codeset($domain,'UTF-8'); textdomain($domain); } // return full language code for given 2 letter language code function languageCodeFor($lang='en') { $lang = isset($lang) ? strtolower($lang) : 'en'; switch ($lang) { case 'en': return 'en_US'; // this can be C or en_US case 'ja': return 'ja_JP'; default : return ($lang . '_' . strtoupper($lang)); } return 'C'; // this will never be reached } function showDirectorySearchForm () { print "
    url method=post> "; print $this->hiddenElements; print "
    "; print " ",$_REQUEST['firstname']); print "
    "; print "",$_REQUEST['lastname']); print ""; print "
    "; } function showSearchDirectory() { if (!$this->show_directory) { return false; } $this->maxrowsperpage=20; $this->showDirectorySearchForm(); if ($_REQUEST['firstname'] || $_REQUEST['lastname']) { if ($_REQUEST['firstname'] && strlen($_REQUEST['firstname']) < 3) { return false; } if ($_REQUEST['lastname'] && strlen($_REQUEST['lastname']) < 3) { return false; } } else { return false; } $this->next = $_REQUEST['next']; // Filter $filter=array('firstName'=> trim($_REQUEST['firstname']), 'lastName' => trim($_REQUEST['lastname']) ); // Range $range=array('start' => intval($this->next), 'count' => intval($this->maxrowsperpage) ); // Order if (!$this->sorting['sortBy']) $this->sorting['sortBy'] = 'changeDate'; if (!$this->sorting['sortOrder']) $this->sorting['sortOrder'] = 'DESC'; $orderBy = array('attribute' => $this->sorting['sortBy'], 'direction' => $this->sorting['sortOrder'] ); // Compose query $Query=array('filter' => $filter, 'orderBy' => $orderBy, 'range' => $range ); // Insert credetials $this->SipPort->addHeader($this->SoapAuthAdmin); // Call function $result = $this->SipPort->getAccounts($Query); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error from %s: %s (%s): %s",$this->SoapEngine->SOAPurl,$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $this->rows = $result->total; if (!$this->next) $this->next=0; if ($this->rows > $this->maxrowsperpage) { $maxrows = $this->maxrowsperpage + $this->next; if ($maxrows > $this->rows) $maxrows = $this->maxrowsperpage; } else { $maxrows=$this->rows; } if ($this->rows) { print "

    "; printf(_("%s contacts found. "),$this->rows); if ($this->isEmbedded()) { //printf (_("Click on %s to add a Contact to Blink. "),$this->plus_sign_img); } print "
    "; print ""; print ""; print ""; print ""; print " "; $i=0; while ($i < $maxrows) { if (!$result->accounts[$i]) break; $account = $result->accounts[$i]; $index=$this->next+$i+1; $rr=floor($index/2); $mod=$index-$rr*2; if ($mod ==0) { $_class='odd'; } else { $_class='even'; } $i++; $name=$account->firstName.' '.$account->lastName; $sip_account=sprintf("%s@%s",$account->id->username,$account->id->domain); $contacts_url=sprintf("%s",$this->url,$sip_account,urlencode($name),$sip_account,$this->phonebook_img); if ($this->isEmbedded()) { //$add_contact_url=sprintf("%s",$sip_account,$name,$this->plus_sign_img); printf ("", $_class, $index, $name, $sip_account, $account->timezone, $this->PhoneDialURL($sip_account), $add_contact_url ); } else { printf ("", $_class, $index, $name, $sip_account, $account->timezone, $this->PhoneDialURL($sip_account), $contacts_url ); } } print "
    "; print _('Display Name'); print ""; print _('SIP Address'); print ""; print _('Timezone'); print ""; print _('Action'); print "
    %d%s%s%s%s %s
    %d%s%s%s%s %s
    "; $this->showPagination($maxrows); return true; } } function showPagination($maxrows) { $url = sprintf("%s&tab=%s&firstname=%s&lastname%s", $this->url, $this->tab, urlencode($_REQUEST['firstname']), urlencode($_REQUEST['lastname']) ); print "

    "; if ($this->next != 0 ) { $show_next=$this->maxrowsperpage-$this->next; if ($show_next < 0) { $mod_show_next = $show_next-2*$show_next; } if (!$mod_show_next) $mod_show_next=0; if ($mod_show_next/$this->maxrowsperpage >= 1) { printf ("Begin ",$url); } printf ("Previous ",$url,$mod_show_next); } print " "; if ($this->next + $this->maxrowsperpage < $this->rows) { $show_next = $this->maxrowsperpage + $this->next; printf ("Next ",$url,$show_next); } print "
    "; } } function lookupGeoLocation($ip) { if ($_loc=geoip_record_by_name($ip)) { $_loc['timezone'] = get_time_zone($_loc['country_code'], $_loc['region']); $_loc['region'] = get_region($_loc['country_code'], $_loc['region']); $country_transition = array( "A1" => "N/A", "A2" => "N/A", "O1" => "N/A", "AP" => "N/A", "GB" => "UK"); if (array_key_exists($_loc['country_code'],$country_transition)) { $_loc['country_code'] = $country_transition[$_loc['country_code']]; } return $_loc; } else { return array(); } } function get_region($country, $region) { if ($country == "US" || $country =="CA" ) { $full_region = $region; // If region can't be found make it a default region to prevent NGNpro error if ($full_region == '' && $country == "US") { $full_region = "NY"; } else if ($full_region == '' && $country == "CA") { $full_region = "QC"; } } else { $full_region=''; } return $full_region; } function get_time_zone($country, $region) { switch ($country) { case "US": switch ($region) { case "AL": $timezone = "America/Chicago"; break; case "AK": $timezone = "America/Anchorage"; break; case "AZ": $timezone = "America/Phoenix"; break; case "AR": $timezone = "America/Chicago"; break; case "CA": $timezone = "America/Los_Angeles"; break; case "CO": $timezone = "America/Denver"; break; case "CT": $timezone = "America/New_York"; break; case "DE": $timezone = "America/New_York"; break; case "DC": $timezone = "America/New_York"; break; case "FL": $timezone = "America/New_York"; break; case "GA": $timezone = "America/New_York"; break; case "HI": $timezone = "Pacific/Honolulu"; break; case "ID": $timezone = "America/Denver"; break; case "IL": $timezone = "America/Chicago"; break; case "IN": $timezone = "America/Indianapolis"; break; case "IA": $timezone = "America/Chicago"; break; case "KS": $timezone = "America/Chicago"; break; case "KY": $timezone = "America/New_York"; break; case "LA": $timezone = "America/Chicago"; break; case "ME": $timezone = "America/New_York"; break; case "MD": $timezone = "America/New_York"; break; case "MA": $timezone = "America/New_York"; break; case "MI": $timezone = "America/New_York"; break; case "MN": $timezone = "America/Chicago"; break; case "MS": $timezone = "America/Chicago"; break; case "MO": $timezone = "America/Chicago"; break; case "MT": $timezone = "America/Denver"; break; case "NE": $timezone = "America/Chicago"; break; case "NV": $timezone = "America/Los_Angeles"; break; case "NH": $timezone = "America/New_York"; break; case "NJ": $timezone = "America/New_York"; break; case "NM": $timezone = "America/Denver"; break; case "NY": $timezone = "America/New_York"; break; case "NC": $timezone = "America/New_York"; break; case "ND": $timezone = "America/Chicago"; break; case "OH": $timezone = "America/New_York"; break; case "OK": $timezone = "America/Chicago"; break; case "OR": $timezone = "America/Los_Angeles"; break; case "PA": $timezone = "America/New_York"; break; case "RI": $timezone = "America/New_York"; break; case "SC": $timezone = "America/New_York"; break; case "SD": $timezone = "America/Chicago"; break; case "TN": $timezone = "America/Chicago"; break; case "TX": $timezone = "America/Chicago"; break; case "UT": $timezone = "America/Denver"; break; case "VT": $timezone = "America/New_York"; break; case "VA": $timezone = "America/New_York"; break; case "WA": $timezone = "America/Los_Angeles"; break; case "WV": $timezone = "America/New_York"; break; case "WI": $timezone = "America/Chicago"; break; case "WY": $timezone = "America/Denver"; break; } break; case "CA": switch ($region) { case "AB": $timezone = "America/Edmonton"; break; case "BC": $timezone = "America/Vancouver"; break; case "MB": $timezone = "America/Winnipeg"; break; case "NB": $timezone = "America/Halifax"; break; case "NL": $timezone = "America/St_Johns"; break; case "NT": $timezone = "America/Yellowknife"; break; case "NS": $timezone = "America/Halifax"; break; case "NU": $timezone = "America/Rankin_Inlet"; break; case "ON": $timezone = "America/Rainy_River"; break; case "PE": $timezone = "America/Halifax"; break; case "QC": $timezone = "America/Montreal"; break; case "SK": $timezone = "America/Regina"; break; case "YT": $timezone = "America/Whitehorse"; break; } break; case "AU": switch ($region) { case "01": $timezone = "Australia/Canberra"; break; case "02": $timezone = "Australia/NSW"; break; case "03": $timezone = "Australia/North"; break; case "04": $timezone = "Australia/Queensland"; break; case "05": $timezone = "Australia/South"; break; case "06": $timezone = "Australia/Tasmania"; break; case "07": $timezone = "Australia/Victoria"; break; case "08": $timezone = "Australia/West"; break; } break; case "AS": $timezone = "US/Samoa"; break; case "CI": $timezone = "Africa/Abidjan"; break; case "GH": $timezone = "Africa/Accra"; break; case "DZ": $timezone = "Africa/Algiers"; break; case "ER": $timezone = "Africa/Asmera"; break; case "ML": $timezone = "Africa/Bamako"; break; case "CF": $timezone = "Africa/Bangui"; break; case "GM": $timezone = "Africa/Banjul"; break; case "GW": $timezone = "Africa/Bissau"; break; case "CG": $timezone = "Africa/Brazzaville"; break; case "BI": $timezone = "Africa/Bujumbura"; break; case "EG": $timezone = "Africa/Cairo"; break; case "MA": $timezone = "Africa/Casablanca"; break; case "GN": $timezone = "Africa/Conakry"; break; case "SN": $timezone = "Africa/Dakar"; break; case "DJ": $timezone = "Africa/Djibouti"; break; case "SL": $timezone = "Africa/Freetown"; break; case "BW": $timezone = "Africa/Gaborone"; break; case "ZW": $timezone = "Africa/Harare"; break; case "ZA": $timezone = "Africa/Johannesburg"; break; case "UG": $timezone = "Africa/Kampala"; break; case "SD": $timezone = "Africa/Khartoum"; break; case "RW": $timezone = "Africa/Kigali"; break; case "NG": $timezone = "Africa/Lagos"; break; case "GA": $timezone = "Africa/Libreville"; break; case "TG": $timezone = "Africa/Lome"; break; case "AO": $timezone = "Africa/Luanda"; break; case "ZM": $timezone = "Africa/Lusaka"; break; case "GQ": $timezone = "Africa/Malabo"; break; case "MZ": $timezone = "Africa/Maputo"; break; case "LS": $timezone = "Africa/Maseru"; break; case "SZ": $timezone = "Africa/Mbabane"; break; case "SO": $timezone = "Africa/Mogadishu"; break; case "LR": $timezone = "Africa/Monrovia"; break; case "KE": $timezone = "Africa/Nairobi"; break; case "TD": $timezone = "Africa/Ndjamena"; break; case "NE": $timezone = "Africa/Niamey"; break; case "MR": $timezone = "Africa/Nouakchott"; break; case "BF": $timezone = "Africa/Ouagadougou"; break; case "ST": $timezone = "Africa/Sao_Tome"; break; case "LY": $timezone = "Africa/Tripoli"; break; case "TN": $timezone = "Africa/Tunis"; break; case "AI": $timezone = "America/Anguilla"; break; case "AG": $timezone = "America/Antigua"; break; case "AW": $timezone = "America/Aruba"; break; case "BB": $timezone = "America/Barbados"; break; case "BZ": $timezone = "America/Belize"; break; case "CO": $timezone = "America/Bogota"; break; case "VE": $timezone = "America/Caracas"; break; case "KY": $timezone = "America/Cayman"; break; case "CR": $timezone = "America/Costa_Rica"; break; case "DM": $timezone = "America/Dominica"; break; case "SV": $timezone = "America/El_Salvador"; break; case "GD": $timezone = "America/Grenada"; break; case "FR": $timezone = "Europe/Paris"; break; case "GP": $timezone = "America/Guadeloupe"; break; case "GT": $timezone = "America/Guatemala"; break; case "GY": $timezone = "America/Guyana"; break; case "CU": $timezone = "America/Havana"; break; case "JM": $timezone = "America/Jamaica"; break; case "BO": $timezone = "America/La_Paz"; break; case "PE": $timezone = "America/Lima"; break; case "NI": $timezone = "America/Managua"; break; case "MQ": $timezone = "America/Martinique"; break; case "UY": $timezone = "America/Montevideo"; break; case "MS": $timezone = "America/Montserrat"; break; case "BS": $timezone = "America/Nassau"; break; case "PA": $timezone = "America/Panama"; break; case "SR": $timezone = "America/Paramaribo"; break; case "PR": $timezone = "America/Puerto_Rico"; break; case "KN": $timezone = "America/St_Kitts"; break; case "LC": $timezone = "America/St_Lucia"; break; case "VC": $timezone = "America/St_Vincent"; break; case "HN": $timezone = "America/Tegucigalpa"; break; case "YE": $timezone = "Asia/Aden"; break; case "JO": $timezone = "Asia/Amman"; break; case "TM": $timezone = "Asia/Ashgabat"; break; case "IQ": $timezone = "Asia/Baghdad"; break; case "BH": $timezone = "Asia/Bahrain"; break; case "AZ": $timezone = "Asia/Baku"; break; case "TH": $timezone = "Asia/Bangkok"; break; case "LB": $timezone = "Asia/Beirut"; break; case "KG": $timezone = "Asia/Bishkek"; break; case "BN": $timezone = "Asia/Brunei"; break; case "IN": $timezone = "Asia/Calcutta"; break; case "MN": $timezone = "Asia/Choibalsan"; break; case "LK": $timezone = "Asia/Colombo"; break; case "BD": $timezone = "Asia/Dhaka"; break; case "AE": $timezone = "Asia/Dubai"; break; case "TJ": $timezone = "Asia/Dushanbe"; break; case "HK": $timezone = "Asia/Hong_Kong"; break; case "TR": $timezone = "Asia/Istanbul"; break; case "IL": $timezone = "Asia/Jerusalem"; break; case "AF": $timezone = "Asia/Kabul"; break; case "PK": $timezone = "Asia/Karachi"; break; case "NP": $timezone = "Asia/Katmandu"; break; case "KW": $timezone = "Asia/Kuwait"; break; case "MO": $timezone = "Asia/Macao"; break; case "PH": $timezone = "Asia/Manila"; break; case "OM": $timezone = "Asia/Muscat"; break; case "CY": $timezone = "Asia/Nicosia"; break; case "KP": $timezone = "Asia/Pyongyang"; break; case "QA": $timezone = "Asia/Qatar"; break; case "MM": $timezone = "Asia/Rangoon"; break; case "SA": $timezone = "Asia/Riyadh"; break; case "KR": $timezone = "Asia/Seoul"; break; case "SG": $timezone = "Asia/Singapore"; break; case "TW": $timezone = "Asia/Taipei"; break; case "GE": $timezone = "Asia/Tbilisi"; break; case "BT": $timezone = "Asia/Thimphu"; break; case "JP": $timezone = "Asia/Tokyo"; break; case "LA": $timezone = "Asia/Vientiane"; break; case "AM": $timezone = "Asia/Yerevan"; break; case "BM": $timezone = "Atlantic/Bermuda"; break; case "CV": $timezone = "Atlantic/Cape_Verde"; break; case "FO": $timezone = "Atlantic/Faeroe"; break; case "IS": $timezone = "Atlantic/Reykjavik"; break; case "GS": $timezone = "Atlantic/South_Georgia"; break; case "SH": $timezone = "Atlantic/St_Helena"; break; case "CL": $timezone = "Chile/Continental"; break; case "NL": $timezone = "Europe/Amsterdam"; break; case "AD": $timezone = "Europe/Andorra"; break; case "GR": $timezone = "Europe/Athens"; break; case "YU": $timezone = "Europe/Belgrade"; break; case "DE": $timezone = "Europe/Berlin"; break; case "SK": $timezone = "Europe/Bratislava"; break; case "BE": $timezone = "Europe/Brussels"; break; case "RO": $timezone = "Europe/Bucharest"; break; case "HU": $timezone = "Europe/Budapest"; break; case "DK": $timezone = "Europe/Copenhagen"; break; case "IE": $timezone = "Europe/Dublin"; break; case "GI": $timezone = "Europe/Gibraltar"; break; case "FI": $timezone = "Europe/Helsinki"; break; case "SI": $timezone = "Europe/Ljubljana"; break; case "GB": $timezone = "Europe/London"; break; case "LU": $timezone = "Europe/Luxembourg"; break; case "MT": $timezone = "Europe/Malta"; break; case "BY": $timezone = "Europe/Minsk"; break; case "MC": $timezone = "Europe/Monaco"; break; case "NO": $timezone = "Europe/Oslo"; break; case "CZ": $timezone = "Europe/Prague"; break; case "LV": $timezone = "Europe/Riga"; break; case "IT": $timezone = "Europe/Rome"; break; case "SM": $timezone = "Europe/San_Marino"; break; case "BA": $timezone = "Europe/Sarajevo"; break; case "MK": $timezone = "Europe/Skopje"; break; case "BG": $timezone = "Europe/Sofia"; break; case "SE": $timezone = "Europe/Stockholm"; break; case "EE": $timezone = "Europe/Tallinn"; break; case "AL": $timezone = "Europe/Tirane"; break; case "LI": $timezone = "Europe/Vaduz"; break; case "VA": $timezone = "Europe/Vatican"; break; case "AT": $timezone = "Europe/Vienna"; break; case "LT": $timezone = "Europe/Vilnius"; break; case "PL": $timezone = "Europe/Warsaw"; break; case "HR": $timezone = "Europe/Zagreb"; break; case "IR": $timezone = "Asia/Tehran"; break; case "MG": $timezone = "Indian/Antananarivo"; break; case "CX": $timezone = "Indian/Christmas"; break; case "CC": $timezone = "Indian/Cocos"; break; case "KM": $timezone = "Indian/Comoro"; break; case "MV": $timezone = "Indian/Maldives"; break; case "MU": $timezone = "Indian/Mauritius"; break; case "YT": $timezone = "Indian/Mayotte"; break; case "RE": $timezone = "Indian/Reunion"; break; case "FJ": $timezone = "Pacific/Fiji"; break; case "TV": $timezone = "Pacific/Funafuti"; break; case "GU": $timezone = "Pacific/Guam"; break; case "NR": $timezone = "Pacific/Nauru"; break; case "NU": $timezone = "Pacific/Niue"; break; case "NF": $timezone = "Pacific/Norfolk"; break; case "PW": $timezone = "Pacific/Palau"; break; case "PN": $timezone = "Pacific/Pitcairn"; break; case "CK": $timezone = "Pacific/Rarotonga"; break; case "WS": $timezone = "Pacific/Samoa"; break; case "KI": $timezone = "Pacific/Tarawa"; break; case "TO": $timezone = "Pacific/Tongatapu"; break; case "WF": $timezone = "Pacific/Wallis"; break; case "TZ": $timezone = "Africa/Dar_es_Salaam"; break; case "VN": $timezone = "Asia/Phnom_Penh"; break; case "KH": $timezone = "Asia/Phnom_Penh"; break; case "CM": $timezone = "Africa/Lagos"; break; case "DO": $timezone = "America/Santo_Domingo"; break; case "ET": $timezone = "Africa/Addis_Ababa"; break; case "FX": $timezone = "Europe/Paris"; break; case "HT": $timezone = "America/Port-au-Prince"; break; case "CH": $timezone = "Europe/Zurich"; break; case "AN": $timezone = "America/Curacao"; break; case "BJ": $timezone = "Africa/Porto-Novo"; break; case "EH": $timezone = "Africa/El_Aaiun"; break; case "FK": $timezone = "Atlantic/Stanley"; break; case "GF": $timezone = "America/Cayenne"; break; case "IO": $timezone = "Indian/Chagos"; break; case "MD": $timezone = "Europe/Chisinau"; break; case "MP": $timezone = "Pacific/Saipan"; break; case "MW": $timezone = "Africa/Blantyre"; break; case "NA": $timezone = "Africa/Windhoek"; break; case "NC": $timezone = "Pacific/Noumea"; break; case "PG": $timezone = "Pacific/Port_Moresby"; break; case "PM": $timezone = "America/Miquelon"; break; case "PS": $timezone = "Asia/Gaza"; break; case "PY": $timezone = "America/Asuncion"; break; case "SB": $timezone = "Pacific/Guadalcanal"; break; case "SC": $timezone = "Indian/Mahe"; break; case "SJ": $timezone = "Arctic/Longyearbyen"; break; case "SY": $timezone = "Asia/Damascus"; break; case "TC": $timezone = "America/Grand_Turk"; break; case "TF": $timezone = "Indian/Kerguelen"; break; case "TK": $timezone = "Pacific/Fakaofo"; break; case "TT": $timezone = "America/Port_of_Spain"; break; case "VG": $timezone = "America/Tortola"; break; case "VI": $timezone = "America/St_Thomas"; break; case "VU": $timezone = "Pacific/Efate"; break; case "RS": $timezone = "Europe/Belgrade"; break; case "ME": $timezone = "Europe/Podgorica"; break; case "AX": $timezone = "Europe/Mariehamn"; break; case "GG": $timezone = "Europe/Guernsey"; break; case "IM": $timezone = "Europe/Isle_of_Man"; break; case "JE": $timezone = "Europe/Jersey"; break; case "BL": $timezone = "America/St_Barthelemy"; break; case "MF": $timezone = "America/Marigot"; break; case "AR": switch ($region) { case "01": $timezone = "America/Argentina/Buenos_Aires"; break; case "02": $timezone = "America/Argentina/Catamarca"; break; case "03": $timezone = "America/Argentina/Tucuman"; break; case "04": $timezone = "America/Argentina/Rio_Gallegos"; break; case "05": $timezone = "America/Argentina/Cordoba"; break; case "06": $timezone = "America/Argentina/Tucuman"; break; case "07": $timezone = "America/Argentina/Buenos_Aires"; break; case "08": $timezone = "America/Argentina/Buenos_Aires"; break; case "09": $timezone = "America/Argentina/Tucuman"; break; case "10": $timezone = "America/Argentina/Jujuy"; break; case "11": $timezone = "America/Argentina/San_Luis"; break; case "12": $timezone = "America/Argentina/La_Rioja"; break; case "13": $timezone = "America/Argentina/Mendoza"; break; case "14": $timezone = "America/Argentina/Buenos_Aires"; break; case "15": $timezone = "America/Argentina/San_Luis"; break; case "16": $timezone = "America/Argentina/Buenos_Aires"; break; case "17": $timezone = "America/Argentina/Salta"; break; case "18": $timezone = "America/Argentina/San_Juan"; break; case "19": $timezone = "America/Argentina/San_Luis"; break; case "20": $timezone = "America/Argentina/Rio_Gallegos"; break; case "21": $timezone = "America/Argentina/Buenos_Aires"; break; case "22": $timezone = "America/Argentina/Catamarca"; break; case "23": $timezone = "America/Argentina/Ushuaia"; break; case "24": $timezone = "America/Argentina/Tucuman"; break; } break; case "BR": switch ($region) { case "01": $timezone = "America/Rio_Branco"; break; case "02": $timezone = "America/Maceio"; break; case "03": $timezone = "America/Sao_Paulo"; break; case "04": $timezone = "America/Manaus"; break; case "05": $timezone = "America/Bahia"; break; case "06": $timezone = "America/Fortaleza"; break; case "07": $timezone = "America/Sao_Paulo"; break; case "08": $timezone = "America/Sao_Paulo"; break; case "11": $timezone = "America/Campo_Grande"; break; case "13": $timezone = "America/Belem"; break; case "14": $timezone = "America/Cuiaba"; break; case "15": $timezone = "America/Sao_Paulo"; break; case "16": $timezone = "America/Belem"; break; case "17": $timezone = "America/Recife"; break; case "18": $timezone = "America/Sao_Paulo"; break; case "20": $timezone = "America/Fortaleza"; break; case "21": $timezone = "America/Sao_Paulo"; break; case "22": $timezone = "America/Recife"; break; case "23": $timezone = "America/Sao_Paulo"; break; case "24": $timezone = "America/Porto_Velho"; break; case "25": $timezone = "America/Boa_Vista"; break; case "26": $timezone = "America/Sao_Paulo"; break; case "27": $timezone = "America/Sao_Paulo"; break; case "28": $timezone = "America/Maceio"; break; case "29": $timezone = "America/Sao_Paulo"; break; case "30": $timezone = "America/Recife"; break; case "31": $timezone = "America/Araguaina"; break; } break; case "CD": switch ($region) { case "02": $timezone = "Africa/Kinshasa"; break; case "05": $timezone = "Africa/Lubumbashi"; break; case "06": $timezone = "Africa/Kinshasa"; break; case "08": $timezone = "Africa/Kinshasa"; break; case "10": $timezone = "Africa/Lubumbashi"; break; case "11": $timezone = "Africa/Lubumbashi"; break; case "12": $timezone = "Africa/Lubumbashi"; break; } break; case "CN": switch ($region) { case "01": $timezone = "Asia/Shanghai"; break; case "02": $timezone = "Asia/Shanghai"; break; case "03": $timezone = "Asia/Shanghai"; break; case "04": $timezone = "Asia/Shanghai"; break; case "05": $timezone = "Asia/Harbin"; break; case "06": $timezone = "Asia/Chongqing"; break; case "07": $timezone = "Asia/Shanghai"; break; case "08": $timezone = "Asia/Harbin"; break; case "09": $timezone = "Asia/Shanghai"; break; case "10": $timezone = "Asia/Shanghai"; break; case "11": $timezone = "Asia/Chongqing"; break; case "12": $timezone = "Asia/Shanghai"; break; case "13": $timezone = "Asia/Urumqi"; break; case "14": $timezone = "Asia/Chongqing"; break; case "15": $timezone = "Asia/Chongqing"; break; case "16": $timezone = "Asia/Chongqing"; break; case "18": $timezone = "Asia/Chongqing"; break; case "19": $timezone = "Asia/Harbin"; break; case "20": $timezone = "Asia/Harbin"; break; case "21": $timezone = "Asia/Chongqing"; break; case "22": $timezone = "Asia/Harbin"; break; case "23": $timezone = "Asia/Shanghai"; break; case "24": $timezone = "Asia/Chongqing"; break; case "25": $timezone = "Asia/Shanghai"; break; case "26": $timezone = "Asia/Chongqing"; break; case "28": $timezone = "Asia/Shanghai"; break; case "29": $timezone = "Asia/Chongqing"; break; case "30": $timezone = "Asia/Chongqing"; break; case "31": $timezone = "Asia/Chongqing"; break; case "32": $timezone = "Asia/Chongqing"; break; case "33": $timezone = "Asia/Chongqing"; break; } break; case "EC": switch ($region) { case "01": $timezone = "Pacific/Galapagos"; break; case "02": $timezone = "America/Guayaquil"; break; case "03": $timezone = "America/Guayaquil"; break; case "04": $timezone = "America/Guayaquil"; break; case "05": $timezone = "America/Guayaquil"; break; case "06": $timezone = "America/Guayaquil"; break; case "07": $timezone = "America/Guayaquil"; break; case "08": $timezone = "America/Guayaquil"; break; case "09": $timezone = "America/Guayaquil"; break; case "10": $timezone = "America/Guayaquil"; break; case "11": $timezone = "America/Guayaquil"; break; case "12": $timezone = "America/Guayaquil"; break; case "13": $timezone = "America/Guayaquil"; break; case "14": $timezone = "America/Guayaquil"; break; case "15": $timezone = "America/Guayaquil"; break; case "17": $timezone = "America/Guayaquil"; break; case "18": $timezone = "America/Guayaquil"; break; case "19": $timezone = "America/Guayaquil"; break; case "20": $timezone = "America/Guayaquil"; break; case "22": $timezone = "America/Guayaquil"; break; } break; case "ES": switch ($region) { case "07": $timezone = "Europe/Madrid"; break; case "27": $timezone = "Europe/Madrid"; break; case "29": $timezone = "Europe/Madrid"; break; case "31": $timezone = "Europe/Madrid"; break; case "32": $timezone = "Europe/Madrid"; break; case "34": $timezone = "Europe/Madrid"; break; case "39": $timezone = "Europe/Madrid"; break; case "51": $timezone = "Africa/Ceuta"; break; case "52": $timezone = "Europe/Madrid"; break; case "53": $timezone = "Atlantic/Canary"; break; case "54": $timezone = "Europe/Madrid"; break; case "55": $timezone = "Europe/Madrid"; break; case "56": $timezone = "Europe/Madrid"; break; case "57": $timezone = "Europe/Madrid"; break; case "58": $timezone = "Europe/Madrid"; break; case "59": $timezone = "Europe/Madrid"; break; case "60": $timezone = "Europe/Madrid"; break; } break; case "GL": switch ($region) { case "01": $timezone = "America/Thule"; break; case "02": $timezone = "America/Godthab"; break; case "03": $timezone = "America/Godthab"; break; } break; case "ID": switch ($region) { case "01": $timezone = "Asia/Pontianak"; break; case "02": $timezone = "Asia/Makassar"; break; case "03": $timezone = "Asia/Jakarta"; break; case "04": $timezone = "Asia/Jakarta"; break; case "05": $timezone = "Asia/Jakarta"; break; case "06": $timezone = "Asia/Jakarta"; break; case "07": $timezone = "Asia/Jakarta"; break; case "08": $timezone = "Asia/Jakarta"; break; case "09": $timezone = "Asia/Jayapura"; break; case "10": $timezone = "Asia/Jakarta"; break; case "11": $timezone = "Asia/Pontianak"; break; case "12": $timezone = "Asia/Makassar"; break; case "13": $timezone = "Asia/Makassar"; break; case "14": $timezone = "Asia/Makassar"; break; case "15": $timezone = "Asia/Jakarta"; break; case "16": $timezone = "Asia/Makassar"; break; case "17": $timezone = "Asia/Makassar"; break; case "18": $timezone = "Asia/Makassar"; break; case "19": $timezone = "Asia/Pontianak"; break; case "20": $timezone = "Asia/Makassar"; break; case "21": $timezone = "Asia/Makassar"; break; case "22": $timezone = "Asia/Makassar"; break; case "23": $timezone = "Asia/Makassar"; break; case "24": $timezone = "Asia/Jakarta"; break; case "25": $timezone = "Asia/Pontianak"; break; case "26": $timezone = "Asia/Pontianak"; break; case "30": $timezone = "Asia/Jakarta"; break; case "31": $timezone = "Asia/Makassar"; break; case "33": $timezone = "Asia/Jakarta"; break; } break; case "KZ": switch ($region) { case "01": $timezone = "Asia/Almaty"; break; case "02": $timezone = "Asia/Almaty"; break; case "03": $timezone = "Asia/Qyzylorda"; break; case "04": $timezone = "Asia/Aqtobe"; break; case "05": $timezone = "Asia/Qyzylorda"; break; case "06": $timezone = "Asia/Aqtau"; break; case "07": $timezone = "Asia/Oral"; break; case "08": $timezone = "Asia/Qyzylorda"; break; case "09": $timezone = "Asia/Aqtau"; break; case "10": $timezone = "Asia/Qyzylorda"; break; case "11": $timezone = "Asia/Almaty"; break; case "12": $timezone = "Asia/Qyzylorda"; break; case "13": $timezone = "Asia/Aqtobe"; break; case "14": $timezone = "Asia/Qyzylorda"; break; case "15": $timezone = "Asia/Almaty"; break; case "16": $timezone = "Asia/Aqtobe"; break; case "17": $timezone = "Asia/Almaty"; break; } break; case "MX": switch ($region) { case "01": $timezone = "America/Mexico_City"; break; case "02": $timezone = "America/Tijuana"; break; case "03": $timezone = "America/Hermosillo"; break; case "04": $timezone = "America/Merida"; break; case "05": $timezone = "America/Mexico_City"; break; case "06": $timezone = "America/Chihuahua"; break; case "07": $timezone = "America/Monterrey"; break; case "08": $timezone = "America/Mexico_City"; break; case "09": $timezone = "America/Mexico_City"; break; case "10": $timezone = "America/Mazatlan"; break; case "11": $timezone = "America/Mexico_City"; break; case "12": $timezone = "America/Mexico_City"; break; case "13": $timezone = "America/Mexico_City"; break; case "14": $timezone = "America/Mazatlan"; break; case "15": $timezone = "America/Chihuahua"; break; case "16": $timezone = "America/Mexico_City"; break; case "17": $timezone = "America/Mexico_City"; break; case "18": $timezone = "America/Mazatlan"; break; case "19": $timezone = "America/Monterrey"; break; case "20": $timezone = "America/Mexico_City"; break; case "21": $timezone = "America/Mexico_City"; break; case "22": $timezone = "America/Mexico_City"; break; case "23": $timezone = "America/Cancun"; break; case "24": $timezone = "America/Mexico_City"; break; case "25": $timezone = "America/Mazatlan"; break; case "26": $timezone = "America/Hermosillo"; break; case "27": $timezone = "America/Merida"; break; case "28": $timezone = "America/Monterrey"; break; case "29": $timezone = "America/Mexico_City"; break; case "30": $timezone = "America/Mexico_City"; break; case "31": $timezone = "America/Merida"; break; case "32": $timezone = "America/Monterrey"; break; } break; case "MY": switch ($region) { case "01": $timezone = "Asia/Kuala_Lumpur"; break; case "02": $timezone = "Asia/Kuala_Lumpur"; break; case "03": $timezone = "Asia/Kuala_Lumpur"; break; case "04": $timezone = "Asia/Kuala_Lumpur"; break; case "05": $timezone = "Asia/Kuala_Lumpur"; break; case "06": $timezone = "Asia/Kuala_Lumpur"; break; case "07": $timezone = "Asia/Kuala_Lumpur"; break; case "08": $timezone = "Asia/Kuala_Lumpur"; break; case "09": $timezone = "Asia/Kuala_Lumpur"; break; case "11": $timezone = "Asia/Kuching"; break; case "12": $timezone = "Asia/Kuala_Lumpur"; break; case "13": $timezone = "Asia/Kuala_Lumpur"; break; case "14": $timezone = "Asia/Kuala_Lumpur"; break; case "15": $timezone = "Asia/Kuching"; break; case "16": $timezone = "Asia/Kuching"; break; } break; case "NZ": switch ($region) { case "85": $timezone = "Pacific/Auckland"; break; case "E7": $timezone = "Pacific/Auckland"; break; case "E8": $timezone = "Pacific/Auckland"; break; case "E9": $timezone = "Pacific/Auckland"; break; case "F1": $timezone = "Pacific/Auckland"; break; case "F2": $timezone = "Pacific/Auckland"; break; case "F3": $timezone = "Pacific/Auckland"; break; case "F4": $timezone = "Pacific/Auckland"; break; case "F5": $timezone = "Pacific/Auckland"; break; case "F7": $timezone = "Pacific/Chatham"; break; case "F8": $timezone = "Pacific/Auckland"; break; case "F9": $timezone = "Pacific/Auckland"; break; case "G1": $timezone = "Pacific/Auckland"; break; case "G2": $timezone = "Pacific/Auckland"; break; case "G3": $timezone = "Pacific/Auckland"; break; } break; case "PT": switch ($region) { case "02": $timezone = "Europe/Lisbon"; break; case "03": $timezone = "Europe/Lisbon"; break; case "04": $timezone = "Europe/Lisbon"; break; case "05": $timezone = "Europe/Lisbon"; break; case "06": $timezone = "Europe/Lisbon"; break; case "07": $timezone = "Europe/Lisbon"; break; case "08": $timezone = "Europe/Lisbon"; break; case "09": $timezone = "Europe/Lisbon"; break; case "10": $timezone = "Atlantic/Madeira"; break; case "11": $timezone = "Europe/Lisbon"; break; case "13": $timezone = "Europe/Lisbon"; break; case "14": $timezone = "Europe/Lisbon"; break; case "16": $timezone = "Europe/Lisbon"; break; case "17": $timezone = "Europe/Lisbon"; break; case "18": $timezone = "Europe/Lisbon"; break; case "19": $timezone = "Europe/Lisbon"; break; case "20": $timezone = "Europe/Lisbon"; break; case "21": $timezone = "Europe/Lisbon"; break; case "22": $timezone = "Europe/Lisbon"; break; } break; case "RU": switch ($region) { case "01": $timezone = "Europe/Volgograd"; break; case "02": $timezone = "Asia/Irkutsk"; break; case "03": $timezone = "Asia/Novokuznetsk"; break; case "04": $timezone = "Asia/Novosibirsk"; break; case "05": $timezone = "Asia/Vladivostok"; break; case "06": $timezone = "Europe/Moscow"; break; case "07": $timezone = "Europe/Volgograd"; break; case "08": $timezone = "Europe/Samara"; break; case "09": $timezone = "Europe/Moscow"; break; case "10": $timezone = "Europe/Moscow"; break; case "11": $timezone = "Asia/Irkutsk"; break; case "13": $timezone = "Asia/Yekaterinburg"; break; case "14": $timezone = "Asia/Irkutsk"; break; case "15": $timezone = "Asia/Anadyr"; break; case "16": $timezone = "Europe/Samara"; break; case "17": $timezone = "Europe/Volgograd"; break; case "18": $timezone = "Asia/Krasnoyarsk"; break; case "20": $timezone = "Asia/Irkutsk"; break; case "21": $timezone = "Europe/Moscow"; break; case "22": $timezone = "Europe/Volgograd"; break; case "23": $timezone = "Europe/Kaliningrad"; break; case "24": $timezone = "Europe/Volgograd"; break; case "25": $timezone = "Europe/Moscow"; break; case "26": $timezone = "Asia/Kamchatka"; break; case "27": $timezone = "Europe/Volgograd"; break; case "28": $timezone = "Europe/Moscow"; break; case "29": $timezone = "Asia/Novokuznetsk"; break; case "30": $timezone = "Asia/Vladivostok"; break; case "31": $timezone = "Asia/Krasnoyarsk"; break; case "32": $timezone = "Asia/Omsk"; break; case "33": $timezone = "Asia/Yekaterinburg"; break; case "34": $timezone = "Asia/Yekaterinburg"; break; case "35": $timezone = "Asia/Yekaterinburg"; break; case "36": $timezone = "Asia/Anadyr"; break; case "37": $timezone = "Europe/Moscow"; break; case "38": $timezone = "Europe/Volgograd"; break; case "39": $timezone = "Asia/Krasnoyarsk"; break; case "40": $timezone = "Asia/Yekaterinburg"; break; case "41": $timezone = "Europe/Moscow"; break; case "42": $timezone = "Europe/Moscow"; break; case "43": $timezone = "Europe/Moscow"; break; case "44": $timezone = "Asia/Magadan"; break; case "45": $timezone = "Europe/Samara"; break; case "46": $timezone = "Europe/Samara"; break; case "47": $timezone = "Europe/Moscow"; break; case "48": $timezone = "Europe/Moscow"; break; case "49": $timezone = "Europe/Moscow"; break; case "50": $timezone = "Asia/Yekaterinburg"; break; case "51": $timezone = "Europe/Moscow"; break; case "52": $timezone = "Europe/Moscow"; break; case "53": $timezone = "Asia/Novosibirsk"; break; case "54": $timezone = "Asia/Omsk"; break; case "55": $timezone = "Europe/Samara"; break; case "56": $timezone = "Europe/Moscow"; break; case "57": $timezone = "Europe/Samara"; break; case "58": $timezone = "Asia/Yekaterinburg"; break; case "59": $timezone = "Asia/Vladivostok"; break; case "60": $timezone = "Europe/Kaliningrad"; break; case "61": $timezone = "Europe/Volgograd"; break; case "62": $timezone = "Europe/Moscow"; break; case "63": $timezone = "Asia/Yakutsk"; break; case "64": $timezone = "Asia/Sakhalin"; break; case "65": $timezone = "Europe/Samara"; break; case "66": $timezone = "Europe/Moscow"; break; case "67": $timezone = "Europe/Samara"; break; case "68": $timezone = "Europe/Volgograd"; break; case "69": $timezone = "Europe/Moscow"; break; case "70": $timezone = "Europe/Volgograd"; break; case "71": $timezone = "Asia/Yekaterinburg"; break; case "72": $timezone = "Europe/Moscow"; break; case "73": $timezone = "Europe/Samara"; break; case "74": $timezone = "Asia/Krasnoyarsk"; break; case "75": $timezone = "Asia/Novosibirsk"; break; case "76": $timezone = "Europe/Moscow"; break; case "77": $timezone = "Europe/Moscow"; break; case "78": $timezone = "Asia/Yekaterinburg"; break; case "79": $timezone = "Asia/Irkutsk"; break; case "80": $timezone = "Asia/Yekaterinburg"; break; case "81": $timezone = "Europe/Samara"; break; case "82": $timezone = "Asia/Irkutsk"; break; case "83": $timezone = "Europe/Moscow"; break; case "84": $timezone = "Europe/Volgograd"; break; case "85": $timezone = "Europe/Moscow"; break; case "86": $timezone = "Europe/Moscow"; break; case "87": $timezone = "Asia/Novosibirsk"; break; case "88": $timezone = "Europe/Moscow"; break; case "89": $timezone = "Asia/Vladivostok"; break; } break; case "UA": switch ($region) { case "01": $timezone = "Europe/Kiev"; break; case "02": $timezone = "Europe/Kiev"; break; case "03": $timezone = "Europe/Uzhgorod"; break; case "04": $timezone = "Europe/Zaporozhye"; break; case "05": $timezone = "Europe/Zaporozhye"; break; case "06": $timezone = "Europe/Uzhgorod"; break; case "07": $timezone = "Europe/Zaporozhye"; break; case "08": $timezone = "Europe/Simferopol"; break; case "09": $timezone = "Europe/Kiev"; break; case "10": $timezone = "Europe/Zaporozhye"; break; case "11": $timezone = "Europe/Simferopol"; break; case "13": $timezone = "Europe/Kiev"; break; case "14": $timezone = "Europe/Zaporozhye"; break; case "15": $timezone = "Europe/Uzhgorod"; break; case "16": $timezone = "Europe/Zaporozhye"; break; case "17": $timezone = "Europe/Simferopol"; break; case "18": $timezone = "Europe/Zaporozhye"; break; case "19": $timezone = "Europe/Kiev"; break; case "20": $timezone = "Europe/Simferopol"; break; case "21": $timezone = "Europe/Kiev"; break; case "22": $timezone = "Europe/Uzhgorod"; break; case "23": $timezone = "Europe/Kiev"; break; case "24": $timezone = "Europe/Uzhgorod"; break; case "25": $timezone = "Europe/Uzhgorod"; break; case "26": $timezone = "Europe/Zaporozhye"; break; case "27": $timezone = "Europe/Kiev"; break; } break; case "UZ": switch ($region) { case "01": $timezone = "Asia/Tashkent"; break; case "02": $timezone = "Asia/Samarkand"; break; case "03": $timezone = "Asia/Tashkent"; break; case "06": $timezone = "Asia/Tashkent"; break; case "07": $timezone = "Asia/Samarkand"; break; case "08": $timezone = "Asia/Samarkand"; break; case "09": $timezone = "Asia/Samarkand"; break; case "10": $timezone = "Asia/Samarkand"; break; case "12": $timezone = "Asia/Samarkand"; break; case "13": $timezone = "Asia/Tashkent"; break; case "14": $timezone = "Asia/Tashkent"; break; } break; case "TL": $timezone = "Asia/Dili"; break; case "PF": $timezone = "Pacific/Marquesas"; break; } return $timezone; } function normalizeURI($uri) { $uri=quoted_printable_decode($uri); if (preg_match("/^(.*)/",$uri,$m)) { if (preg_match("/^(.*):/U",$m[2],$p)){ $uri=$m[1]."@".$p[1].">"; } else { $uri=$m[1]."@".$m[2]; } } else if (preg_match("/^(sips?:.*)[=:;]/U",$uri,$p)) { $uri=$p[1]; } return $uri; } function normalizeTime($period) { $sec=$period%60; $min=floor($period/60); $h=floor($min/60); if (!$period) return ; if ($h>0) { $min=$min-60*$h; } if ($h >= 1) { return sprintf('%dh%02d\'%02d"', $h, $min, $sec); } else { return sprintf('%d\'%02d"', $min, $sec); } } function checkURI($uri) { //dprint ("checkURI($uri) "); if ($uri == "") return true; if (preg_match("/^(sip:|sips:)(.*)$/",$uri,$m)) $uri=$m[2]; $regexp = "/^(\+?[a-z0-9*][a-z0-9_.*-]*)@([a-z0-9][a-z0-9-]*\.)+(([a-z]{2,})|(\d+))$/i"; if (stristr($uri,"-.") || !preg_match($regexp, $uri)) { print "Invalid URI \"$uri\". "; return false; } return true; } function checkPhonebookURI($uri) { $regexp = "/^sip:([a-z0-9%_.-]*)@([a-z0-9%.-]*)$/i"; if (stristr($contact,"-.") || !preg_match($regexp, $uri)) { print "Invalid URI \"$uri\". "; return false; } return true; } function getLocalTime($timezone,$timestamp) { $tz=getenv('TZ'); putenv("TZ=$timezone"); $LocalTime=date("Y-m-d H:i:s", $timestamp); putenv("TZ=$tz"); return $LocalTime; } function getSipThorHomeNode ($account,$sip_proxy) { if (!$account || !$sip_proxy) return false; $socket = fsockopen($sip_proxy, 9500, $errno, $errstr, 1); if (!$socket) { return false; } $request=sprintf("lookup sip_proxy for %s",$account); if (fputs($socket,"$request\r\n") !== false) { $ret = fgets($socket,4096); } fclose($socket); return $ret; } function getSipAccountFromX509Certificate() { if (!$_SERVER[SSL_CLIENT_CERT]) { print _("Error: No X.509 client certificate provided\n"); return false; } if (!$cert=openssl_x509_parse($_SERVER[SSL_CLIENT_CERT])) { print _("Error: Failed to parse X.509 client certificate\n"); return false; } $username = $cert['subject']['CN']; $a=explode("@",$username); $domain= $a[1]; if (count($a) !=2 ) { print _("No SIP Address available. "); return false; } require("/etc/cdrtool/ngnpro_engines.inc"); global $domainFilters, $resellerFilters, $soapEngines ; $credentials['account'] = $username; if ($domainFilters[$domain]['sip_engine']) { $credentials['engine'] = $domainFilters[$domain]['sip_engine']; $credentials['customer'] = $domainFilters[$domain]['customer']; $credentials['reseller'] = $domainFilters[$domain]['reseller']; } else if ($domainFilters['default']['sip_engine']) { $credentials['engine']=$domainFilters['default']['sip_engine']; } else { print "Error: no domainFilter available in ngnpro_engines.inc"; return false; } $SOAPlogin=array( "username" => $soapEngines[$credentials['engine']]['username'], "password" => $soapEngines[$credentials['engine']]['password'], "admin" => true ); $SoapAuth = array('auth', $SOAPlogin , 'urn:AGProjects:NGNPro', 0, ''); $SipPort = new WebService_NGNPro_SipPort($soapEngines[$credentials['engine']]['url']); $SipPort->_options['timeout'] = 5; $SipPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $SipPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); $SipPort->addHeader($SoapAuth); $result = $SipPort->getAccount(array("username" =>$a[0],"domain" =>$domain)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error from %s (SipPort): %s (%s): %s",$soapEngines[$credentials['engine']]['url'],$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } $credentials['customer'] = $result->customer; $credentials['reseller'] = $result->reseller; return $credentials; } function getSipAccountFromHTTPDigest () { require("/etc/cdrtool/enrollment/config.ini"); if (!is_array($enrollment) || !strlen($enrollment['nonce_key'])) { $log= 'Error: Missing nonce in enrollment settings'; syslog(LOG_NOTICE, $log); die($log); return false; } if ($_REQUEST['realm']) { // required by Blink cocoa $realm=$_REQUEST['realm']; $a=explode("@",$realm); if (count($a) == 2) { $realm = $a[1]; } } else { $realm = 'SIP_settings'; } // security implemented based on // http://static.springsource.org/spring-security/site/docs/2.0.x/reference/digest.html $_id = microtime(true)+ 300; // expires 5 minutes in the future $_key = $enrollment['nonce_key']; $nonce = base64_encode($_id.":".md5($_id.":".$_key)); if (empty($_SERVER['PHP_AUTH_DIGEST'])) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.$nonce.'",opaque="'.md5($realm).'"'); //syslog(LOG_NOTICE, sprintf ("SIP settings page: sent auth request for realm %s to %s", $realm, $_SERVER['REMOTE_ADDR'])); die(); } // analyze the PHP_AUTH_DIGEST variable if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($data['username'])) { $log=sprintf("SIP settings page: Invalid credentials from %s", $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); die($log); } // generate the valid response $username = $data['username']; if (strstr($username, '@')) { $a = explode("@",$username); $username = $a[0]; $domain = $a[1]; } else { $domain = $realm; } require("/etc/cdrtool/ngnpro_engines.inc"); global $domainFilters, $resellerFilters, $soapEngines ; $credentials['account'] = sprintf("%s@%s",$username, $domain); if ($domainFilters[$domain]['sip_engine']) { $credentials['engine'] = $domainFilters[$domain]['sip_engine']; $credentials['customer'] = $domainFilters[$domain]['customer']; $credentials['reseller'] = $domainFilters[$domain]['reseller']; } else if ($domainFilters['default']['sip_engine']) { $credentials['engine']=$domainFilters['default']['sip_engine']; } else { $log=sprintf("SIP settings page error: no domainFilter available in ngnpro_engines.inc from %s", $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); die(); } $SOAPlogin=array( "username" => $soapEngines[$credentials['engine']]['username'], "password" => $soapEngines[$credentials['engine']]['password'], "admin" => true ); $SoapAuth = array('auth', $SOAPlogin , 'urn:AGProjects:NGNPro', 0, ''); $SipPort = new WebService_NGNPro_SipPort($soapEngines[$credentials['engine']]['url']); $SipPort->_options['timeout'] = 5; $SipPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0); $SipPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0); $SipPort->addHeader($SoapAuth); $result = $SipPort->getAccount(array("username" =>$username,"domain" =>$domain)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.$nonce.'",opaque="'.md5($realm).'"'); $log=sprintf("SIP settings page error: non-existent username %s from %s", $credentials['account'], $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); die(); } $web_password=''; foreach ($result->properties as $_property) { if ($_property->name == 'web_password') { $web_password=$_property->value; break; } } if ($web_password) { $A1 = md5($data['username'] . ':' . $realm . ':' . $web_password); $login_type_log = 'web password'; } else if (strstr($data['username'], '@')) { $A1 = md5($data['username'] . ':' . $realm . ':' . $result->password); $login_type_log = 'cleartext legacy password'; } else if ($result->ha1) { $login_type_log = sprintf('encrypted password'); $A1 = $result->ha1; } else { $A1 = md5($data['username'] . ':' . $realm . ':' . $result->password); $login_type_log = 'cleartext password'; } $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']); $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2); if ($data['response'] != $valid_response) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.$nonce.'",opaque="'.md5($realm).'"'); $log=sprintf("SIP settings page error: wrong credentials using %s for %s from %s", $login_type_log, $credentials['account'], $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); die(); } // check nonce $client_nonce_els=explode(":",base64_decode($data['nonce'])); if (md5($client_nonce_els[0].":".$_key) != $client_nonce_els[1]) { header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.$nonce.'",opaque="'.md5($realm).'"'); $log=sprintf("SIP settings page error: wrong nonce for %s from %s", $credentials['account'], $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); die(); } if (microtime(true) > $client_nonce_els[0]) { // nonce is stale header('HTTP/1.1 401 Unauthorized'); header('WWW-Authenticate: Digest realm="'.$realm. '",qop="auth",nonce="'.$nonce.'",stale=true,opaque="'.md5($realm).'"'); $log=sprintf("SIP settings page error: nonce has expired for %s from %s", $username, $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); die(); } $log=sprintf("SIP settings page: %s logged in using %s from %s", $credentials['account'], $login_type_log, $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); $credentials['customer'] = $result->customer; $credentials['reseller'] = $result->reseller; return $credentials; } function http_digest_parse($txt) { // function to parse the http auth header // protect against missing data $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); $data = array(); $keys = implode('|', array_keys($needed_parts)); preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER); foreach ($matches as $m) { $data[$m[1]] = $m[3] ? $m[3] : $m[4]; unset($needed_parts[$m[1]]); } return $needed_parts ? false : $data; } function renderUI($SipSettings_class,$account,$login_credentials,$soapEngines) { // Generic code for all sip settings pages $SipSettings = new $SipSettings_class($account,$login_credentials,$soapEngines); if ($_REQUEST['action']) { $log_action=$_REQUEST['action']; } else { $log_action='load main page'; } $log=sprintf("SIP settings page: %s for %s from %s", $log_action, $account, $_SERVER['REMOTE_ADDR']); syslog(LOG_NOTICE, $log); if (!strstr($_REQUEST['action'],'get_') && !strstr($_REQUEST['action'],'set_') && !strstr($_REQUEST['action'],'put_') && !strstr($_REQUEST['action'],'export_') && !strstr($_REQUEST['action'],'add_')) { $title = "SIP settings of $account"; $header = $SipSettings->headerFile; $css = $SipSettings->cssFile; $auto_refesh_tab=$SipSettings->auto_refesh_tab; $absolute_url= $SipSettings->absolute_url; include($header); dprint("Header file $header included, refresh=$auto_refesh_tab"); include($css); dprint("CSS file $css included"); } if ($_REQUEST['action']=="save settings") { if ($SipSettings->checkSettings()) { $SipSettings->saveSettings(); unset($SipSettings); $SipSettings = new $SipSettings_class($account,$login_credentials,$soapEngines); } else { print ""; printf (_("Error: %s"),$SipSettings->error); print ""; } } else if ($_REQUEST['action']=="set diversions") { $SipSettings->setDiversions(); unset($SipSettings); $SipSettings = new $SipSettings_class($account,$login_credentials,$soapEngines); } else if ($_REQUEST['action']=="set barring") { $SipSettings->setBarringPrefixes(); } else if ($_REQUEST['action']=="set reject") { $SipSettings->setRejectMembers(); } else if ($_REQUEST['action']=="set accept rules") { $SipSettings->setAcceptRules(); } else if ($_REQUEST['action']=="set aliases") { $SipSettings->setAliases(); } else if ($_REQUEST['action']=="send email") { $SipSettings->sendEmail(); } else if ($_REQUEST['action']=="get_crt") { $SipSettings->exportCertificateX509(); return true; } else if ($_REQUEST['action']=="get_p12") { $SipSettings->exportCertificateP12(); return true; } else if ($_REQUEST['action'] == 'get_balance_history') { $SipSettings->getBalanceHistory(); if ($_REQUEST['csv']) { $SipSettings->exportBalanceHistory(); } else { print json_encode($SipSettings->balance_history); } return true; } else if ($_REQUEST['action'] == 'get_call_forwarding') { $SipSettings->getDiversions(); print json_encode($SipSettings->diversions); return true; } else if ($_REQUEST['action'] == 'get_prepaid') { $SipSettings->getPrepaidStatus(); print json_encode($SipSettings->prepaidAccount); return true; } else if ($_REQUEST['action'] == 'get_monthly_usage') { $SipSettings->getCallStatistics(); print json_encode($SipSettings->thisMonth); return true; } else if ($_REQUEST['action'] == 'get_accept_rules'){ $SipSettings->getAcceptRules(); print json_encode($SipSettings->acceptRules); return true; } else if ($_REQUEST['action'] == 'get_journal_entries'){ $SipSettings->getJournalEntries(); print json_encode($SipSettings->journalEntries); return true; } else if ($_REQUEST['action'] == 'put_journal_entries'){ print json_encode($SipSettings->putJournalEntries()); return true; } else if ($_REQUEST['action'] == 'delete_journal_entries'){ print json_encode($SipSettings->deleteJournalEntries()); return true; } else if ($_REQUEST['action'] == 'get_reject_rules'){ $SipSettings->getRejectMembers(); print json_encode($SipSettings->rejectMembers); return true; } else if ($_REQUEST['action'] == 'get_history'){ $SipSettings->getHistory('completed'); print json_encode($SipSettings->call_history); return true; } else if ($_REQUEST['action'] == 'get_voicemail'){ $SipSettings->getVoicemail(); print json_encode($SipSettings->voicemail); return true; } else if ($_REQUEST['action'] == 'get_aliases'){ $SipSettings->getAliases(); print json_encode($SipSettings->aliases); return true; } else if ($_REQUEST['action'] == 'get_enum'){ $SipSettings->getEnumMappings(); print json_encode($SipSettings->enums); return true; } else if ($_REQUEST['action'] == 'export_identity_proof'){ $SipSettings->exportIdentityProof(); return true; } else if ($_REQUEST['action'] == 'add_balance'){ if (!$_REQUEST['id'] || !$_REQUEST['number']) { $return=array('success' => false, 'error_message' => 'Missing id or number' ); print (json_encode($return)); return false; } $card = array('id' => intval($_REQUEST['id']), 'number' => $_REQUEST['number'] ); $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->addBalanceFromVoucher($SipSettings->sipId,$card); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $return=array('success' => false, 'error_message' => $_msg ); print (json_encode($return)); return false; } else { $return=array('success' => true, 'error_message' => 'Added balance succeeded' ); print (json_encode($return)); return true; } } else if ($_REQUEST['action'] == 'get_identity'){ $account=array('sip_address' => $SipSettings->account, 'email' => $SipSettings->email, 'first' => $SipSettings->firstName, 'lastname' => $SipSettings->lastName, 'pstn_caller_id' => $SipSettings->rpid, 'mobile_number' => $SipSettings->mobile_number, 'timezone' => $SipSettings->timezone, 'no_answer_timeout' => $SipSettings->timeout, 'quick_dial' => $SipSettings->quickdial ); print json_encode($account); return true; } else if ($_REQUEST['action'] == 'get_devices'){ $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->getSipDeviceLocations(array($SipSettings->sipId)); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return false; } else { foreach ($result[0]->locations as $locationStructure) { $contact=$locationStructure->address.":".$locationStructure->port; if ($locationStructure->publicAddress) { $publicContact=$locationStructure->publicAddress.":".$locationStructure->publicPort; } else { $publicContact=$contact; } $devices[]=array("contact" => $contact, "publicContact" => $publicContact, "expires" => $locationStructure->expires, "user_agent" => $locationStructure->userAgent, "transport" => $locationStructure->transport ); } } print (json_encode($devices)); return true; } else if ($_REQUEST['action'] == 'set_dnd_on'){ $SipSettings->getAcceptRules(); $SipSettings->acceptRules['temporary']=array('groups' =>array('nobody'), 'duration' =>intval($_REQUEST['duration']) ); $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->setAcceptRules($SipSettings->sipId,$SipSettings->acceptRules); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; } else { $_ret=true; if (intval($_REQUEST['duration'] > 0)) { $_msg=sprintf(_('Do not disturb has been enabled for %d minutes'),intval($_REQUEST['duration'])); } else { $_msg=sprintf(_('Do not disturb has been enabled')); } } $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } else if ($_REQUEST['action'] == 'set_dnd_off'){ $SipSettings->getAcceptRules(); $SipSettings->acceptRules['temporary']=array('groups' =>array('everybody'), 'duration' =>0 ); $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->setAcceptRules($SipSettings->sipId,$SipSettings->acceptRules); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; } else { $_ret=true; $_msg=sprintf(_('Do not disturb has been disabled')); } $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } else if ($_REQUEST['action'] == 'set_privacy_on'){ $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->addToGroup(array("username" => $SipSettings->username,"domain"=> $SipSettings->domain),"anonymous"); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; } else { $_ret=true; $_msg=sprintf(_('Caller-ID is now hidden for outgoing calls')); } $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } else if ($_REQUEST['action'] == 'set_privacy_off'){ $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->removeFromGroup(array("username" => $SipSettings->username,"domain"=> $SipSettings->domain),"anonymous"); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); if ($error_fault->detail->exception->errorcode == 1031) { $_ret=true; $_msg=sprintf(_('Caller-ID is now visible for outgoing calls')); } else { $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; } } else { $_ret=true; $_msg=sprintf(_('Caller-ID is now visible for outgoing calls')); } $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } else if ($_REQUEST['action'] == 'add_alias'){ $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $username=trim($_REQUEST['username']); if (!strlen($username)) { $return=array('success' => false, 'error_message' => 'Error: missing username' ); print (json_encode($return)); return false; } $_aliasObject=array("id"=>array("username"=>strtolower($username), "domain"=>$SipSettings->domain ), "owner" => intval($SipSettings->owner), "target"=> array("username" => $SipSettings->username,"domain"=> $SipSettings->domain) ) ; $result = $SipSettings->SipPort->addAlias($_aliasObject); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; } else { $_ret=true; $_msg=sprintf(_('Added alias %s'),strtolower($username)); } $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } else if ($_REQUEST['action'] == 'set_call_forwarding') { $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->getCallDiversions($SipSettings->sipId); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } $SipSettings->getVoicemail(); foreach(array_keys($SipSettings->diversionType) as $condition) { $old_diversions[$condition]=$result->$condition; } $_log=''; foreach(array_keys($old_diversions) as $key) { if (isset($_REQUEST[$key])) { printf ("Key $key changed %s",$_REQUEST[$key]); $textboxURI=$_REQUEST[$key]; if ($textboxURI == "" && strlen($SipSettings->mobile_number)) { $textboxURI = $SipSettings->mobile_number; } if ($textboxURI && $textboxURI != "" && !preg_match("/@/",$textboxURI)) { $textboxURI=$textboxURI."@".$SipSettings->domain; } if (preg_match("/^([\+|0].*)@/",$textboxURI,$m)) { $textboxURI=$m[1]."@".$SipSettings->domain; } if (strlen($textboxURI) && $textboxURI != "" && !preg_match("/^sip:/",$textboxURI)) { $textboxURI='sip:'.$textboxURI; } if ($textboxURI) { $new_diversions[$key]=$textboxURI; } $_log.=sprintf("%s=%s ",$key,$textboxURI); $divert_changed=true; } else { if ($old_diversions[$key]) { $new_diversions[$key]=$old_diversions[$key]; } } } if ($divert_changed) { $SipSettings->SipPort->addHeader($SipSettings->SoapAuth); $result = $SipSettings->SipPort->setCallDiversions($SipSettings->sipId,$new_diversions); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); $_msg=sprintf ("Error (SipPort): %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); $_ret=false; } else { $_ret=true; $_msg=sprintf(_('Changed diversions %s'),$_log); } $return=array('success' => $_ret, 'error_message' => $_msg ); print (json_encode($return)); return true; } else { $return=array('success' => true, 'error_message' => 'Diversions remained the same' ); print (json_encode($return)); return true; } } else if ($_REQUEST['action']) { $return=array('success' => false, 'error_message' => "Error: invalid action" ); print (json_encode($return)); return false; } if (!$_REQUEST['export']) { $SipSettings->showAccount(); print " "; } } class Enrollment { var $init = false; var $create_voicemail = false; var $send_email_notification = true; var $create_email_alias = false; var $create_customer = true; var $timezones = array(); var $default_timezone = 'Europe/Amsterdam'; var $configuration_file = '/etc/cdrtool/enrollment/config.ini'; var $allow_pstn = 1; var $quota = 50; var $prepaid = 1; var $create_certificate = 0; var $customer_belongs_to_reseller = false; function log_action($action){ global $auth; $location = "Unknown"; $_loc=geoip_record_by_name($_SERVER['REMOTE_ADDR']); if ($_loc['country_name']) { $location = $_loc['country_name']; } $log = sprintf("CDRTool login username=%s, IP=%s, location=%s, action=%s, script=%s", $auth->auth["uname"], $_SERVER['REMOTE_ADDR'], $location, $action, $_SERVER['PHP_SELF'] ); syslog(LOG_NOTICE, $log); } function Enrollment() { require($this->configuration_file); require("/etc/cdrtool/ngnpro_engines.inc"); $this->soapEngines = $soapEngines; $this->enrollment = $enrollment; $this->loadTimezones(); if (!is_array($this->soapEngines)) { $return=array('success' => false, 'error_message' => 'Error: Missing soap engines configuration' ); print (json_encode($return)); return false; } if (!is_array($this->enrollment)) { $return=array('success' => false, 'error_message' => 'Error: Missing enrollment configuration' ); print (json_encode($return)); return false; } $this->sipDomain = $this->enrollment['sip_domain']; $this->sipEngine = $this->enrollment['sip_engine']; if ($this->enrollment['timezone']) { $this->default_timezone = $this->enrollment['timezone']; } if ($this->enrollment['customer_engine']) { $this->customerEngine = $this->enrollment['customer_engine']; } else { $this->customerEngine = $this->enrollment['sip_engine']; } if ($this->enrollment['email_engine']) { $this->emailEngine = $this->enrollment['email_engine']; } else { $this->emailEngine = $this->enrollment['sip_engine']; } if (is_array($this->enrollment['groups'])) { $this->groups = $this->enrollment['groups']; } else { $this->groups = array(); } $this->reseller = $this->enrollment['reseller']; $this->outbound_proxy = $this->enrollment['outbound_proxy']; $this->xcap_root = $this->enrollment['xcap_root']; $this->msrp_relay = $this->enrollment['msrp_relay']; $this->settings_url = $this->enrollment['settings_url']; $this->ldap_hostname = $this->enrollment['ldap_hostname']; $this->ldap_dn = $this->enrollment['ldap_dn']; if ($this->enrollment['sip_class']) { $this->sipClass = $this->enrollment['sip_class']; } else { $this->sipClass = 'SipSettings'; } if (!$this->sipEngine) { $return=array('success' => false, 'error_message' => 'Missing sip engine' ); print (json_encode($return)); return false; } if (!$this->sipDomain) { $return=array('success' => false, 'error_message' => 'Missing sip domain' ); print (json_encode($return)); return false; } $this->sipLoginCredentials = array( 'reseller' => intval($this->reseller), 'sip_engine' => $this->sipEngine, 'login_type' => 'admin' ); $this->init=true; } function createAccount() { if (!$this->init) return false; if (!$_REQUEST['email']) { $return=array('success' => false, 'error' => 'value_error', 'error_message' => 'Missing email address' ); print (json_encode($return)); return false; } if (!$this->checkEmail($_REQUEST['email'])) { $return=array('success' => false, 'error' => 'value_error', 'error_message' => 'Invalid email address' ); print (json_encode($return)); return false; } if (!$_REQUEST['password']) { $return=array('success' => false, 'error' => 'value_error', 'error_message' => 'Missing password' ); print (json_encode($return)); return false; } if (!$_REQUEST['display_name']) { $return=array('success' => false, 'error' => 'value_error', 'error_message' => 'Missing display name' ); print (json_encode($return)); return false; } $username=strtolower(trim($_REQUEST['username'])); if (!preg_match("/^[1-9a-z][0-9a-z_.-]{2,64}[0-9a-z]$/",$username)) { $return=array('success' => false, 'error' => 'value_error', 'error_message' => 'The username must contain at least 4 lowercase alpha-numeric . _ or - characters and must start and end with a positive digit or letter' ); print (json_encode($return)); return false; } $sip_address=$username.'@'.$this->sipDomain; if ($this->create_customer && !$_REQUEST['owner']) { // create owner id $customerEngine = 'customers@'.$this->customerEngine; $this->CustomerSoapEngine = new SoapEngine($customerEngine,$this->soapEngines,$this->customerLoginCredentials); $_customer_class = $this->CustomerSoapEngine->records_class; $this->customerRecords = new $_customer_class($this->CustomerSoapEngine); $this->customerRecords->html=false; $properties=$this->customerRecords->setInitialCredits(array('sip_credit' => 1, 'sip_alias_credit' => 1, 'email_credit' => 1 ) ); if (preg_match("/^(\w+)\s+(\w+)$/",$_REQUEST['display_name'],$m)) { $firstName = $m[1]; $lastName = $m[2]; } else { $firstName = $_REQUEST['display_name']; $lastName = 'Blink'; } $this->log_action("Create owner account ($firstname $lastname) "); $timezone=$_REQUEST['tzinfo']; if (!in_array($timezone, $this->timezones)) { $timezone=$this->default_timezone; } $location = lookupGeoLocation($_SERVER['REMOTE_ADDR']); $customer=array( 'firstName' => $firstName, 'lastName' => $lastName, 'timezone' => $timezone, 'password' => trim($_REQUEST['password']), 'email' => trim($_REQUEST['email']), 'country' => $location['country_code'], 'state' => utf8_encode($location['region']), 'city' => utf8_encode($location['city']), 'properties' => $properties ); if ($this->customer_belongs_to_reseller) { $customer['reseller'] =intval($this->reseller); } if ($location['country_code'] == 'NL') { $customer['tel'] = '+31999999999'; } else if ($location['country_code'] == 'US') { $customer['tel'] = sprintf ("+1%s9999999",$location['area_code']); } else { $customer['tel'] = '+19999999999'; } $_customer_created=false; $j=0; while ($j < 3) { $username.=RandomString(4); $customer['username']=$username; if (!$result = $this->customerRecords->addRecord($customer)) { if ($this->customerRecords->SoapEngine->exception->errorcode != "5001") { $return=array('success' => false, 'error' => 'internal_error', 'error_message' => 'failed to create non-duplicate customer entry' ); print (json_encode($return)); return false; } } else { $_customer_created=true; break; } $j++; } if (!$_customer_created) { if ($this->sipRecords->soap_error_description) { $_msg=$this->sipRecords->soap_error_description; } else { $_msg='failed to create customer account'; } $return=array('success' => false, 'error' => 'internal_error', 'error_message' => $_msg ); print (json_encode($return)); return false; } else { $this->log_action("Owner account created (". $customer['username'].")"); } $owner=$result->id; if (!$owner) { $return=array('success' => false, 'error' => 'internal_error', 'error_message' => 'failed to obtain a new owner id' ); print (json_encode($return)); return false; } else { $this->log_action("Owner id is $owner (". $customer['username'].")"); } } else if (is_numeric($_REQUEST['owner']) && $_REQUEST['owner'] != 0 ) { $owner=intval($_REQUEST['owner']); } else { $return=array('success' => false, 'error' => 'internal_error', 'error_message' => 'no owner information provided' ); print (json_encode($return)); return false; } // create SIP Account $sipEngine = 'sip_accounts@'.$this->sipEngine; $this->SipSoapEngine = new SoapEngine($sipEngine,$this->soapEngines,$this->sipLoginCredentials); $_sip_class = $this->SipSoapEngine->records_class; $this->sipRecords = new $_sip_class($this->SipSoapEngine); $this->sipRecords->html=false; $sip_properties[]=array('name'=> 'ip', 'value' => $_SERVER['REMOTE_ADDR']); $sip_properties[]=array('name'=> 'registration_email', 'value' => $_REQUEST['email']); $languages=array("en","ro","nl","es","de"); if (isset($_REQUEST['lang'])){ if (in_array($_REQUEST['lang'],$languages)) { $sip_properties[]=array('name'=> 'language', 'value' => $_REQUEST['lang']); } } if (strlen($timezone)) { $sip_properties[]=array('name'=> 'timezone', 'value' => $timezone); } if (strlen($user_agent)) { $sip_properties[]=array('name'=> 'user_agent', 'value' => trim(urldecode($user_agent))); } $sipAccount = array('account' => $sip_address, 'fullname' => $_REQUEST['display_name'], 'email' => $_REQUEST['email'], 'password' => $_REQUEST['password'], 'timezone' => $timezone, 'prepaid' => $this->prepaid, 'pstn' => $this->allow_pstn, 'quota' => $this->quota, 'owner' => intval($owner), 'groups' => $this->groups, 'properties'=> $sip_properties ); $this->log_action("Create SIP account ($sip_addres)"); if (!$result = $this->sipRecords->addRecord($sipAccount)) { if ($this->sipRecords->SoapEngine->exception->errorstring) { if ($this->sipRecords->SoapEngine->exception->errorcode == 1011) { $return=array('success' => false, 'error' => 'user_exists', 'error_message' => $this->sipRecords->SoapEngine->exception->errorstring ); } else { $return=array('success' => false, 'error' => 'internal_error', 'error_message' => $this->sipRecords->SoapEngine->exception->errorstring ); } } else { $_msg='failed to create sip account'; $return=array('success' => false, 'error' => 'internal_error', 'error_message' => $_msg ); } print (json_encode($return)); $_dictionary=array('customer'=>intval($owner), 'error' => 'internal_error', 'confirm' => true ); $this->customerRecords->deleteRecord($_dictionary); return false; } else { $sip_address=$result->id->username.'@'.$result->id->domain; $this->log_action("SIP account created ($sip_address)"); if ($this->create_certificate) { if (!$passport = $this->generateCertificate($sip_address,$_REQUEST['email'],$_REQUEST['password'])) { $return=array('success' => false, 'error' => 'internal_error', 'error_message' => 'failed to generate certificate' ); print (json_encode($return)); return false; } } // Generic code for all sip settings pages if ($this->create_voicemail || $this->send_email_notification) { if ($SipSettings = new $this->sipClass($sip_address,$this->sipLoginCredentials,$this->soapEngines)) { if ($this->create_voicemail) { // Add voicemail account $this->log_action("Add voicemail account ($sip_address)"); $SipSettings->addVoicemail(); $SipSettings->setVoicemailDiversions(); } if ($this->send_email_notification) { // Sent account settings by email $SipSettings->sendEmail('hideHtml'); } } } if ($this->create_email_alias) { $this->log_action("Add email alias ($sip_address)"); $emailEngine = 'email_aliases@'.$this->emailEngine; $this->EmailSoapEngine = new SoapEngine($emailEngine,$this->soapEngines,$this->sipLoginCredentials); $_email_class = $this->EmailSoapEngine->records_class; $this->emailRecords = new $_email_class($this->EmailSoapEngine); $this->emailRecords->html=false; $emailAlias = array('name' => strtolower($sip_address), 'type' => 'MBOXFW', 'owner' => intval($owner), 'value' => $_REQUEST['email'] ); $this->emailRecords->addRecord($emailAlias); } $return=array('success' => true, 'sip_address' => $sip_address, 'email' => $result->email, 'settings_url' => $this->settings_url, 'outbound_proxy' => $this->outbound_proxy, 'xcap_root' => $this->xcap_root, 'msrp_relay' => $this->msrp_relay ); if ($this->create_certificate) { $return['passport'] = $passport; } if ($this->ldap_hostname) { $return['ldap_hostname'] = $this->ldap_hostname; } if ($this->ldap_dn) { $return['ldap_dn'] = $this->ldap_dn; } /* 'mdns_username' => $customer['username'], 'mdns_password' => $customer['password'], 'mdns_id' => intval($owner), 'outbound_proxy' => $this->outbound_proxy, 'xcap_root' => $this->xcap_root, 'msrp_relay' => $this->msrp_relay, 'ldap_hostname' => $this->ldap_hostname, 'ldap_dn' => $this->ldap_dn */ print (json_encode($return)); return true; } } function generateCertificate($sip_address,$email,$password) { if (!$this->init) return false; if (!is_array($this->enrollment)) { print _("Error: missing enrollment settings"); return false; } if (!$this->enrollment['ca_conf']) { //print _("Error: missing enrollment ca_conf settings"); return false; } if (!$this->enrollment['ca_crt']) { //print _("Error: missing enrollment ca_crt settings"); return false; } if (!$this->enrollment['ca_key']) { //print _("Error: missing enrollment ca_key settings"); return false; } $config = array( 'config' => $this->enrollment['ca_conf'], 'digest_alg' => 'md5', 'private_key_bits' => 1024, 'private_key_type' => OPENSSL_KEYTYPE_RSA, 'encrypt_key' => false, ); $dn = array( "countryName" => $this->enrollment['countryName'], "stateOrProvinceName" => $this->enrollment['stateOrProvinceName'], "localityName" => $this->enrollment['localityName'], "organizationName" => $this->enrollment['organizationName'], "organizationalUnitName" => $this->enrollment['organizationalUnitName'], "commonName" => $sip_address, "emailAddress" => $email ); $this->key = openssl_pkey_new($config); $this->csr = openssl_csr_new($dn, $this->key); openssl_csr_export($this->csr, $this->csr_out); openssl_pkey_export($this->key, $this->key_out, $password, $config); $ca="file://".$this->enrollment['ca_crt']; $this->crt = openssl_csr_sign($this->csr, $ca, $this->enrollment['ca_key'], 3650, $config); if ($this->crt==FALSE) { while (($e = openssl_error_string()) !== false) { echo $e . "\n"; print "

    "; } return false; } openssl_x509_export ($this->crt, $this->crt_out); openssl_pkcs12_export ($this->crt, $this->pk12_out, $this->key, $password); return array( 'crt' => $this->crt_out, 'key' => $this->key_out, 'pk12' => $this->pk12_out, 'ca' => file_get_contents($this->enrollment['ca_crt']) ); } function checkEmail($email) { dprint ("checkEmail($email)"); $regexp = "/^([a-z0-9][a-z0-9_.-]*)@([a-z0-9][a-z0-9-]*\.)+([a-z]{2,})$/i"; if (stristr($email,"-.") || !preg_match($regexp, $email)) { return false; } return true; } function loadTimezones () { if (!$fp = fopen("timezones", "r")) { syslog(LOG_NOTICE, 'Error: Failed to open timezones file'); return false; } while ($buffer = fgets($fp,1024)) { $this->timezones[]=trim($buffer); } fclose($fp); } } class PaypalProcessor { var $deny_countries = array(); var $allow_countries = array(); var $deny_ips = array(); var $make_credit_checks = true; var $transaction_results = array('success' => false); var $vat = 0; function PaypalProcessor($account) { require('cc_processor.php'); $this->CardProcessor = new CreditCardProcessor(); $this->account = &$account; } function refundTransaction($transaction_id) { } function doDirectPayment($basket) { if (!is_object($this->account)) { print " "; print 'Invalid account data'; print " "; return false; } if (!is_array($basket)) { print " "; print 'Invalid basket data'; print " "; return false; } if (is_array($this->test_credit_cards) && in_array($_POST['creditCardNumber'], $this->test_credit_cards)) { $this->CardProcessor->environment='sandbox'; } $this->CardProcessor->chapter_class = 'chapter'; $this->CardProcessor->odd_row_class = 'oddc'; $this->CardProcessor->even_row_class = 'evenc'; $this->CardProcessor->note = $this->account->account; $this->CardProcessor->account = $this->account->account; $this->CardProcessor->vat = $this->vat; // set hidden elements we need to preserve in the shopping cart application $this->CardProcessor->hidden_elements = $this->account->hiddenElements; // load shopping items $this->CardProcessor->cart_items=$basket; // load user information from owner information if available otherwise from sip account settings if ($this->account->owner_information['firstName']) { $this->CardProcessor->user_account['FirstName']=$this->account->owner_information['firstName']; } else { $this->CardProcessor->user_account['FirstName']=$this->account->firstName; } if ($this->account->owner_information['lastName']) { $this->CardProcessor->user_account['LastName']=$this->account->owner_information['lastName']; } else { $this->CardProcessor->user_account['LastName']=$this->account->lastName; } if ($this->account->owner_information['email']) { $this->CardProcessor->user_account['Email']=$this->account->owner_information['email']; } else { $this->CardProcessor->user_account['Email']=$this->account->email; } if ($this->account->owner_information['address'] && $this->account->owner_information['address']!= 'Unknown') { $this->CardProcessor->user_account['Address1']=$this->account->owner_information['address']; } else { $this->CardProcessor->user_account['Address1']=''; } if ($this->account->owner_information['city'] && $this->account->owner_information['city']!= 'Unknown') { $this->CardProcessor->user_account['City']=$this->account->owner_information['city']; } else { $this->CardProcessor->user_account['City']=''; } if ($this->account->owner_information['country'] && $this->account->owner_information['country']!= 'Unknown') { $this->CardProcessor->user_account['Country']=$this->account->owner_information['country']; } else { $this->CardProcessor->user_account['Country']=''; } if ($this->account->owner_information['state'] && $this->account->owner_information['state']!= 'Unknown') { $this->CardProcessor->user_account['State']=$this->account->owner_information['state']; } else { $this->CardProcessor->user_account['State']=''; } if ($this->account->owner_information['postcode'] && $this->account->owner_information['postcode']!= 'Unknown') { $this->CardProcessor->user_account['PostCode']=$this->account->owner_information['postcode']; } else { $this->CardProcessor->user_account['PostCode']=''; } if ($_REQUEST['purchase'] == '1' ) { $chapter=sprintf(_("Transaction Results")); $this->account->showChapter($chapter); print " "; // ensure that submit requests are coming only from the current page if ($_SERVER['HTTP_REFERER'] == $this->CardProcessor->getPageURL()) { // check submitted values $errors = $this->CardProcessor->checkForm($_POST); if (count($errors) > 0){ print $this->CardProcessor->displayFormErrors($errors); foreach (array_keys($errors) as $key) { $log_text.=sprintf("%s:%s ",$errors[$key]['field'],$errors[$key]['desc']); } $log=sprintf("CC transaction for %s failed with error: %s",$this->account->account,$log_text); syslog(LOG_NOTICE, $log); return false; } // process the payment $b=time(); $pay_process_results = $this->CardProcessor->processPayment($_POST); if(count($pay_process_results['error']) > 0){ // there was a problem with payment // show error and stop if ($pay_process_results['error']['field'] == 'reload') { print $pay_process_results['error']['desc']; } else { print $this->CardProcessor->displayProcessErrors($pay_process_results['error']); } $e=time(); $d=$e-$b; $log=sprintf("CC transaction for %s failed with error: %s (%s) after %d seconds", $this->account->account, $pay_process_results['error']['short_message'], $pay_process_results['error']['error_code'], $d ); syslog(LOG_NOTICE, $log); return false; } else { $e=time(); $d=$e-$b; $log=sprintf("CC transaction %s for %s completed succesfully in %d seconds", $pay_process_results['success']['desc']->TransactionID, $this->account->account, $d ); syslog(LOG_NOTICE, $log); print "

    "; print _("Transaction completed sucessfully. "); /* if ($this->CardProcessor->environment!='sandbox' && $this->account->first_transaction) { print "

    "; print _("This is your first payment. "); print "

    "; print _("Please allow the time to check the validity of your transaction before activating your Credit. "); print "

    "; print _("You can speed up the validation process by sending a copy of an utility bill (electriciy, gas or TV) that displays your address. "); print "

    "; printf (_("For questions related to your payments or to request a refund please email to %s and mention your transaction id %s. "), $this->account->billing_email, $pay_process_results['success']['desc']->TransactionID ); $this->make_credit_checks=true; } else { print "

    "; print _("You may check your new balance in the Credit tab. "); } */ } if ($this->account->Preferences['ip'] && $_loc=geoip_record_by_name($this->account->Preferences['ip'])) { $enrollment_location=$_loc['country_name'].'/'.$_loc['city']; } else if ($this->account->Preferences['ip'] && $_loc=geoip_country_name_by_name($this->account->Preferences['ip'])) { $enrollment_location=$_loc; } else { $enrollment_location='Unknown'; } if ($_loc=geoip_record_by_name($_SERVER['REMOTE_ADDR'])) { $transaction_location=$_loc['country_name'].'/'.$_loc['city']; } else if ($_loc=geoip_country_name_by_name($_SERVER['REMOTE_ADDR'])) { $transaction_location=$_loc; } else { $transaction_location='Unknown'; } if ($this->account->Preferences['timezone']) { $timezone=$this->account->Preferences['timezone']; } else { $timezone='Unknown'; } $extra_information=array( 'Account Page' => $this->account->admin_url_absolute, 'Account First Name' => $this->account->firstName, 'Account Last Name ' => $this->account->lastName, 'Account Timezone' => $this->account->timezone, 'Enrollment IP' => $this->account->Preferences['ip'], 'Enrollment Location' => $enrollment_location, 'Enrollment Email' => $this->account->Preferences['registration_email'], 'Enrollment Timezone' => $timezone, 'Transaction Location' => $transaction_location ); $result = $this->account->addInvoice($this->CardProcessor); if ($result) { $extra_information['Invoice Page']=sprintf("https://admin.ag-projects.com/admin/invoice.phtml?iId=%d&adminonly=1",$result['invoice']); } if ($this->CardProcessor->saveOrder($_POST,$pay_process_results,$extra_information)) { $this->transaction_results=array('success' => true, 'id' => $this->CardProcessor->transaction_data['TRANSACTION_ID'] ); return true; } else { $log=sprintf("Error: SIP Account %s - CC transaction %s failed to save order",$this->account->account, $this->CardProcessor->transaction_data['TRANSACTION_ID']); syslog(LOG_NOTICE, $log); return false; } } else { print _("Invalid CC Request"); return false; } print " "; } else { print " "; // print the submit form $arr_form_page_objects = $this->CardProcessor->showSubmitForm(); print $arr_form_page_objects['page_body_content']; print " "; } } function fraudDetected() { if (count($this->deny_ips)) { foreach ($this->deny_ips as $_ip) { if ($this->account->Preferences['ip'] && preg_match("/^$_ip/",$this->account->Preferences['ip'])) { $this->fraud_reason=$this->account->Preferences['ip'].' is Blocked'; return true; } if (preg_match("/^$_ip/",$_SERVER['REMOTE_ADDR'])) { $this->fraud_reason=$_SERVER['REMOTE_ADDR'].' is a Blocked'; return true; } } } if (count($this->deny_countries)) { if ($_loc=geoip_record_by_name($this->account->Preferences['ip'])) { if (in_array($_loc['country_name'],$this->deny_countries)) { $this->fraud_reason=$_loc['country_name'].' is Blocked'; return true; } } } if (count($this->allow_countries)) { if ($_loc=geoip_record_by_name($this->account->Preferences['ip'])) { if (!in_array($_loc['country_name'],$this->allow_countries)) { $this->fraud_reason=$_loc['country_name'].' is Not Allowed'; return true; } } } if (count($this->deny_email_domains)) { if (count($this->accept_email_addresses)) { if (in_array($this->account->email,$this->accept_email_addresses)) return false; } list($user,$domain)= explode("@",$this->account->email); foreach ($this->deny_email_domains as $deny_domain) { if ($domain == $deny_domain) { $this->fraud_reason=sprintf ('Domain %s is Not Allowed',$domain); return true; } } } return false; } } class DIDProcessor { function DIDProcessor() { /* http://www.didww.com/support/ API help page: http://open.didww.com */ $this->db = new DB_CDRTool(); require('didww_soap_library.php'); include("/etc/cdrtool/enrollment/config.ini"); if (!$enrollment['did_username'] || !$enrollment['did_key']) { print '

    Error: Missing DID engine credentials'; return false; } if ($enrollment['did_environment'] == 'production') { $this->did_engine = new WebService_DID_World_Wide__DID_World_Wide_Port(); $this->auth_string = sha1($enrollment['did_username'].$enrollment['did_key']); $this->environment='production'; } else { print "

    Testing DID environment

    "; flush(); $this->did_engine = new WebService_DID_World_Wide__DID_World_Wide_Port_Testing(); $this->auth_string = sha1($enrollment['did_username'].$enrollment['did_key'].'sandbox'); $this->environment='testing'; } $this->did_engine->_options['timeout'] = 30; } function getPrefixesFromRemote () { if (!$this->auth_string) return false; $result = $this->did_engine->didww_getdidwwregions($this->auth_string,$country); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error: %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { foreach ($result as $_country) { foreach ($_country->cities as $_city) { $prefix = $_country->country_prefix.$_city->city_prefix; if (!$_city->isavailable) continue; $prefixes[$prefix]=array('country_prefix' => trim($_country->country_prefix), 'country_name' => trim($_country->country_name), 'country_iso' => trim($_country->country_iso), 'city_name' => trim($_city->city_name), 'city_prefix' => trim($_city->city_prefix), 'setup' => $_city->setup, 'monthly' => $_city->monthly ); } } } return $prefixes; } function getPrefixes () { $query=sprintf("select * from ddi_cache where environment = '%s' and DATE_ADD(date, INTERVAL +1 day) > NOW()",addslashes($this->environment)); if (!$this->db->query($query)) return false; if ($this->db->num_rows()) { $this->db->next_record(); $prefixes = json_decode($this->db->f('cache'),true); if (!is_array($prefixes)) { $prefixes = $this->cachePrefixes(); } } else { $prefixes=$this->cachePrefixes(); } return $prefixes; } function cachePrefixes() { if ($prefixes = $this->getPrefixesFromRemote()) { $query=sprintf("delete from ddi_cache where environment = '%s'",addslashes($this->environment)); $this->db->query($query); $query=sprintf("insert into ddi_cache (cache,date,environment) values ('%s', NOW(),'%s')",addslashes(json_encode($prefixes)),addslashes($this->environment)); $this->db->query($query); return $prefixes; } else { return false; } } function getResellerInfo() { if (!$this->auth_string) return false; $result = $this->did_engine->didww_getdidwwapidetails($this->auth_string); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error: %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { print "

    ";
                 print_r($result);
                 print "
    "; } } function createOrder($data) { if (!$this->auth_string) return false; print "
    ";
             print_r($data);
             print "
    "; $result = $this->did_engine->didww_ordercreate($this->auth_string, $data['customer_id'], $data['country_iso'], $data['city_prefix'], $data['period'], $data['map_data'], $data['prepaid_funds'], $data['uniq_hash'] ); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error: %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { $query=sprintf ("insert into ddi_numbers ( `customer_id`, `country_name`, `city_name`, `did_number`, `did_status`, `did_timeleft`, `did_expire_date_gmt`, `order_id`, `order_status`, `sip_address`, `did_setup`, `did_monthly`, `did_period`, `prepaid_balance`, `environment` ) values ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ", addslashes($data['customer_id']), addslashes($result->country_name), addslashes($result->city_name), addslashes($result->did_number), addslashes($result->did_status), addslashes($result->did_timeleft), addslashes($result->did_expire_date_gmt), addslashes($result->order_id), addslashes($result->order_status), addslashes($data['map_data']['map_detail']), addslashes($result->did_setup), addslashes($result->did_monthly), addslashes($result->did_period), addslashes($result->prepaid_balance), addslashes($this->environment) ); if (!$this->db->query($query)) { $log=sprintf ("Database error for DID createOrder: %s (%s)",$this->db->Error,$this->db->Errno); print $log; syslog(LOG_NOTICE, $log); } } } function renewOrder($data) { if (!$this->auth_string) return false; print "

    ";
             print_r($data);
             print "
    "; $result = $this->did_engine->didww_orderautorenew($this->auth_string, $data['customer_id'], $data['number'], $data['period'], $data['uniq_hash'] ); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error: %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { $query=sprintf ("update ddi_numbers set did_timeleft = '%s' and did_expire_date_gmt = '%s' where did_number = '%s' ", addslashes($result->did_timeleft), addslashes($result->did_expire_date_gmt), addslashes($result->did_number) ); if (!$this->db->query($query)) { $log=sprintf ("Database error for DID renewOrder: %s (%s)",$this->db->Error,$this->db->Errno); print $log; syslog(LOG_NOTICE, $log); } print $query; } } function cancelOrder($data) { if (!$this->auth_string) return false; print "

    ";
             print_r($data);
             print "
    "; $result = $this->did_engine->didww_ordercancel($this->auth_string, $data['customer_id'], $data['number'] ); if (PEAR::isError($result)) { $error_msg = $result->getMessage(); $error_fault= $result->getFault(); $error_code = $result->getCode(); printf ("

    Error: %s (%s): %s",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring); return false; } else { $query=sprintf ("delete from ddi_numbers where did_number = '%s'",addslashes($result->did_number)); if (!$this->db->query($query)) { $log=sprintf ("Database error for DID cancelOrder: %s (%s)",$this->db->Error,$this->db->Errno); print $log; syslog(LOG_NOTICE, $log); } print $query; } } function getOrders($sip_address) { $orders=array(); $query=sprintf ("select * from ddi_numbers where sip_address = '%s' and environment = '%s'",addslashes($sip_address),addslashes($this->environment)); if (!$this->db->query($query)) { $log=sprintf ("Database error for DID createOrder: %s (%s)",$this->db->Error,$this->db->Errno); print $log; syslog(LOG_NOTICE, $log); } else { while ($this->db->next_record()) { $orders[$this->db->f('did_number')]=array('country_name' => $this->db->f('country_name'), 'city_name' => $this->db->f('city_name'), 'did_status' => $this->db->f('did_status'), 'did_timeleft' => $this->db->f('did_timeleft'), 'did_expire_date_gmt' => $this->db->f('did_expire_date_gmt'), 'order_id' => $this->db->f('order_id'), 'order_status' => $this->db->f('order_status'), 'sip_address' => $this->db->f('sip_address'), 'did_setup' => $this->db->f('did_setup'), 'did_monthly' => $this->db->f('did_monthly') ); } } return $orders; } } function RandomIdentifier($length=30) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, strlen($characters) - 1)]; } return $randomString; } if (file_exists("/etc/cdrtool/local/sip_settings.php")) { require_once('/etc/cdrtool/local/sip_settings.php'); } ?>