Skip to content

Instantly share code, notes, and snippets.

@leedm777
Last active January 4, 2016 06:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leedm777/8585690 to your computer and use it in GitHub Desktop.
Save leedm777/8585690 to your computer and use it in GitHub Desktop.
Patch adding application subtypes for CDRTool
Wed Feb 12 12:33:04 CST 2014 David M. Lee <dlee@digium.com>
* application-suptypes
This patch adds the concept of 'subtypes' for applications.
When a CDR is recorded, it's Sip-Application-Type may contain a subtype
(for example, audio.incoming).
When the rating engine looks for a matching billing rate, it will match
on the full application.subtype. This allows billing rates to be more
specific, for example recording different rates for incoming traffic
versus outgoing.
diff -rN -u old-cdrtool/doc/RATING.txt new-cdrtool/doc/RATING.txt
--- old-cdrtool/doc/RATING.txt 2014-02-12 12:33:13.000000000 -0600
+++ new-cdrtool/doc/RATING.txt 2014-02-12 12:33:13.000000000 -0600
@@ -216,6 +216,14 @@
possible destination has a 'corresponding id' and name in the destinations
table.
+ The 'audio' application may optionally be specified with a subtype in order
+ to refine billing rates. If a subtype is specified, it is appended to the
+ application name, separated by a dot (i.e. 'audio.incoming').
+
+ For example, ('1', 'audio') can have a durationRate of 280, where
+ ('1', 'audio.incoming') can have a durationRate of 0. If the application
+ isn't specified in the CDR, it defaults to 'audio'.
+
This step determines the costs within the current time span associated
with the time of day and destination id. If the call duration exceeds
this time span (that is a new interval for which another rate applies is
diff -rN -u old-cdrtool/library/cdr_generic.php new-cdrtool/library/cdr_generic.php
--- old-cdrtool/library/cdr_generic.php 2014-02-12 12:33:13.000000000 -0600
+++ new-cdrtool/library/cdr_generic.php 2014-02-12 12:33:13.000000000 -0600
@@ -2240,7 +2240,8 @@
'RatingTables' => $this->CDRS->RatingTables,
'aNumber' => $this->aNumber,
'cNumber' => $this->cNumber,
- 'ENUMtld' => $this->ENUMtld
+ 'ENUMtld' => $this->ENUMtld,
+ 'application' => $this->application
);
diff -rN -u old-cdrtool/library/cdr_opensips.php new-cdrtool/library/cdr_opensips.php
--- old-cdrtool/library/cdr_opensips.php 2014-02-12 12:33:13.000000000 -0600
+++ new-cdrtool/library/cdr_opensips.php 2014-02-12 12:33:13.000000000 -0600
@@ -2497,11 +2497,10 @@
$this->UserAgentPrint = quoted_printable_decode($this->UserAgent);
- if (strstr($this->application,'audio')) {
- $this->application='audio';
- }
-
- if (!in_array($this->application,$this->supportedApplicationTypes)) {
+ $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;
}
diff -rN -u old-cdrtool/library/rating.php new-cdrtool/library/rating.php
--- old-cdrtool/library/rating.php 2014-02-12 12:33:13.000000000 -0600
+++ new-cdrtool/library/rating.php 2014-02-12 12:33:13.000000000 -0600
@@ -136,7 +136,10 @@
$this->traffic = 0;
}
- $this->application='audio';
+ $this->application=$dictionary['application'];
+ if (!$this->application) {
+ $this->application = 'audio';
+ }
$durationRate = 0;
@@ -1490,14 +1493,14 @@
function lookupRateValuesAudio($rateName,$DestinationId) {
- if (is_array($this->rateValuesCache[$rateName][$DestinationId]['audio'])) {
- return $this->rateValuesCache[$rateName][$DestinationId]['audio'];
+ if (is_array($this->rateValuesCache[$rateName][$DestinationId][$this->application])) {
+ return $this->rateValuesCache[$rateName][$DestinationId][$this->application];
}
if ($this->mongo_db != NULL) {
// mongo backend
$mongo_where['destination'] = $DestinationId;
- $mongo_where['application'] = 'audio';
+ $mongo_where['application'] = $this->application;
$mongo_where['$or'] = array(array('reseller_id' => intval($this->ResellerId)),
array('reseller_id' => 0)
);
@@ -1527,7 +1530,7 @@
);
// cache values
- $this->rateValuesCache[$rateName][$DestinationId]['audio']=$values;
+ $this->rateValuesCache[$rateName][$DestinationId][$this->application]=$values;
return $values;
}
}
@@ -1538,17 +1541,19 @@
} else {
$table="billing_rates_default";
}
- $query=sprintf("select * from %s where destination = '%s' and application = 'audio'",
+ $query=sprintf("select * from %s where destination = '%s' and application = '%s'",
$table,
- addslashes($DestinationId)
+ addslashes($DestinationId),
+ addslashes($this->application)
);
} else {
$table="billing_rates";
- $query=sprintf("select * from %s where name = '%s' and destination = '%s' and application = 'audio'",
+ $query=sprintf("select * from %s where name = '%s' and destination = '%s' and application = '%s'",
$table,
addslashes($rateName),
- addslashes($DestinationId)
+ addslashes($DestinationId),
+ addslashes($this->application)
);
}
@@ -1560,9 +1565,10 @@
return false;
}
// try the main table
- $query=sprintf("select * from billing_rates where name = '%s' and destination = '%s' and application = 'audio'",
+ $query=sprintf("select * from billing_rates where name = '%s' and destination = '%s' and application = '%s'",
addslashes($rateName),
- addslashes($DestinationId)
+ addslashes($DestinationId),
+ addslashes($this->application)
);
if (!$this->db->query($query)) {
@@ -1582,7 +1588,7 @@
);
// cache values
- $this->rateValuesCache[$rateName][$DestinationId]['audio']=$values;
+ $this->rateValuesCache[$rateName][$DestinationId][$this->application]=$values;
return $values;
} else {
return false;
@@ -8466,6 +8472,19 @@
$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 (
@@ -8476,6 +8495,7 @@
$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
);
@@ -8603,7 +8623,8 @@
'gateway' => $CDR->gateway,
'BillingPartyId' => $CDR->BillingPartyId,
'ENUMtld' => $CDR->ENUMtld,
- 'RatingTables' => $this->CDRS->RatingTables
+ 'RatingTables' => $this->CDRS->RatingTables,
+ 'application' => $application
);
$Rate = new Rate($this->settings, $this->db);
@@ -8643,7 +8664,8 @@
'gateway' => $CDR->gateway,
'BillingPartyId' => $CDR->BillingPartyId,
'ENUMtld' => $CDR->ENUMtld,
- 'RatingTables' => $this->CDRS->RatingTables
+ 'RatingTables' => $this->CDRS->RatingTables,
+ 'application' => $application
);
$Rate = new Rate($this->settings, $this->db);
@@ -8782,7 +8804,8 @@
return $log;
}
- if (!strlen($NetFields['application']) || (strlen($NetFields['application']) && $NetFields['application'] == 'audio')) {
+ $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);
@@ -8790,8 +8813,8 @@
}
}
- if (strlen($NetFields['application'])) {
- if ($NetFields['application'] == 'audio' || $NetFields['application'] == 'sms' ) {
+ if (strlen($app_prefix)) {
+ if ($app_prefix == 'audio' || $app_prefix == 'sms' ) {
$application=$NetFields['application'];
} else {
$log=sprintf ("error: unsupported application %s",$NetFields['application']);
@@ -8800,6 +8823,7 @@
}
} else {
$application='audio';
+ $app_prefix='audio';
}
if (!$NetFields['gateway']) {
@@ -8833,6 +8857,7 @@
$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
);
@@ -8854,7 +8879,8 @@
'gateway' => $CDR->gateway,
'BillingPartyId' => $CDR->BillingPartyId,
'ENUMtld' => $CDR->ENUMtld,
- 'RatingTables' => $this->CDRS->RatingTables
+ 'RatingTables' => $this->CDRS->RatingTables,
+ 'application' => $application
);
@@ -8862,7 +8888,7 @@
$this->runtime['instantiate_rate']=microtime_float();
- if ($application == 'audio') {
+ if ($app_prefix == 'audio') {
if ($Rate->calculateAudio($RateDictionary)) {
$this->runtime['calculate_rate']=microtime_float();
@@ -8905,17 +8931,18 @@
syslog(LOG_NOTICE, 'Failed to calculate rate in DebitBalance()');
return "Failed\n";
}
- } else if ($application == 'sms') {
+ } 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=sms",
+ $log = sprintf ("Price=%s CallId=%s BillingParty=%s DestId=%s Application=%s",
$Rate->price,
$NetFields['callid'],
$CDR->BillingPartyId,
- $CDR->DestinationId
+ $CDR->DestinationId,
+ $application
);
syslog(LOG_NOTICE, $log);
@@ -9011,6 +9038,19 @@
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 (
@@ -9022,6 +9062,7 @@
$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
);
@@ -9040,7 +9081,8 @@
'gateway' => $CDR->gateway,
'BillingPartyId' => $CDR->BillingPartyId,
'ENUMtld' => $CDR->ENUMtld,
- 'RatingTables' => $this->CDRS->RatingTables
+ 'RatingTables' => $this->CDRS->RatingTables,
+ 'application' => $application
);
$Rate->calculateAudio($RateDictionary);
diff -rN -u old-cdrtool/setup/radius/OpenSIPS/dictionary.opensips new-cdrtool/setup/radius/OpenSIPS/dictionary.opensips
--- old-cdrtool/setup/radius/OpenSIPS/dictionary.opensips 2014-02-12 12:33:13.000000000 -0600
+++ new-cdrtool/setup/radius/OpenSIPS/dictionary.opensips 2014-02-12 12:33:13.000000000 -0600
@@ -93,3 +93,4 @@
#ATTRIBUTE Event-Timestamp 230 string
ATTRIBUTE SIP-Proxy-IP 231 string
ATTRIBUTE ENUM-TLD 232 string
+ATTRIBUTE Sip-Application-Type 233 string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment