Browse code

Added support for max-time update of monitored calls

- updated example config file
- updated documentation

Carlos Ruiz Diaz authored on 22/08/2013 15:16:31
Showing 4 changed files
... ...
@@ -1,11 +1,10 @@
1
-
2 1
 cnxcc Module
3 2
 
4 3
 Carlos Ruiz Diaz
5 4
 
6
-   ConexionGroup SA
5
+   ConexionGroup S.A.
7 6
 
8
-   Copyright © 2012 Carlos Ruiz Diaz, carlos.ruizdiaz@gmail.com
7
+   Copyright © 2013 Carlos Ruiz Diaz, carlos.ruizdiaz@gmail.com
9 8
      __________________________________________________________________
10 9
 
11 10
    Table of Contents
... ...
@@ -26,6 +25,9 @@ Carlos Ruiz Diaz
26 26
 
27 27
               4.1. cnxcc_set_max_credit()
28 28
               4.2. cnxcc_set_max_time()
29
+              4.3. cnxcc_update_max_time()
30
+              4.4. cnxcc_set_max_channel()
31
+              4.5. cnxcc_terminate_all()
29 32
 
30 33
         5. Exported RPC Commands
31 34
 
... ...
@@ -43,7 +45,10 @@ Carlos Ruiz Diaz
43 43
    1.2. credit_check_period
44 44
    1.3. cnxcc_set_max_credit()
45 45
    1.4. cnxcc_set_max_time()
46
-   1.5. kamailio-cnxcc.cfg
46
+   1.5. cnxcc_update_max_time()
47
+   1.6. cnxcc_set_max_channels()
48
+   1.7. cnxcc_set_max_time()
49
+   1.8. kamailio-cnxcc.cfg
47 50
 
48 51
 Chapter 1. Admin Guide
49 52
 
... ...
@@ -63,6 +68,9 @@ Chapter 1. Admin Guide
63 63
 
64 64
         4.1. cnxcc_set_max_credit()
65 65
         4.2. cnxcc_set_max_time()
66
+        4.3. cnxcc_update_max_time()
67
+        4.4. cnxcc_set_max_channel()
68
+        4.5. cnxcc_terminate_all()
66 69
 
67 70
    5. Exported RPC Commands
68 71
 
... ...
@@ -100,6 +108,9 @@ Chapter 1. Admin Guide
100 100
    If your accounting program does not maintain the state of the call in
101 101
    real time, this module can provide you that ability.
102 102
 
103
+   Cnxcc can also provide more common means of monitoring, i.e., by time
104
+   limit or by maximum simultaneous calls.
105
+
103 106
 2. Dependencies
104 107
 
105 108
    2.1. Modules
... ...
@@ -142,6 +153,9 @@ modparam("cnxcc", "credit_check_period", 1)
142 142
 
143 143
    4.1. cnxcc_set_max_credit()
144 144
    4.2. cnxcc_set_max_time()
145
+   4.3. cnxcc_update_max_time()
146
+   4.4. cnxcc_set_max_channel()
147
+   4.5. cnxcc_terminate_all()
145 148
 
146 149
 4.1.  cnxcc_set_max_credit()
147 150
 
... ...
@@ -152,6 +166,7 @@ modparam("cnxcc", "credit_check_period", 1)
152 152
    Return code:
153 153
      * 1 - successful
154 154
      * -1 - failed, error logged
155
+     * -2 - failed, credit value is less than initial pulse value
155 156
 
156 157
    Example 1.3. cnxcc_set_max_credit()
157 158
 ...
... ...
@@ -178,7 +193,84 @@ l_p)", "$var(final_p)");
178 178
 $var(customer) = "john-doe-123-basic";
179 179
 $var(max_time) = 120;
180 180
 
181
-cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
181
+cnxcc_set_max_time("$var(customer)", "$var(max_time)");
182
+...
183
+
184
+4.3.  cnxcc_update_max_time()
185
+
186
+   Updates max-time of an established and monitored call. This can be used
187
+   to grant minimum values and to update them every short periods on time
188
+   as a mean to prevent frauds and/or to mimic requested/granted units of
189
+   time of Credit Control Application behavior.
190
+
191
+   Return code:
192
+     * 1 - successful
193
+     * -1 - failed, error logged
194
+
195
+   Example 1.5. cnxcc_update_max_time()
196
+...
197
+        $var(update_time)  = 5;
198
+        $var(client)       = "john-doe-123-basic";
199
+
200
+        if (!cnxcc_update_max_time("$var(client)",
201
+                                  "$var(update_time)")) {
202
+                xlog("Error updating max-time");
203
+                return;
204
+        }
205
+
206
+...
207
+
208
+4.4.  cnxcc_set_max_channel()
209
+
210
+   Specifies a limit for the number of simultaneous calls
211
+
212
+   Return code:
213
+     * 1 - successful
214
+     * -1 - failed, error logged
215
+     * -2 - failed, calls established plus calls being established result
216
+       in more than the limit you specified
217
+     * -3 - failed, number of calls established is more than the limit you
218
+       specified
219
+
220
+   Example 1.6. cnxcc_set_max_channels()
221
+...
222
+$var(customer)  = "john-doe-123-basic";
223
+$var(max_chan)  = 2;
224
+$var(retcode)   = cnxcc_set_max_channels("$var(customer)", "$var(max_chan)");
225
+
226
+if ($var(retcode) == -1) {
227
+        xlog("Error setting up credit control");
228
+        return;
229
+}
230
+
231
+if ($var(retcode) < -1) {
232
+        xlog("Too many channels for customer");
233
+        sl_send_reply(403, "Forbidden");
234
+
235
+        if (!cnxcc_terminate_all("$var(customer)")) {
236
+                xlog("Error terminating customer's calls");
237
+        }
238
+
239
+        exit;
240
+}
241
+
242
+...
243
+
244
+4.5.  cnxcc_terminate_all()
245
+
246
+   Terminates all calls of the specified customer/profile
247
+
248
+   Return code:
249
+     * 1 - successful
250
+     * -1 - failed, error logged
251
+
252
+   Example 1.7. cnxcc_set_max_time()
253
+...
254
+$var(customer)  = "john-doe-123-basic";
255
+
256
+if (!cnxcc_terminate_all("$var(customer)")) {
257
+        xlog("Error terminating customer's calls");
258
+}
182 259
 ...
183 260
 
184 261
 5. Exported RPC Commands
... ...
@@ -194,7 +286,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
194 194
    Parameters: none
195 195
 
196 196
    Example:
197
-            sercmd cnxcc.active_clients
197
+            kamcmd cnxcc.active_clients
198 198
 
199 199
 5.2. cnxcc.check_client
200 200
 
... ...
@@ -203,7 +295,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
203 203
    Parameters: client/customer identifier
204 204
 
205 205
    Example:
206
-            sercmd cnxcc.check_client john-doe-123-premium
206
+            kamcmd cnxcc.check_client john-doe-123-premium
207 207
 
208 208
 5.3. cnxcc.kill_call
209 209
 
... ...
@@ -212,7 +304,7 @@ cnxcc_set_max_tim ("$var(customer)", "$var(max_time)");
212 212
    Parameters: Call-ID
213 213
 
214 214
    Example:
215
-            sercmd cnxcc.kill_call qumojlaahitafih@carlosrdcnx-laptop.site
215
+            kamcmd cnxcc.kill_call qumojlaahitafih@carlosrdcnx-laptop.site
216 216
 
217 217
 6. Events
218 218
 
... ...
@@ -242,7 +334,7 @@ event_route[cnxcc:call-shutdown]
242 242
 
243 243
 8. Sample
244 244
 
245
-   Example 1.5. kamailio-cnxcc.cfg
245
+   Example 1.8. kamailio-cnxcc.cfg
246 246
 ...
247 247
 route[CNXCC]
248 248
 {
... ...
@@ -104,6 +104,7 @@ static int pv_get_calls(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
104 104
  * Billing management functions
105 105
  */
106 106
 static int set_max_time(struct sip_msg* msg, char* number, char* str2);
107
+static int update_max_time(struct sip_msg* msg, char* number, char* str2);
107 108
 static int set_max_credit(struct sip_msg* msg, char *str_pv_client, char *str_pv_credit, char *str_pv_cps, char *str_pv_inip, char *str_pv_finp);
108 109
 static int set_max_channels(struct sip_msg* msg, char* str_pv_client, char* str_pv_max_chan);
109 110
 static int get_channel_count(struct sip_msg* msg, char* str_pv_client, char* str_pv_max_chan);
... ...
@@ -142,6 +143,7 @@ static pv_export_t mod_pvs[] =
142 142
 static cmd_export_t cmds[] =
143 143
 {
144 144
 	{"cnxcc_set_max_time",   (cmd_function) set_max_time, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, ANY_ROUTE},
145
+	{"cnxcc_update_max_time",   (cmd_function) update_max_time, 2, fixup_pvar_pvar, fixup_free_pvar_pvar, ANY_ROUTE},
145 146
 	{"cnxcc_set_max_credit",   (cmd_function) set_max_credit, 5, fixup_par, NULL, ANY_ROUTE},
146 147
 	{"cnxcc_set_max_channels",   (cmd_function) set_max_channels, 2, fixup_pvar_pvar, NULL, ANY_ROUTE},
147 148
 	{"cnxcc_get_channel_count",   (cmd_function) get_channel_count, 2, fixup_pvar_pvar, NULL, ANY_ROUTE},
... ...
@@ -1755,6 +1757,97 @@ static int set_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv_m
1755 1755
 	return 1;
1756 1756
 }
1757 1757
 
1758
+static int update_max_time(struct sip_msg* msg, char* str_pv_client, char* str_pv_secs)
1759
+{
1760
+	credit_data_t *credit_data 	= NULL;
1761
+	pv_spec_t *secs_spec		= (pv_spec_t *) str_pv_secs,
1762
+		  *client_id_spec	= (pv_spec_t *) str_pv_client;
1763
+	pv_value_t secs_val, client_id_val;
1764
+	int secs				= 0;
1765
+
1766
+	set_ctrl_flag(msg);
1767
+
1768
+	if (parse_headers(msg, HDR_CALLID_F, 0) != 0)
1769
+	{
1770
+		LM_ERR("Error parsing Call-ID");
1771
+		return -1;
1772
+	}
1773
+
1774
+	if (pv_get_spec_value(msg, secs_spec, &secs_val) != 0)
1775
+	{
1776
+		LM_ERR("Can't get secs PV value\n");
1777
+		return -1;
1778
+	}
1779
+	secs	= secs_val.ri;
1780
+
1781
+	if (secs <= 0)
1782
+	{
1783
+		LM_ERR("[%.*s] MAXSECS cannot be less than or equal to zero: %d\n", msg->callid->body.len, msg->callid->body.s, secs);
1784
+		return -1;
1785
+	}
1786
+
1787
+	if (pv_get_spec_value(msg, client_id_spec, &client_id_val) != 0)
1788
+	{
1789
+		LM_ERR("[%.*s]: can't get client_id PV value\n", msg->callid->body.len, msg->callid->body.s);
1790
+		return -1;
1791
+	}
1792
+
1793
+	if (client_id_val.rs.len == 0 || client_id_val.rs.s == NULL)
1794
+	{
1795
+		LM_ERR("[%.*s]: client ID cannot be null\n", msg->callid->body.len, msg->callid->body.s);
1796
+		return -1;
1797
+	}
1798
+
1799
+	LM_DBG("Updating call for client [%.*s], max-secs[%d], call-id[%.*s]\n", client_id_val.rs.len, client_id_val.rs.s,
1800
+													secs,
1801
+													msg->callid->body.len, msg->callid->body.s);
1802
+
1803
+
1804
+
1805
+	struct str_hash_table *ht	= NULL;
1806
+	struct str_hash_entry *e	= NULL;
1807
+	ht				= _data.time.credit_data_by_client;
1808
+	double update_fraction		= secs;
1809
+	call_t *call			= NULL,
1810
+	       *tmp_call		= NULL;
1811
+
1812
+	lock_get(&_data.time.lock);
1813
+	e							= str_hash_get(ht, client_id_val.rs.s, client_id_val.rs.len);
1814
+	lock_release(&_data.time.lock);
1815
+
1816
+	if (e == NULL)
1817
+	{
1818
+		LM_ERR("Client [%.*s] was not found\n", e->key.len, e->key.s);
1819
+		return -1;
1820
+	}
1821
+		
1822
+	credit_data					= (credit_data_t *) e->u.p;
1823
+
1824
+	lock_get(&credit_data->lock);
1825
+
1826
+	LM_DBG("Updating max-secs for [%.*s] from [%f] to [%f]\n", e->key.len, e->key.s, credit_data->max_amount, credit_data->max_amount + secs);
1827
+	
1828
+	credit_data->max_amount				+= secs;
1829
+
1830
+	if (credit_data->number_of_calls > 0)
1831
+		update_fraction	= secs / credit_data->number_of_calls;
1832
+
1833
+	clist_foreach_safe(credit_data->call_list, call, tmp_call, next)
1834
+	{
1835
+		if (!call->confirmed)
1836
+			continue;
1837
+		
1838
+		call->max_amount	+= update_fraction;
1839
+	}
1840
+
1841
+//redit_data->consumed_amount			= 0;
1842
+
1843
+
1844
+	lock_release(&credit_data->lock);
1845
+
1846
+	return 1;
1847
+}
1848
+
1758 1849
 static int has_to_tag(struct sip_msg *msg)
1759 1850
 {
1760 1851
 	if (msg->to == NULL && parse_headers(msg, HDR_TO_F, 0) != 0)
... ...
@@ -186,6 +186,49 @@ cnxcc_set_max_time("$var(customer)", "$var(max_time)");
186 186
             </example>
187 187
         </section>
188 188
 
189
+        <section>
190
+            <title>
191
+                <function moreinfo="none">cnxcc_update_max_time()</function>
192
+            </title>
193
+            <para>
194
+		Updates max-time of an established and monitored call. This can be used to grant minimum values and to update them every short periods on time as a mean to prevent frauds and/or to mimic requested/granted units of time of Credit Control Application behavior.
195
+            </para>
196
+            <para>
197
+                <emphasis>Return code:</emphasis>
198
+                <itemizedlist>
199
+                    <listitem>
200
+                    <para>
201
+                        <emphasis>1 - successful</emphasis>
202
+                    </para>
203
+                    </listitem>
204
+                     
205
+                    <listitem>
206
+                    <para>
207
+                        <emphasis>-1 - failed, error logged</emphasis>
208
+                    </para>
209
+                    </listitem>
210
+                </itemizedlist>
211
+            </para>
212
+            <example>
213
+		<title>cnxcc_update_max_time()</title>
214
+                <programlisting format="linespecific">
215
+...
216
+        $var(update_time)  = 5;
217
+        $var(client)       = "john-doe-123-basic";
218
+
219
+        if (!cnxcc_update_max_time("$var(client)",
220
+                                  "$var(update_time)")) {
221
+                xlog("Error updating max-time");
222
+                return;
223
+        }
224
+
225
+...
226
+		</programlisting>
227
+            </example>
228
+        </section>
229
+
230
+
231
+
189 232
     	<section>
190 233
             <title>
191 234
                 <function moreinfo="none">cnxcc_set_max_channel()</function>
... ...
@@ -223,7 +266,7 @@ cnxcc_set_max_time("$var(customer)", "$var(max_time)");
223 223
                 </itemizedlist>
224 224
             </para>
225 225
             <example>
226
-		<title>cnxcc_set_max_time()</title>
226
+		<title>cnxcc_set_max_channels()</title>
227 227
                 <programlisting format="linespecific">
228 228
 ...
229 229
 $var(customer)  = "john-doe-123-basic";
... ...
@@ -1,8 +1,8 @@
1 1
 #!KAMAILIO
2 2
 
3
-##!define CNXCC_TIME
3
+#!define CNXCC_TIME
4 4
 ##!define CNXCC_MONEY
5
-#!define CNXCC_CHANNEL
5
+##!define CNXCC_CHANNEL
6 6
 
7 7
 #
8 8
 # Kamailio (OpenSER) SIP Server v3.2 - default configuration script
... ...
@@ -455,12 +455,18 @@ modparam("dialog", "default_timeout", 3600)
455 455
 modparam("dialog", "db_mode", 0)
456 456
 modparam("dialog", "dlg_flag", DLG_FLAG)
457 457
 
458
-#!ifdef CNXCC_CHANNEL
458
+
459 459
 loadmodule "rtimer.so";
460
+#!ifdef CNXCC_CHANNEL
460 461
 modparam("rtimer", "timer", "name=ta;interval=1;mode=1;")
461 462
 modparam("rtimer", "exec", "timer=ta;route=SHOW_CHANNEL_COUNT")
462 463
 #!endif
463 464
 
465
+#!ifdef CNXCC_TIME
466
+modparam("rtimer", "timer", "name=ta;interval=5;mode=1;")
467
+modparam("rtimer", "exec", "timer=ta;route=UPDATE_MAX_TIME")
468
+#!endif
469
+
464 470
 loadmodule "cnxcc.so"
465 471
 modparam("cnxcc", "dlg_flag", CC_FLAG)
466 472
 modparam("cnxcc", "credit_check_period", 1) #check every 1 second
... ...
@@ -609,7 +615,7 @@ route[CNXCC]
609 609
 #!ifdef CNXCC_TIME
610 610
 	xlog("L_INFO", "Setting up time based credit control");
611 611
 	
612
-	$var(max_time)	= 10;
612
+	$var(max_time)	= 5;
613 613
 	
614 614
 	if (!cnxcc_set_max_time("$var(client)",
615 615
                                   "$var(max_time)")) {
... ...
@@ -635,6 +641,30 @@ route[SHOW_CHANNEL_COUNT]
635 635
 }
636 636
 #!endif
637 637
 
638
+#!ifdef CNXCC_TIME
639
+route[UPDATE_MAX_TIME]
640
+{
641
+	if ($DLG_count == 0) // no active dialog? no time to be updated 
642
+		return;	
643
+	
644
+	if ($var(granted_units) == 4) // after 25 seconds, we will stop updating the granted time
645
+		return;
646
+
647
+	$var(granted_units) = $var(granted_units) + 1;
648
+	xlog("L_INFO", "Updating max-time. Granted units $var(granted_units)/4");
649
+
650
+        $var(update_time)  = 5;
651
+	$var(client)	   = "customer1";
652
+
653
+        if (!cnxcc_update_max_time("$var(client)",
654
+                                  "$var(update_time)")) {
655
+                xlog("Error updating max-time");
656
+                return;
657
+        }
658
+
659
+}
660
+#!endif
661
+
638 662
 route[RELAY] {
639 663
 
640 664
 	# enable additional event routes for forwarded requests