diff --git a/data/kamailio/etc/kamailio/kamailio-cgrates.cfg b/data/kamailio/etc/kamailio/kamailio-cgrates.cfg index 5f2b70bfe..7db28931b 100644 --- a/data/kamailio/etc/kamailio/kamailio-cgrates.cfg +++ b/data/kamailio/etc/kamailio/kamailio-cgrates.cfg @@ -1,55 +1,47 @@ # Kamailio-CGRateS related route blocks - +# Called on new connection over evapi, should normally be the case of CGRateS engine event_route[evapi:connection-new] { $sht(cgrconn=>cgr) = $evapi(srcaddr) + ":" + $evapi(srcport); # Detect presence of at least one connection } +# Called when the connection with CGRateS closes event_route[evapi:connection-closed] { - $var(connClosed) = $evapi(srcaddr) + ":" + $evapi(srcport); - if $sht(cgrconn=>cgr) == $var(connClosed) { - $sht(cgrconn=>cgr) = $null; - } + $var(connClosed) = $evapi(srcaddr) + ":" + $evapi(srcport); + if $sht(cgrconn=>cgr) == $var(connClosed) { + $sht(cgrconn=>cgr) = $null; + } } +# Message received from CGRateS, dispatch it to own route event_route[evapi:message-received] { json_get_field("$evapi(msg)", "Event", "$var(Event)"); - route($(var(Event){s.rm,"})); # String characters are kept by json_get_field, remove them here + route($(var(Event){s.rm,"})); # String characters are kept by json_get_field, remove them here } +# Called by Kamailio on new dialog event_route[dialog:start] { route(CGR_CALL_START); } +# Called by Kamailio on dialog end event_route[dialog:end] { route(CGR_CALL_END); } -event_route[dialog:failed] { - $avp(s:missed_call) = 1; +# Called by Kamailio on local disconnect +event_route[tm:local-request] { route(CGR_CALL_END); } + # Send AUTH_REQUEST to CGRateS -route[CGR_AUTH_REQUEST] { +route[CGRATES_AUTH_REQUEST] { # Auth INVITEs with CGRateS if $sht(cgrconn=>cgr) == $null { sl_send_reply("503","Charging controller unreachable"); exit; } - switch ($fU) { - case 1001: - $dlg_var(cgrReqType) = "*prepaid"; - break; - case 1002: - $dlg_var(cgrReqType) = "*postpaid"; - break; - default: - $dlg_var(cgrReqType) = "*rated"; - } - $dlg_var(cgrTenant) = "cgrates.org"; - $dlg_var(cgrAccount) = $fU; - $dlg_var(cgrDestination) = $rU; evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\", \"tr_index\":\"$T(id_index)\", \"tr_label\":\"$T(id_label)\", @@ -57,40 +49,61 @@ route[CGR_AUTH_REQUEST] { \"cgr_tenant\":\"$dlg_var(cgrTenant)\", \"cgr_account\":\"$dlg_var(cgrAccount)\", \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_setuptime\":\"$TS\"}"); + \"cgr_setuptime\":\"$TS\", + \"cgr_computelcr\":\"true\"}"); } # Process AUTH_REPLY from CGRateS route[CGR_AUTH_REPLY] { json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)"); - json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)"); - json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)"); - json_get_field("$evapi(msg)", "AuthError", "$var(AuthError)"); + json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)"); + json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)"); + json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)"); + json_get_field("$evapi(msg)", "Error", "$var(Error)"); $var(id_index) = $(var(TransactionIndex){s.int}); $var(id_label) = $(var(TransactionLabel){s.int}); - $var(max_session_time) = $(var(MaxSessionTime){s.int}); - t_continue("$var(id_index)", "$var(id_label)", "CGR_DIALOG_TIMEOUT"); + $var(CgrMaxSessionTime) = $(var(MaxSessionTime){s.int}); + $var(CgrSuppliers) = $(var(Suppliers){s.rm,"}); + $var(CgrError) = $(var(Error){s.rm,"}); + t_continue("$var(id_index)", "$var(id_label)", "CGRATES_AUTH_REPLY"); # Unpark the transaction } -# Check AUTH_REPLY for errors and set dialog timeout if necessary, call route(RELAY) after processing -route[CGR_DIALOG_TIMEOUT] { - if $var(AuthError) != "null" { # null is converted in string by json_get_field - xlog("CGR_AUTH_ERROR: $var(AuthError)"); - sl_send_reply("503","CGR_AUTH_ERROR"); +# Send AUTH_REQUEST to CGRateS +route[CGRATES_LCR_REQUEST] { + # Auth INVITEs with CGRateS + if $sht(cgrconn=>cgr) == $null { + sl_send_reply("503","Charging controller unreachable"); exit; } - if $var(max_session_time) != -1 && !dlg_set_timeout("$var(max_session_time)") { - sl_send_reply("503","CGR_MAX_SESSION_TIME_ERROR"); - exit; - } - route(RELAY); + evapi_async_relay("{\"event\":\"CGR_LCR_REQUEST\", + \"tr_index\":\"$T(id_index)\", + \"tr_label\":\"$T(id_label)\", + \"cgr_tenant\":\"$dlg_var(cgrTenant)\", + \"cgr_account\":\"$dlg_var(cgrAccount)\", + \"cgr_destination\":\"$dlg_var(cgrDestination)\", + \"cgr_setuptime\":\"$TS\"}"); +} + +# Process LCR_REPLY from CGRateS +route[CGR_LCR_REPLY] { + json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)"); + json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)"); + json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)"); + json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)"); + json_get_field("$evapi(msg)", "Error", "$var(Error)"); + $var(id_index) = $(var(TransactionIndex){s.int}); + $var(id_label) = $(var(TransactionLabel){s.int}); + $var(CgrMaxSessionTime) = $(var(MaxSessionTime){s.int}); + $var(CgrSuppliers) = $(var(Suppliers){s.rm,"}); + $var(CgrError) = $(var(Error){s.rm,"}); + t_continue("$var(id_index)", "$var(id_label)", "CGRATES_AUTH_REPLY"); # Unpark the transaction } # CGRateS request for session disconnect route[CGR_SESSION_DISCONNECT] { json_get_field("$evapi(msg)", "HashEntry", "$var(HashEntry)"); - json_get_field("$evapi(msg)", "HashId", "$var(HashId)"); - json_get_field("$evapi(msg)", "Reason", "$var(Reason)"); + json_get_field("$evapi(msg)", "HashId", "$var(HashId)"); + json_get_field("$evapi(msg)", "Reason", "$var(Reason)"); jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.end_dlg","params":[$(var(HashEntry){s.rm,"}),$(var(HashId){s.rm,"})]}'); #$jsonrpl($var(reply)); } @@ -101,7 +114,7 @@ route[CGR_CALL_START] { xlog("Charging controller unreachable"); exit; } - evapi_async_relay("{\"event\":\"CGR_CALL_START\", + evapi_relay("{\"event\":\"CGR_CALL_START\", \"callid\":\"$dlg(callid)\", \"from_tag\":\"$dlg(from_tag)\", \"h_entry\":\"$dlg(h_entry)\", @@ -110,7 +123,8 @@ route[CGR_CALL_START] { \"cgr_tenant\":\"$dlg_var(cgrTenant)\", \"cgr_account\":\"$dlg_var(cgrAccount)\", \"cgr_destination\":\"$dlg_var(cgrDestination)\", - \"cgr_answertime\":\"$TS\"}"); + \"cgr_answertime\":\"$TS\", + \"cgr_supplier\":\"$dlg_var(cgrSupplier)\"}"); } # Inform CGRateS about CALL_END (stop debit loops, perform accounting if desired in this way) @@ -119,21 +133,17 @@ route[CGR_CALL_END] { xlog("Charging controller unreachable"); exit; } - - # As default the duration is 0. - # If missed_call avp doesn't exists system send the correct duration - $var(callDur) = 0; - if( $avp(s:missed_call) == $null){ - $var(callDur) = $TS - $dlg(start_ts); - } - - evapi_async_relay("{\"event\":\"CGR_CALL_END\", + $var(callDur) = $TS - $dlg(start_ts); + evapi_relay("{\"event\":\"CGR_CALL_END\", \"callid\":\"$dlg(callid)\", \"from_tag\":\"$dlg(from_tag)\", \"cgr_reqtype\":\"$dlg_var(cgrReqType)\", \"cgr_tenant\":\"$dlg_var(cgrTenant)\", - \"cgr_account\":\"$dlg_var(cgrAccount)\", + \"cgr_account\":\"$dlg_var(cgrAccount)\", \"cgr_destination\":\"$dlg_var(cgrDestination)\", \"cgr_answertime\":\"$dlg(start_ts)\", - \"cgr_duration\":\"$var(callDur)\"}"); + \"cgr_duration\":\"$var(callDur)\", + \"cgr_supplier\":\"$dlg_var(cgrSupplier)\", + \"cgr_disconnectcause\":\"$T_reply_code\"}"); } + diff --git a/data/kamailio/etc/kamailio/kamailio.cfg b/data/kamailio/etc/kamailio/kamailio.cfg index 76409a528..d751bcebe 100644 --- a/data/kamailio/etc/kamailio/kamailio.cfg +++ b/data/kamailio/etc/kamailio/kamailio.cfg @@ -17,14 +17,18 @@ memlog=5 log_facility=LOG_LOCAL0 fork=yes children=4 -listen=172.16.254.79:5060 tcp_connection_lifetime=3605 +use_dns_cache=no +dns_try_ipv6=no +dns_retr_time=1 +dns_retr_no=1 +dns_servers_no=1 +dns_use_search_list=no ####### Modules Section ######## mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/" -loadmodule "mi_fifo.so" loadmodule "kex.so" loadmodule "corex.so" loadmodule "tm.so" @@ -39,10 +43,7 @@ loadmodule "textops.so" loadmodule "siputils.so" loadmodule "xlog.so" loadmodule "sanity.so" -loadmodule "ctl.so" -loadmodule "mi_rpc.so" loadmodule "nathelper.so" -loadmodule "rtpproxy.so" loadmodule "htable.so" loadmodule "auth.so" loadmodule "evapi.so" @@ -51,10 +52,10 @@ loadmodule "dialog.so" loadmodule "xhttp.so" loadmodule "jsonrpc-s.so" + + # ----------------- setting module-specific parameters --------------- -# ----- mi_fifo params ----- -modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo") # ----- tm params ----- modparam("tm", "failure_reply_mode", 3) @@ -74,9 +75,6 @@ modparam("dialog", "dlg_flag", FLT_DIALOG) modparam("dialog", "send_bye", 1) modparam("dialog", "timeout_noreset", 1) -# ----- rtpproxy params ----- -modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722") - # ----- nathelper params ----- modparam("nathelper", "natping_interval", 30) modparam("nathelper", "ping_nated_only", 1) @@ -91,10 +89,6 @@ modparam("usrloc", "nat_bflag", FLB_NATB) modparam("htable", "htable", "users=>size=8;") modparam("htable", "htable", "cgrconn=>size=1;") - -modparam("evapi", "workers", 2) -modparam("evapi", "bind_addr", "127.0.0.1:8448") - ####### Routing Logic ######## include_file "kamailio-cgrates.cfg" @@ -104,6 +98,7 @@ event_route[htable:mod-init] { $sht(users=>1002) = "CGRateS.org"; $sht(users=>1003) = "CGRateS.org"; $sht(users=>1004) = "CGRateS.org"; + $sht(users=>1005) = "CGRateS.org"; $sht(users=>1006) = "CGRateS.org"; $sht(users=>1007) = "CGRateS.org"; } @@ -170,10 +165,51 @@ request_route { route(RELAY); } dlg_manage(); - route(CGR_AUTH_REQUEST); + switch ($fU) { + case 1001: + case 1006: + case 1007: + $dlg_var(cgrReqType) = "*prepaid"; + break; + case 1002: + $dlg_var(cgrReqType) = "*postpaid"; + break; + case 1003: + $dlg_var(cgrReqType) = "*pseudoprepaid"; + break; + default: + $dlg_var(cgrReqType) = "*rated"; + } + $dlg_var(cgrTenant) = "cgrates.org"; + $dlg_var(cgrAccount) = $fU; + $dlg_var(cgrDestination) = $rU; + route(CGRATES_AUTH_REQUEST); # Will be answered in CGRATES_AUTH_REPLY + #route(CGRATES_LCR_REQUEST); exit; } +# Here will land requests after processing them with CGRateS. Call RELAY or other routes following this route +route[CGRATES_AUTH_REPLY] { + if $var(CgrError) != "" { + xlog("CGR_AUTH_ERROR: $var(CgrError)"); + sl_send_reply("503","CGR_ERROR"); + exit; + } + if $var(CgrMaxSessionTime) != -1 { + if $var(CgrMaxSessionTime) == 0 { // Not enough balance, do not allow the call to go through + sl_send_reply("403","Insufficient credit"); + exit; + } else if !dlg_set_timeout("$var(CgrMaxSessionTime)") { + sl_send_reply("503","CGR_MAX_SESSION_TIME_ERROR"); + exit; + } + } + if $var(CgrSuppliers) != "" { # Enforce the supplier variable to the first one received from CGRateS, more for testing purposes + $dlg_var(cgrSupplier) = $(var(CgrSuppliers){s.select,0,,}); + } + route(RELAY); +} + # Wrapper for relaying requests route[RELAY] { # enable additional event routes for forwarded requests @@ -321,8 +357,6 @@ route[NATMANAGE] { if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) return; - rtpproxy_manage("co"); - if (is_request()) { if (!has_totag()) { if(t_is_branch_route()) { diff --git a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg index 9a837fd5e..7db28931b 100644 --- a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg +++ b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg @@ -114,7 +114,7 @@ route[CGR_CALL_START] { xlog("Charging controller unreachable"); exit; } - evapi_async_relay("{\"event\":\"CGR_CALL_START\", + evapi_relay("{\"event\":\"CGR_CALL_START\", \"callid\":\"$dlg(callid)\", \"from_tag\":\"$dlg(from_tag)\", \"h_entry\":\"$dlg(h_entry)\", @@ -134,7 +134,7 @@ route[CGR_CALL_END] { exit; } $var(callDur) = $TS - $dlg(start_ts); - evapi_async_relay("{\"event\":\"CGR_CALL_END\", + evapi_relay("{\"event\":\"CGR_CALL_END\", \"callid\":\"$dlg(callid)\", \"from_tag\":\"$dlg(from_tag)\", \"cgr_reqtype\":\"$dlg_var(cgrReqType)\",