1Call Control Module 2 3Dan Pascu 4 5 <dan@ag-projects.com> 6 7Edited by 8 9Dan Pascu 10 11 <dan@ag-projects.com> 12 13 Copyright © 2005-2008 Dan Pascu 14 __________________________________________________________________ 15 16 Table of Contents 17 18 1. Admin Guide 19 20 1. Overview 21 2. Description 22 3. Features 23 4. Dependencies 24 25 4.1. Kamailio Modules 26 4.2. External Libraries or Applications 27 28 5. Exported parameters 29 30 5.1. disable (int) 31 5.2. socket_name (string) 32 5.3. socket_timeout (int) 33 5.4. signaling_ip_avp (string) 34 5.5. canonical_uri_avp (string) 35 5.6. diverter_avp_id (string) 36 37 6. Functions 38 39 6.1. call_control() 40 41 List of Examples 42 43 1.1. Setting the disable parameter 44 1.2. Setting the socket_name parameter 45 1.3. Setting the socket_timeout parameter 46 1.4. Setting the signaling_ip_avp parameter 47 1.5. Setting the canonical_uri_avp parameter 48 1.6. Setting the diverter_avp_id parameter 49 1.7. Using the call_control function 50 51Chapter 1. Admin Guide 52 53 Table of Contents 54 55 1. Overview 56 2. Description 57 3. Features 58 4. Dependencies 59 60 4.1. Kamailio Modules 61 4.2. External Libraries or Applications 62 63 5. Exported parameters 64 65 5.1. disable (int) 66 5.2. socket_name (string) 67 5.3. socket_timeout (int) 68 5.4. signaling_ip_avp (string) 69 5.5. canonical_uri_avp (string) 70 5.6. diverter_avp_id (string) 71 72 6. Functions 73 74 6.1. call_control() 75 761. Overview 77 78 This module allows one to limit the duration of calls and automatically 79 end them when they exceed the imposed limit. Its main use case is to 80 implement a prepaid system, but it can also be used to impose a global 81 limit on all calls processed by the proxy. 82 832. Description 84 85 Callcontrol consists of 3 components: 86 * The Kamailio call_control module 87 * An external application called callcontrol which keeps track of the 88 calls that have a time limit and automatically ends them when they 89 exceed it. This application receives requests from Kamailio and 90 makes requests to a rating engine (see below) to find out if a call 91 needs to be limited or not. When a call ends (or is ended) it will 92 also instruct the rating engine to debit the balance for the caller 93 with the consumed amount. The callcontrol application is available 94 from http://callcontrol.ag-projects.com/ 95 * NOTE: At the moment the callcontrol application only supports the 96 old “MI” interface for communication with Kamailio. This interface 97 is unfortunately not available anymore in Kamailio. So this 98 application cannot be used right now out of the box together with 99 the call_control module. See the next link for possible solutions: 100 https://lists.kamailio.org/pipermail/sr-users/2019-June/106056.html 101 . 102 * A rating engine that is used to calculate the time limit based on 103 the caller's credit and the destination price and to debit the 104 caller's balance after a call ends. This is available as part of 105 CDRTool from http://cdrtool.ag-projects.com/ 106 107 The callcontrol application runs on the same machine as Kamailio and 108 they communicate over a filesystem socket, while the rating engine can 109 run on a different host and communicates with the callcontrol 110 application using a TCP connection. 111 112 Callcontrol is invoked by calling the call_control() function for the 113 initial INVITE of every call we want to apply a limit to. This will end 114 up as a request to the callcontrol application, which will interogate 115 the rating engine for a time limit for the given caller and 116 destination. The rating engine will determine if the destination has 117 any associated cost and if the caller has any credit limit and if so 118 will return the amount of time he is allowed to call that destination. 119 Otherwise it will indicate that there is no limit associated with the 120 call. If there is a limit, the callcontrol application will retain the 121 session and attach a timer to it that will expire after the given time 122 causing it to call back to Kamailio with a request to end the dialog. 123 If the rating engine returns that there is no limit for the call, the 124 session is discarded by the callcontrol application and it will allow 125 it to go proceed any limit. An appropriate response is returned to the 126 call_control module that is then returned by the call_control() 127 function call and allows the script to make a decision based on the 128 answer. 129 1303. Features 131 132 * Very simple API consisting of a single function that needs to be 133 called once for the first INVITE of every call. The rest is done 134 automatically in the background using dialog callbacks. 135 * Gracefully end dialogs when they exceed their time by triggering a 136 dlg_end_dlg request into the dialog module, that will generate two 137 BYE messages towards each endpoint, ending the call cleanly. 138 * Allow parallel sessions using one balance per subscriber 139 * Integrates with mediaproxy's ability to detect when a call does 140 timeout sending media and is closed. In this case the dlg_end_dlg 141 that is triggered by mediaproxy will end the callcontrol session 142 before it reaches the limit and consumes all the credit for a call 143 that died and didn't actually take place. For this mediaproxy has 144 to be used and it has to be started by engage_media_proxy() to be 145 able to keep track of the call's dialog and end it on timeout. 146 Even when mediaproxy is unable to end the dialog because it was not 147 started with engage_media_proxy(), the callcontrol application is 148 still able to detect calls that did timeout sending media, by 149 looking in the radius accounting records for entries recorded by 150 mediaproxy for calls that did timeout. These calls will also be 151 ended gracefully by the callcontrol application itself. 152 1534. Dependencies 154 155 4.1. Kamailio Modules 156 4.2. External Libraries or Applications 157 1584.1. Kamailio Modules 159 160 The following modules must be loaded before this module: 161 * pv module 162 * dialog module 163 1644.2. External Libraries or Applications 165 166 The following libraries or applications must be installed before 167 running Kamailio with this module loaded: 168 * None. 169 1705. Exported parameters 171 172 5.1. disable (int) 173 5.2. socket_name (string) 174 5.3. socket_timeout (int) 175 5.4. signaling_ip_avp (string) 176 5.5. canonical_uri_avp (string) 177 5.6. diverter_avp_id (string) 178 1795.1. disable (int) 180 181 Boolean flag that specifies if callcontrol should be disabled. This is 182 useful when you want to use the same Kamailio configuration in two 183 different contexts, one using callcontrol, the other not. In the case 184 callcontrol is disabled, calls to the call_control() function will 185 return a code indicating that there is no limit associated with the 186 call, allowing the use of the same configuration without changes. 187 188 Default value is “0”. 189 190 Example 1.1. Setting the disable parameter 191... 192modparam("call_control", "disable", 1) 193... 194 1955.2. socket_name (string) 196 197 The path to the filesystem socket where the callcontrol application 198 listens for commands from the module. 199 200 Default value is “/run/callcontrol/socket”. 201 202 Example 1.2. Setting the socket_name parameter 203... 204modparam("call_control", "socket_name", "/run/callcontrol/socket") 205... 206 2075.3. socket_timeout (int) 208 209 How long time (in milliseconds) to wait for an answer from the 210 callcontrol application. 211 212 Default value is “500” ms. 213 214 Example 1.3. Setting the socket_timeout parameter 215... 216modparam("call_control", "socket_timeout", 500) 217... 218 2195.4. signaling_ip_avp (string) 220 221 Specification of the AVP which holds the IP address from where the SIP 222 signaling originated. If this AVP is set it will be used to get the 223 signaling IP address, else the source IP address from where the SIP 224 message was received will be used. This AVP is meant to be used in 225 cases where there are more than one proxy in the call setup path and 226 the proxy that actually starts callcontrol doesn't receive the SIP 227 messages directly from the UA and it cannot determine the NAT IP 228 address from where the signaling originated. In such a case attaching a 229 SIP header at the first proxy and then copying that header's value into 230 the signaling_ip_avp on the proxy that starts callcontrol will allow it 231 to get the correct NAT IP address from where the SIP signaling 232 originated. 233 234 This is used by the rating engine which finds the rates to apply to a 235 call based on caller's SIP URI, caller's SIP domain or caller's IP 236 address (whichever yields a rate first, in this order). 237 238 Default value is “$avp(s:signaling_ip)”. 239 240 Example 1.4. Setting the signaling_ip_avp parameter 241... 242modparam("call_control", "signaling_ip_avp", "$avp(s:signaling_ip)") 243... 244 2455.5. canonical_uri_avp (string) 246 247 Specification of the AVP which holds an optional application defined 248 canonical request URI. When this is set, it will be used as the 249 destination when computing the call price, otherwise the request URI 250 will be used. This is useful when the username of the ruri needs to 251 have a different, canonical form in the rating engine computation than 252 it has in the ruri. 253 254 Default value is “$avp(s:can_uri)”. 255 256 Example 1.5. Setting the canonical_uri_avp parameter 257... 258modparam("call_control", "canonical_uri_avp", "$avp(s:can_uri)") 259... 260 2615.6. diverter_avp_id (string) 262 263 Specification of the id of an integer AVP which holds an optional 264 application defined diverter SIP URI. When this is set, it will be used 265 by the rating engine as the billing party when finding the rates to 266 apply to a given call, otherwise, the caller's URI taken from the From 267 field will be used. When set, this AVP should contain a value in the 268 form “user@domain” (no sip: prefix should be used). 269 270 This is useful when a destination diverts a call, thus becoming the new 271 caller. In this case the billing party is the diverter and this AVP 272 should be set to it, to allow the rating engine to pick the right rates 273 for the call. For example, if A calls B and B diverts all its calls 274 unconditionally to C, then the diverter AVP should the set to B's URI, 275 because B is the billing party in the call not A after the call was 276 diverted. 277 278 Default value is “805”. 279 280 Example 1.6. Setting the diverter_avp_id parameter 281... 282modparam("call_control", "diverter_avp_id", 805) 283 284route { 285 ... 286 # alice@example.com is paying for this call 287 $avp(i:805) = "sip:alice@example.com"; 288 ... 289} 290... 291 2926. Functions 293 294 6.1. call_control() 295 2966.1. call_control() 297 298 Trigger the use of callcontrol for the dialog started by the INVITE for 299 which this function is called (the function should only be called for 300 the first INVITE of a call). Further in-dialog requests will be 301 processed automatically using internal bindings into the dialog state 302 machine, allowing callcontrol to update its internal state as the 303 dialog progresses, without any other intervention from the script. 304 305 This function should be called right before the message is sent out 306 using t_relay(), when all the request uri modifications are over and a 307 final destination has been determined. 308 309 This function has the following return codes: 310 311 * +2 - call has no limit 312 * +1 - call has limit and is traced by callcontrol 313 * -1 - not enough credit to make the call 314 * -2 - call is locked by another call in progress 315 * -5 - internal error (message parsing, communication, ...) 316 317 This function can be used from REQUEST_ROUTE. 318 319 Example 1.7. Using the call_control function 320... 321if (is_avp_set("$avp(i:805)")) { 322 # the diverter AVP is set, use it as billing party 323 $avp(s:billing_party_domain) = $(avp(i:805){uri.domain}); 324} else { 325 $avp(s:billing_party_domain) = $fd; 326} 327 328if (method==INVITE && !has_totag() && 329 is_domain_local("$avp(s:billing_party_domain)")) { 330 call_control(); 331 switch ($retcode) { 332 case 2: 333 # Call with no limit 334 case 1: 335 # Call has limit and is under callcontrol management 336 break; 337 case -1: 338 # Not enough credit (prepaid call) 339 sl_send_reply("402", "Not enough credit"); 340 exit; 341 break; 342 case -2: 343 # Locked by another call in progress (prepaid call) 344 sl_send_reply("403", "Call locked by another call in progress"); 345 exit; 346 break; 347 default: 348 # Internal error (message parsing, communication, ...) 349 if (PREPAID_ACCOUNT) { 350 xlog("Call control: internal server error\n"); 351 sl_send_reply("500", "Internal server error"); 352 exit; 353 } else { 354 xlog("L_WARN", "Cannot set time limit for postpaid call\n"); 355 } 356 } 357} 358t_relay(); 359... 360