function normalize($save="",$table="") { if (!$table) $table = $this->CDRS->table; if ($this->CDRS->CSCODE && $CarrierInfo = $this->CDRS->CDRTool['normalize']['CS_CODES'][$this->CDRS->CSCODE]) { // We found a carrier so we set the BillingId $this->BillingId = $CarrierInfo[BillingPartyId]; } if ($save) { if (!$this->id) { return 0; } $query =""; $query1 =""; $query2 =""; if ($this->CDRS->normalizedField) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s='1' ",addslashes($this->CDRS->normalizedField)); $mongo_field = array_search($this->CDRS->normalizedField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = 1; } if ($this->CDRS->BillingPartyIdField && $this->BillingPartyId) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->BillingPartyIdField),addslashes($this->BillingPartyId)); $mongo_field = array_search($this->CDRS->BillingPartyIdField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->BillingPartyId; } if (strlen($this->durationNormalized) && $this->durationNormalized != $this->duration) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s ='%s' ",addslashes($this->CDRS->durationField),addslashes($this->durationNormalized)); $this->duration=$this->durationNormalized; $mongo_field = array_search($this->CDRS->durationField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = intval($this->durationNormalized); } else { $mongo_field = array_search($this->CDRS->durationField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = intval($this->duration); } if ($this->CDRS->DestinationIdField) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->DestinationIdField),addslashes($this->DestinationId)); $mongo_field = array_search($this->CDRS->DestinationIdField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->DestinationId; } if ($this->CDRS->ResellerIdField) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->ResellerIdField),addslashes($this->ResellerId)); $mongo_field = array_search($this->CDRS->ResellerIdField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->ResellerId; } if ($this->usernameNormalized && $this->usernameNormalized!=$this->username) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->usernameField),addslashes($this->usernameNormalized)); $mongo_field = array_search($this->CDRS->usernameField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->usernameNormalized; } if ($this->aNumberNormalized && $this->aNumberNormalized!=$this->aNumber) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->aNumberField),addslashes($this->aNumberNormalized)); $this->aNumber=$this->aNumberNormalized; $mongo_field = array_search($this->CDRS->aNumberField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->aNumberNormalized; } if ($this->CDRS->applicationField && $this->applicationNormalized) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->applicationField), addslashes($this->applicationNormalized)); $this->application=$this->applicationNormalized; $mongo_field = array_search($this->CDRS->applicationField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->applicationNormalized; } if ($this->CDRS->flowField && $this->flow) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->flowField),addslashes($this->flow)); $mongo_field = array_search($this->CDRS->flowField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->flow; } if ($this->domainNormalized && $this->domainNormalized != $this->domain) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->domainField),addslashes($this->domainNormalized)); $this->domainNumber=$this->domainNormalized; $this->domain=$this->domainNormalized; $mongo_field = array_search($this->CDRS->domainField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->domainNormalized; } if ($this->cNumberNormalized && $this->cNumberNormalized!=$this->cNumber) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->cNumberField),addslashes($this->cNumberNormalized)); $this->cNumber=$this->cNumberNormalized; $mongo_field = array_search($this->CDRS->cNumberField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->cNumberNormalized; } if ($this->CDRS->BillingIdField && $this->BillingId) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->BillingIdField),addslashes($this->BillingId)); $mongo_field = array_search($this->CDRS->BillingIdField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->BillingId; } if ($this->CDRS->RemoteAddressField && $this->RemoteAddressNormalized && $this->RemoteAddressNormalized!= $this->RemoteAddress) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->RemoteAddressField),addslashes($this->RemoteAddressNormalized)); $mongo_field = array_search($this->CDRS->RemoteAddressField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->RemoteAddressNormalized; } if ($this->CDRS->CanonicalURIField && $this->CanonicalURINormalized && $this->CanonicalURINormalized!= $this->CanonicalURI) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->CanonicalURIField),addslashes($this->CanonicalURINormalized)); $mongo_field = array_search($this->CDRS->CanonicalURIField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->CanonicalURINormalized; } if ($this->stopTimeNormalized) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->stopTimeField),addslashes($this->stopTimeNormalized)); $mongo_field = array_search($this->CDRS->stopTimeField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->stopTimeNormalized; } if ($this->CDRS->ratingEnabled && ($this->duration || $this->application == 'message')) { if ($this->DestinationId) { $Rate = new Rate($this->CDRS->rating_settings, $this->CDRS->cdrtool); if ($this->application == 'message') { $RateDictionary=array( 'callId' => $this->callId, 'timestamp' => $this->timestamp, 'duration' => $this->duration, 'DestinationId' => $this->DestinationId, 'BillingPartyId' => $this->BillingPartyId, 'ResellerId' => $this->ResellerId, 'domain' => $this->domain, 'gateway' => $this->gateway, 'RatingTables' => $this->CDRS->RatingTables, 'aNumber' => $this->aNumber, 'cNumber' => $this->cNumber ); $Rate->calculateMessage($RateDictionary); } else { $RateDictionary=array( 'callId' => $this->callId, 'timestamp' => $this->timestamp, 'duration' => $this->duration, 'DestinationId' => $this->DestinationId, 'inputTraffic' => $this->inputTraffic, 'outputTraffic' => $this->outputTraffic, 'BillingPartyId' => $this->BillingPartyId, 'ResellerId' => $this->ResellerId, 'domain' => $this->domain, 'gateway' => $this->gateway, 'RatingTables' => $this->CDRS->RatingTables, 'aNumber' => $this->aNumber, 'cNumber' => $this->cNumber, 'ENUMtld' => $this->ENUMtld, 'application' => $this->application ); $Rate->calculateAudio($RateDictionary); } $this->pricePrint = $Rate->pricePrint; $this->price = $Rate->price; $this->rateInfo = $Rate->rateInfo; $this->rateDuration = $Rate->duration; if ($Rate->broken_rate) { $this->broken_rate=true; } } else { $this->rateInfo=''; $this->pricePrint=''; $this->price=''; } if ($this->CDRS->priceField) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->priceField),addslashes($this->pricePrint)); $mongo_field = array_search($this->CDRS->priceField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = floatval($this->pricePrint); if ($this->CDRS->rateField ) { if ($updatedFields) $query .= ", "; $updatedFields++; $query.=sprintf(" %s = '%s' ",addslashes($this->CDRS->rateField),addslashes($this->rateInfo)); $mongo_field = array_search($this->CDRS->rateField, $this->CDRS->CDRFields); $this->mongo_cdr[$mongo_field] = $this->rateInfo; } } } $query1 = sprintf("update %s set %s where %s = '%s'",addslashes($table),$query,addslashes($this->idField),addslashes($this->id)); dprint($query1); #TODO remove me, I am used to temporary sync mysql data with mongo data if ($this->CDRS->mongo_table) { $mongo_field = array_search($this->idField, $this->CDRS->CDRFields); try { $this->CDRS->mongo_table->update(array($mongo_field => $this->id), $this->mongo_cdr, array("upsert" => true)); } catch (MongoException $e) { printf("Caught Mongo exception: %s", $e->getMessage()); } catch (Exception $e) { printf("Caught exception: %s", $e->getMessage()); } } if ($updatedFields) { if ($this->CDRS->CDRdb1->query($query1)) { if ($this->CDRS->CDRdb1->affected_rows()) { if ( $this->isBillingPartyLocal() && $table == "radacct".date('Ym')) { // cache usage only if current month $_traffic=($this->inputTraffic+$this->outputTraffic)/2; $_usage=array('calls' => 1, 'duration' => $this->duration, 'cost' => $this->price, 'cost_today' => $this->price, 'traffic' => $_traffic ); $this->cacheQuotaUsage($_usage); } } else { if (preg_match("/^(\w+)(\d{4})(\d{2})$/",$table,$m)) { $previousTable=$m[1].date('Ym', mktime(0, 0, 0, $m[3]-1, "01", $m[2])); $query2 = sprintf("update %s set %s where %s = '%s'",addslashes($previousTable),$query,addslashes($this->idField),addslashes($this->id)); if ($this->CDRS->CDRdb1->query($query2)) { if ($this->CDRS->CDRdb1->affected_rows()) { if ( $this->isBillingPartyLocal() && $previousTable == "radacct".date('Ym')) { // cache usage only if current month $_traffic=($this->inputTraffic+$this->outputTraffic)/2; $_usage=array('calls' => 1, 'duration' => $this->duration, 'cost' => $this->price, 'cost_today' => $this->price, 'traffic' => $_traffic ); $this->cacheQuotaUsage($_usage); } } } else { $log=sprintf ("Database error: %s (%s)",$this->CDRS->CDRdb1->Error,$this->CDRS->CDRdb1->Errno); syslog(LOG_NOTICE, $log); print($log); return 0; } } } return 1; } else { $log=sprintf ("Database error for query %s: %s (%s)",$query1,$this->CDRS->CDRdb1->Error,$this->CDRS->CDRdb1->Errno); syslog(LOG_NOTICE, $log); print($log); return 0; } } } else { if ($this->CDRS->BillingPartyIdField && $CarrierInfo['BillingPartyId']) { $this->domain = $CarrierInfo['BillingDomain']; } if ($this->usernameNormalized && $this->usernameNormalized!=$this->username) { $this->username=$this->usernameNormalized; } if ($this->aNumberNormalized && $this->aNumberNormalized!=$this->aNumber) { $this->aNumber=$this->aNumberNormalized; } if ($this->domainNormalized && $this->domainNormalized != $this->domain) { $this->domainNumber=$this->domainNormalized; } if ($this->cNumberNormalized && $this->cNumberNormalized!=$this->cNumber) { $this->cNumber=$this->cNumberNormalized; } if ($this->CDRS->RemoteAddressField && $this->RemoteAddressNormalized && $this->RemoteAddressNormalized!= $this->RemoteAddress) { $this->RemoteAddress=$this->RemoteAddressNormalized; } } return 1; }
function processNetworkInput($tinput) { // Read key=value pairs from input // Strip any unnecessary spaces $this->runtime=array(); $tinput=preg_replace("/\s+/"," ",$tinput); if ($tinput == "/" and strlen($this->last_input)) { $tinput = $this->last_input; } else { $this->last_input = $tinput; } $_els=explode(" ",trim($tinput)); $this->runtime['start']=microtime_float(); syslog(LOG_NOTICE, $tinput); if (!$_els[0]) return 0; // read fields from input unset($NetFields); unset($seenField); $i=0; while ($i < count($_els)) { $i++; $_dict = explode("=",$_els[$i]); $_key = strtolower(trim($_dict[0])); if ($_key == 'callid') { $_value = trim($_dict[1]); } else { $_value = strtolower(trim($_dict[1])); } if ($_key && $seenField[$_key]) { $log=sprintf ("Error: '$_key' attribute is present more than once in $tinput"); syslog(LOG_NOTICE, $log); return 0; } else { if ($_key) { $NetFields[$_key]=$_value; $seenField[$_key]++; } } } $NetFields['action']=strtolower($_els[0]); $this->method = $NetFields['action']; // begin processing if ($NetFields['action']=="maxsessiontime") { if (!$NetFields['from']) { $log=sprintf ("error: missing From parameter"); syslog(LOG_NOTICE, $log); return $log; } if (!$NetFields['to']) { $log=sprintf ("error: missing To parameter"); syslog(LOG_NOTICE, $log); return $log; } if (!$NetFields['gateway']) { $log=sprintf ("error: missing gateway parameter"); syslog(LOG_NOTICE, $log); return $log; } if (!$NetFields['callid']) { $log=sprintf ("error: missing Call Id parameter"); syslog(LOG_NOTICE, $log); return $log; } if (!$NetFields['duration'] && $this->settings['MaxSessionTime']) { $NetFields['duration']=$this->settings['MaxSessionTime']; } $app_prefix = preg_replace('/[.].*$/', '', $NetFields['application']); if (strlen($app_prefix)) { if ($app_prefix == 'audio' || $app_prefix == 'sms' ) { $application=$NetFields['application']; } else { $log=sprintf ("error: unsupported application %s",$NetFields['application']); syslog(LOG_NOTICE, $log); return $log; } } else { $application='audio'; } list($username_t,$domain_t)=explode("@",$NetFields['from']); $CDRStructure=array ( $this->CDRS->CDRFields['callId'] => $NetFields['callid'], $this->CDRS->CDRFields['aNumber'] => $NetFields['from'], $this->CDRS->CDRFields['CanonicalURI'] => $NetFields['to'], $this->CDRS->CDRFields['gateway'] => $NetFields['gateway'], $this->CDRS->CDRFields['duration'] => floor($NetFields['duration']), $this->CDRS->CDRFields['timestamp'] => time(), $this->CDRS->CDRFields['domain'] => $domain_t, $this->CDRS->CDRFields['application'] => $application, 'skip_fix_prepaid_duration' => true ); $CDR = new $this->CDRS->CDR_class($this->CDRS, $CDRStructure); $CDR->normalize(); $this->runtime['normalize_cdr']=microtime_float(); $query=sprintf("select * from %s where account = '%s'",addslashes($this->prepaid_table),addslashes($CDR->BillingPartyId)); if (!$this->db->query($query)) { $log=sprintf ("Database error for query '%s': %s (%s), link_id =%s, query_id =%s",$query,$this->db->Error,$this->db->Errno,$this->db->Link_ID,$this->db->Query_ID); syslog(LOG_NOTICE,$log); $this->logRuntime(); $ret=sprintf("error: database error for query '%s': %s (%s)",$query,$this->db->Error,$this->db->Errno)."\n"."type=prepaid"; return $ret; } if (!$this->db->num_rows()) { $log=sprintf ("MaxSessionTime=unlimited Type=postpaid CallId=%s BillingParty=%s",$NetFields['callid'],$CDR->BillingPartyId); syslog(LOG_NOTICE, $log); $ret="none"."\n"."type=postpaid"; return $ret; } $this->db->next_record(); $current_balance = $this->db->f('balance'); $old_session_counter = $this->db->f('session_counter'); $max_sessions = $this->db->f('max_sessions'); if (strlen($this->db->f('active_sessions'))) { // load active sessions $active_sessions = json_decode($this->db->f('active_sessions'),true); if (count($active_sessions)) { // purge stale sessions $active_sessions_new=array(); $expired=0; foreach (array_keys($active_sessions) as $_session) { $expired_since=time() - $active_sessions[$_session]['timestamp'] - $active_sessions[$_session]['MaxSessionTime']; if ($expired_since > 120) { // this session has passed its maxsessiontime plus its reasonable setup time of 2 minutes, // it could be stale // because the call control module did not call debitbalance, so we purge it $log = sprintf ("Session %s for %s has expired since %d seconds", $_session, $active_sessions[$_session]['BillingPartyId'], $expired_since); syslog(LOG_NOTICE, $log); $expired++; } else { $active_sessions_new[$_session]=$active_sessions[$_session]; } } if ($expired) { $active_sessions=$active_sessions_new; } } } else { $active_sessions=array(); } if (!$current_balance) { $log=sprintf ("No balance found"); syslog(LOG_NOTICE,$log); $this->logRuntime(); $ret="0"."\n"."type=prepaid"; return $ret; } if (preg_match("/^0[0-9]{1,}@/",$CDR->CanonicalURINormalized)) { if (!$CDR->DestinationId) { $log = sprintf ("error: cannot figure out the destination id for %s",$CDR->CanonicalURI); $this->logRuntime(); syslog(LOG_NOTICE, $log); $ret=$log."\n"."type=prepaid"; return $ret; } } else { $log=sprintf ("MaxSessionTime=unlimited Type=prepaid CallId=%s BillingParty=%s DestId=None",$NetFields['callid'],$CDR->BillingPartyId); syslog(LOG_NOTICE, $log); $this->logRuntime(); $ret="none"."\n"."type=prepaid"; return $ret; } $session_counter=count($active_sessions); if ($max_sessions && $session_counter >= $max_sessions) { $log = sprintf ("Locked: maximum number of concurrent calls %s reached, $max_sessions allowed"); syslog(LOG_NOTICE, $log); $ret="Locked"."\n"."type=prepaid"; return $ret; } $maxduration=0; // Build Rate dictionary containing normalized CDR fields plus customer Balance if (count($active_sessions)) { // set $this->remaining_balance and $this->parallel_calls for ongoing calls: if (!$this->getActivePrepaidSessions($active_sessions, $current_balance, $CDR->BillingPartyId, array($CDR->callId))) { $ret="0"."\n"."type=prepaid"; return $ret; } $this->runtime['get_parallel_calls']=microtime_float(); // add this new call to the list of parallel calls $RateDictionary=array( 'duration' => $CDR->duration, 'callId' => $CDR->callId, 'Balance' => $this->remaining_balance, 'timestamp' => $CDR->timestamp, 'DestinationId' => $CDR->DestinationId, 'region' => $CDR->region, 'domain' => $CDR->domain, 'gateway' => $CDR->gateway, 'BillingPartyId' => $CDR->BillingPartyId, 'ENUMtld' => $CDR->ENUMtld, 'RatingTables' => $this->CDRS->RatingTables, 'application' => $application ); $Rate = new Rate($this->settings, $this->db); $_maxduration = round($Rate->MaxSessionTime($RateDictionary)); $log = sprintf ("Maximum duration for new session %s of %s to destination %s having balance=%s is %s", $CDR->callId, $CDR->BillingPartyId, $CDR->DestinationId, $this->remaining_balance, $_maxduration); syslog(LOG_NOTICE, $log); if ($_maxduration > 0) { $this->parallel_calls[$CDR->callId]=array('remainingBalancePerSecond' => $this->remaining_balance/$_maxduration); } else { $log = sprintf ("Maximum duration for new session %s of %s <=0",$CDR->callId,$CDR->BillingPartyId); syslog(LOG_NOTICE, $log); $ret="0"."\n"."type=prepaid"; return $ret; } $this->parallel_calls[$CDR->callId]=array('remainingBalancePerSecond' => $this->remaining_balance/$_maxduration); $maxduration=$this->getAggregatedMaxSessiontime($this->parallel_calls, $this->remaining_balance, $CDR->BillingPartyId); } else { $RateDictionary=array( 'duration' => $CDR->duration, 'callId' => $CDR->callId, 'Balance' => $current_balance, 'timestamp' => $CDR->timestamp, 'DestinationId' => $CDR->DestinationId, 'region' => $CDR->region, 'domain' => $CDR->domain, 'gateway' => $CDR->gateway, 'BillingPartyId' => $CDR->BillingPartyId, 'ENUMtld' => $CDR->ENUMtld, 'RatingTables' => $this->CDRS->RatingTables, 'application' => $application ); $Rate = new Rate($this->settings, $this->db); $this->runtime['instantiate_rate']=microtime_float(); $maxduration = round($Rate->MaxSessionTime($RateDictionary)); } // add new active session $active_sessions[$CDR->callId]= array('timestamp' => $CDR->timestamp, 'duration' => $CDR->duration, 'BillingPartyId' => $CDR->BillingPartyId, 'MaxSessionTime' => $maxduration, 'domain' => $CDR->domain, 'gateway' => $CDR->gateway, 'Destination' => $CDR->destinationPrint, 'DestinationId' => $CDR->DestinationId, 'region' => $CDR->region, 'connectCost' => $Rate->connectCost ); if ($CDR->ENUMtld) { $active_sessions[$CDR->callId]['ENUMtld']=$CDR->ENUMtld; } $this->runtime['calculate_maxduration']=microtime_float(); if ($maxduration < 0) { $log = sprintf ("error: maxduration %s is negative",$maxduration); syslog(LOG_NOTICE, $log); $ret=$log."\n"."type=prepaid"; return $ret; } if ($Rate->min_duration && $maxduration < $Rate->min_duration) { $log = sprintf ("Notice: maxduration of %s is less then min_duration (%s)",$maxduration,$Rate->min_duration); syslog(LOG_NOTICE, $log); $ret="0"."\n"."type=prepaid"; return $ret; } if (!$Rate->billingTimezone) { $log = sprintf ("error: cannot figure out the billing timezone")."\n"."type=prepaid"; syslog(LOG_NOTICE, $log); $ret=$log."\n"."type=prepaid"; return $ret; } if (!$Rate->startTimeBilling) { $log = sprintf ("error: cannot figure out the billing start time")."\n"."type=prepaid"; syslog(LOG_NOTICE, $log); $ret=$log."\n"."type=prepaid"; return $ret; } $log=sprintf("MaxSessionTime=%s Type=prepaid CallId=%s BillingParty=%s DestId=%s Balance=%s Spans=%d Counter=%d->%d", $maxduration, $NetFields['callid'], $CDR->BillingPartyId, $CDR->DestinationId, $RateDictionary['Balance'], $Rate->MaxSessionTimeSpans, $old_session_counter, count($active_sessions) ); syslog(LOG_NOTICE, $log); if ($maxduration > 0) { $query=sprintf("update %s set active_sessions = '%s', session_counter = '%s' where account = '%s'", addslashes($this->prepaid_table), addslashes(json_encode($active_sessions)), count($active_sessions), addslashes($CDR->BillingPartyId)); if (!$this->db->query($query)) { $log=sprintf ("Database error for %s: %s (%s)",$query,$this->db->Error,$this->db->Errno); syslog(LOG_NOTICE,$log); $log=sprintf ("error: database error %s (%s)",$this->db->Error,$this->db->Errno); return $log; } } $this->runtime['update_prepaid']=microtime_float(); $this->logRuntime(); $ret=$maxduration."\n"."type=prepaid"; return $ret; } else if ($NetFields['action'] == "dumpprepaidsessions") { if (!$NetFields['account']) { $log=sprintf ("error: missing account parameter"); syslog(LOG_NOTICE, $log); return $log; } $query=sprintf("select * from %s where account = '%s'", addslashes($this->prepaid_table), addslashes($NetFields['account']) ); if (!$this->db->query($query)) { $log=sprintf ("Database error for %s: %s (%s)",$query,$this->db->Error,$this->db->Errno); syslog(LOG_NOTICE,$log); $this->logRuntime(); return 0; } if (!$this->db->num_rows()) { $log=sprintf ("DebitBalanceAudio() error: account $account does not exist"); syslog(LOG_NOTICE, $log); $this->logRuntime(); return 0; } $this->db->next_record(); return var_export(json_decode($this->db->f('active_sessions'),true), true); } else if ($NetFields['action'] == "debitbalance") { if (!$NetFields['from']) { $log=sprintf ("error: missing From parameter"); syslog(LOG_NOTICE, $log); return $log; } if (!$NetFields['to']) { $log=sprintf ("error: missing To parameter"); syslog(LOG_NOTICE, $log); return $log; } $app_prefix = preg_replace('/[.].*$/', '', $NetFields['application']); if (!strlen($app_prefix) || (strlen($app_prefix) && $app_prefix == 'audio')) { if (!strlen($NetFields['duration'])) { $log=sprintf ("error: missing Duration parameter"); syslog(LOG_NOTICE, $log); return $log; } } if (strlen($app_prefix)) { if ($app_prefix == 'audio' || $app_prefix == 'sms' ) { $application=$NetFields['application']; } else { $log=sprintf ("error: unsupported application %s",$NetFields['application']); syslog(LOG_NOTICE, $log); return $log; } } else { $application='audio'; $app_prefix='audio'; } if (!$NetFields['gateway']) { $log=sprintf ("error: missing gateway parameter"); syslog(LOG_NOTICE, $log); return $log; } if (!$NetFields['callid']) { $log=sprintf ("error: missing Call Id parameter"); syslog(LOG_NOTICE, $log); return $log; } if ($NetFields['force']) { $force=true; } else { $force=false; } $timestamp=time(); list($username_t,$domain_t)=explode("@",$NetFields['from']); $CDRStructure=array ( $this->CDRS->CDRFields['callId'] => $NetFields['callid'], $this->CDRS->CDRFields['aNumber'] => $NetFields['from'], $this->CDRS->CDRFields['CanonicalURI'] => $NetFields['to'], $this->CDRS->CDRFields['gateway'] => $NetFields['gateway'], $this->CDRS->CDRFields['ENUMtld'] => $NetFields['enumtld'], $this->CDRS->CDRFields['duration'] => floor($NetFields['duration']), $this->CDRS->CDRFields['timestamp'] => time(), $this->CDRS->CDRFields['domain'] => $domain_t, $this->CDRS->CDRFields['application'] => $application, 'skip_fix_prepaid_duration' => true ); // Init CDR $CDR = new $this->CDRS->CDR_class($this->CDRS, $CDRStructure); $CDR->normalize(); $this->runtime['normalize_cdr']=microtime_float(); // Build Rate dictionary containing normalized CDR fields plus customer Balance $RateDictionary=array( 'callId' => $NetFields['callid'], 'timestamp' => $CDR->timestamp, 'duration' => $CDR->duration, 'DestinationId' => $CDR->DestinationId, 'region' => $CDR->region, 'domain' => $CDR->domain, 'gateway' => $CDR->gateway, 'BillingPartyId' => $CDR->BillingPartyId, 'ENUMtld' => $CDR->ENUMtld, 'RatingTables' => $this->CDRS->RatingTables, 'application' => $application ); $Rate = new Rate($this->settings, $this->db); $this->runtime['instantiate_rate']=microtime_float(); if ($app_prefix == 'audio') { if ($Rate->calculateAudio($RateDictionary)) { $this->runtime['calculate_rate']=microtime_float(); $this->sessionDoesNotExist=false; $result = $this->DebitBalanceAudio($CDR->BillingPartyId,$Rate->price,$NetFields['callid'],$CDR->duration,$force); if ($this->sessionDoesNotExist) { return "Failed"; } $this->runtime['debit_balance']=microtime_float(); $log = sprintf ("DebitBalance=%s Duration=%s CallId=%s BillingParty=%s DestId=%s MaxSessionTime=%d Counter=%d->%d", $Rate->price, $CDR->duration, $NetFields['callid'], $CDR->BillingPartyId, $CDR->DestinationId, $result, $this->old_session_count, $this->new_session_count ); syslog(LOG_NOTICE, $log); $RateReturn = "Ok"; $RateReturn.= sprintf("\nMaxSessionTime=%d",$result); if (strlen($Rate->price)) { $RateReturn.="\n".$Rate->price; if ($Rate->rateInfo) { $RateReturn.="\n".trim($Rate->rateInfo); } } return $RateReturn; } else { syslog(LOG_NOTICE, 'Failed to calculate rate in DebitBalance()'); return "Failed\n"; } } else if ($app_prefix == 'sms') { // return Ok, No credit, Error if ($Rate->calculateMessage($RateDictionary)) { if ($this->DebitBalanceMessage($CDR->BillingPartyId,$CDR->destinationPrint,$Rate->price,$NetFields['callid'])) { $log = sprintf ("Price=%s CallId=%s BillingParty=%s DestId=%s Application=%s", $Rate->price, $NetFields['callid'], $CDR->BillingPartyId, $CDR->DestinationId, $application ); syslog(LOG_NOTICE, $log); $RateReturn = "Ok"; if (strlen($Rate->price)) { $RateReturn.="\n".$Rate->price; if ($Rate->rateInfo) { $RateReturn.="\n".trim($Rate->rateInfo); } } return $RateReturn; } else { return "Failed"; } } else { return "Failed"; } } else { return false; } } else if ($NetFields['action'] == "addbalance") { if (!$NetFields['from']) { $log=sprintf ("Error: Missing From parameter"); syslog(LOG_NOTICE, $log); return 0; } if (!is_numeric($NetFields['value'])) { $log=sprintf ("Error: Missing Value parameter, it must be numeric"); syslog(LOG_NOTICE, $log); return 0; } return $this->CreditBalance($NetFields['from'],$NetFields['value']); } else if ($NetFields['action'] == "deletebalance") { if (!$NetFields['from']) { $log=sprintf ("Error: Missing From parameter"); syslog(LOG_NOTICE, $log); return 0; } return $this->DeleteBalance($NetFields['from']); } else if ($NetFields['action'] == "deletebalancehistory") { if (!$NetFields['from']) { $log=sprintf ("Error: Missing From parameter"); syslog(LOG_NOTICE, $log); return 0; } return $this->DeleteBalanceHistory($NetFields['from']); } else if ($NetFields['action'] == "showprice") { if (!$NetFields['from']) { $log=sprintf ("Error: Missing From parameter"); syslog(LOG_NOTICE, $log); return 0; } if (!$NetFields['to']) { $log=sprintf ("Error: Missing To parameter"); syslog(LOG_NOTICE, $log); return 0; } if (!strlen($NetFields['duration'])) { $log=sprintf ("Error: Missing Duration parameter"); syslog(LOG_NOTICE, $log); return 0; } if ($NetFields['timestamp']) { $timestamp=$NetFields['timestamp']; } else { $timestamp=time(); } if (!$NetFields['gateway']) { $log=sprintf ("error: missing gateway parameter"); syslog(LOG_NOTICE, $log); return $log; } $app_prefix = preg_replace('/[.].*$/', '', $NetFields['application']); if (strlen($app_prefix)) { if ($app_prefix == 'audio' || $app_prefix == 'sms' ) { $application=$NetFields['application']; } else { $log=sprintf ("error: unsupported application %s",$NetFields['application']); syslog(LOG_NOTICE, $log); return $log; } } else { $application='audio'; } list($username_t,$domain_t)=explode("@",$NetFields['from']); $CDRStructure=array ( $this->CDRS->CDRFields['callId'] => $NetFields['callid'], $this->CDRS->CDRFields['aNumber'] => $NetFields['from'], $this->CDRS->CDRFields['CanonicalURI'] => $NetFields['to'], $this->CDRS->CDRFields['gateway'] => $NetFields['gateway'], $this->CDRS->CDRFields['ENUMtld'] => $NetFields['enumtld'], $this->CDRS->CDRFields['duration'] => floor($NetFields['duration']), $this->CDRS->CDRFields['timestamp'] => time(), $this->CDRS->CDRFields['domain'] => $domain_t, $this->CDRS->CDRFields['application'] => $application, 'skip_fix_prepaid_duration' => true ); $CDR = new $this->CDRS->CDR_class($this->CDRS, $CDRStructure); $CDR->normalize(); $Rate = new Rate($this->settings, $this->db); $RateDictionary=array( 'callId' => $CDR->callId, 'timestamp' => $CDR->timestamp, 'duration' => $CDR->duration, 'DestinationId' => $CDR->DestinationId, 'region' => $CDR->region, 'domain' => $CDR->domain, 'gateway' => $CDR->gateway, 'BillingPartyId' => $CDR->BillingPartyId, 'ENUMtld' => $CDR->ENUMtld, 'RatingTables' => $this->CDRS->RatingTables, 'application' => $application ); $Rate->calculateAudio($RateDictionary); $this->runtime['calculate_rate']=microtime_float(); if (strlen($Rate->price)) { $RateReturn=$Rate->price; if ($Rate->rateInfo) { $RateReturn.="\n".trim($Rate->rateInfo); } } else { $RateReturn="0"; } return $RateReturn; } else if ($NetFields['action'] == "getbalance") { if (!$NetFields['from']) { $log=sprintf ("Error: Missing From parameter"); syslog(LOG_NOTICE, $log); return 0; } $query=sprintf("select * from %s where account = '%s'", addslashes($this->prepaid_table), addslashes($NetFields['from']) ); if (!$this->db->query($query)) { $log=sprintf ("Database error for %s: %s (%s)",$query,$this->db->Error,$this->db->Errno); syslog(LOG_NOTICE,$log); $this->logRuntime(); return 0; } if ($this->db->num_rows()) { $this->db->next_record(); return number_format($this->db->f('balance'),4,".",""); } else { return sprintf("%0.4f",0); } } else if ($NetFields['action'] == "getbalancehistory") { if (!$NetFields['from']) { $log=sprintf ("Error: Missing From parameter"); syslog(LOG_NOTICE, $log); return 0; } $history=$this->getBalanceHistory($NetFields['from']); return trim($history); } else if ($NetFields['action'] == "getentityprofiles") { if (!$NetFields['entity']) { $log=sprintf ("Error: Missing Entity parameter"); syslog(LOG_NOTICE, $log); return 0; } $entity=$this->GetEntityProfiles($NetFields['entity']); return trim($entity); } else if ($NetFields['action'] == "showprofiles") { return trim($this->CDRS->RatingTables->showProfiles()); } else if ($NetFields['action'] == "showenumtlds") { return trim($this->CDRS->RatingTables->showENUMtlds()); } else if ($NetFields['action'] == "version") { $version_file=$this->CDRS->CDRTool['Path']."/version"; $version="CDRTool version ".trim(file_get_contents($version_file)); return $version; } else if ($NetFields['action'] == "help") { return $this->showHelp(); } else if ($NetFields['action'] == "reloadratingtables") { return $this->reloadRatingTables(); } else if ($NetFields['action'] == "keepalive") { return $this->keepAlive(); } else if ($NetFields['action'] == "reloadquota") { if (!$NetFields['account']) { $log=sprintf ("Error: Missing Account parameter"); syslog(LOG_NOTICE, $log); return 0; } return $this->reloadQuota($NetFields['account']); } else if ($NetFields['action'] == "reloaddomains") { return $this->CDRS->LoadDomains(); } else if ($NetFields['action'] == "reloadcustomers") { if ($NetFields['customer'] && $NetFields['type']) { $_customerFilter=array('customer'=>$NetFields['customer'], 'type'=>$NetFields['type']); } return $this->reloadCustomers($_customerFilter); } else { $log=sprintf ("Error: Invalid request"); syslog(LOG_NOTICE, $log); return 0; } }