Updating kamevapi tutorial files

This commit is contained in:
DanB
2018-05-16 14:47:06 +02:00
parent c050f0b879
commit 6e8a0235f1
3 changed files with 139 additions and 68 deletions

View File

@@ -81,7 +81,7 @@
"kamailio_agent": {
"enabled": true,
"evapi_conns":[ // instantiate connections to multiple Kamailio servers
{"address": "192.168.56.102:8448", "reconnects": 5}
{"address": "127.0.0.1:8448", "reconnects": 5}
],
"sessions_conns": [
{"address": "*internal"} // connection towards session service: <*internal>

View File

@@ -1,10 +1,12 @@
# 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);
@@ -13,22 +15,37 @@ event_route[evapi:connection-closed] {
}
}
# 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
}
# 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);
}
# Parse the CGRateS attributes from encoded variable into pseudovariables
route[PARSE_CGRATES_ATTRIBUTES] {
# convert encoded attributes into individual Kamailio pseudovariables
$var(idx) = 0;
while !strempty($(var(cgrAttributes){s.select,$var(idx),,})) {
$avp($(var(cgrAttributes){s.select,$var(idx),,}{s.select,0,:}))
= $(var(cgrAttributes){s.select,$var(idx),,}{s.select,1,:});
$var(idx) = $var(idx) + 1;
}
}
# CGRateS request for session disconnect
route[CGR_SESSION_DISCONNECT] {
json_get_field("$evapi(msg)", "HashEntry", "$var(HashEntry)");
@@ -39,8 +56,46 @@ route[CGR_SESSION_DISCONNECT] {
}
# Send AUTH_REQUEST to CGRateS
route[CGRATES_AUTH_REQUEST] {
# Route to mainly query account password from CGRateS
route[CGRATES_SIMPLEAUTH_REQUEST] {
if $sht(cgrconn=>cgr) == $null {
sl_send_reply("503","Charging controller unreachable");
exit;
}
evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\",
\"tr_index\":\"$T(id_index)\",
\"tr_label\":\"$T(id_label)\",
\"cgr_subsystems\":\"*attributes\",
\"cgr_context\":\"simpleauth\",
\"reply_route\":\"CGR_SIMPLEAUTH_REPLY\",
\"Account\":\"$fU\"}");
}
# Route receiving simpleauth replies, sanitizes them and dispatch back into Kamailio inside CGRATES_SIMPLEAUTH_REPLY
route[CGR_SIMPLEAUTH_REPLY] {
json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)");
$var(TransactionIndex) = $(var(TransactionIndex){s.rm,"});
$var(id_index) = $(var(TransactionIndex){s.int});
json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)");
$var(TransactionLabel) = $(var(TransactionLabel){s.rm,"});
$var(id_label) = $(var(TransactionLabel){s.int});
json_get_field("$evapi(msg)", "Attributes", "$var(cgrAttributes)");
$var(cgrAttributes) = $(var(cgrAttributes){s.rm,"});
json_get_field("$evapi(msg)", "Error", "$var(cgrError)");
$var(cgrError) = $(var(cgrError){s.rm,"});
t_continue("$var(id_index)", "$var(id_label)", "CGRATES_SIMPLEAUTH_REPLY"); # Unpark the transaction
}
# Request session auth information from CGRateS
route[CGRATES_SESSIONAUTH_REQUEST] {
# Auth INVITEs with CGRateS
if $sht(cgrconn=>cgr) == $null {
sl_send_reply("503","Charging controller unreachable");
@@ -49,16 +104,16 @@ route[CGRATES_AUTH_REQUEST] {
evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\",
\"tr_index\":\"$T(id_index)\",
\"tr_label\":\"$T(id_label)\",
\"cgr_subsystems\":\"*attributes;*resources;*accounts;*suppliers;*stats;*thresholds\",
\"RequestType\":\"$dlg_var(cgrReqType)\",
\"Tenant\":\"$dlg_var(cgrTenant)\",
\"Account\":\"$dlg_var(cgrAccount)\",
\"Destination\":\"$dlg_var(cgrDestination)\",
\"cgr_subsystems\":\"*attributes;*accounts\",
\"reply_route\":\"CGR_SESSIONAUTH_REPLY\",
\"Account\":\"$fU\",
\"Destination\":\"$rU\",
\"SetupTime\":\"$TS\"}");
}
# Process AUTH_REPLY from CGRateS
route[CGR_AUTH_REPLY] {
# Process SESSIONAUTH_reply from CGRateS
route[CGR_SESSIONAUTH_REPLY] {
json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)");
$var(TransactionIndex) = $(var(TransactionIndex){s.rm,"});
$var(id_index) = $(var(TransactionIndex){s.int});
@@ -82,20 +137,20 @@ route[CGR_AUTH_REPLY] {
json_get_field("$evapi(msg)", "Error", "$var(cgrError)");
$var(cgrError) = $(var(cgrError){s.rm,"});
t_continue("$var(id_index)", "$var(id_label)", "CGRATES_AUTH_REPLY"); # Unpark the transaction
t_continue("$var(id_index)", "$var(id_label)", "CGRATES_SESSIONAUTH_REPLY"); # Unpark the transaction
}
# Inform CGRateS about CALL_START (start prepaid sessions loops)
route[CGR_CALL_START] {
if $sht(cgrconn=>cgr) == $null {
xlog("Charging controller unreachable");
exit;
}
$var(cgrOriginID) = $dlg(callid)+";"+$dlg(from_tag);
evapi_relay("{\"event\":\"CGR_CALL_START\",
\"h_entry\":\"$dlg(h_entry)\",
\"h_id\":\"$dlg(h_id)\",
\"cgr_subsystems\":\"*attributes;*resources;*accounts;*stats;*thresholds\",
\"cgr_subsystems\":\"*attributes;*accounts\",
\"OriginID\":\"$dlg_var(cgrOriginID)\",
\"RequestType\":\"$dlg_var(cgrReqType)\",
\"Tenant\":\"$dlg_var(cgrTenant)\",
@@ -105,7 +160,6 @@ route[CGR_CALL_START] {
}
# Inform CGRateS about CALL_END (stop debit loops, perform accounting if desired in this way)
route[CGR_CALL_END] {
if $sht(cgrconn=>cgr) == $null {
@@ -114,7 +168,7 @@ route[CGR_CALL_END] {
}
$var(callDur) = $TS - $dlg(start_ts);
evapi_relay("{\"event\":\"CGR_CALL_END\",
\"cgr_subsystems\":\"*resources;*accounts;*stats;*thresholds\",
\"cgr_subsystems\":\"*accounts\",
\"OriginID\":\"$dlg_var(cgrOriginID)\",
\"RequestType\":\"$dlg_var(cgrReqType)\",
\"Tenant\":\"$dlg_var(cgrTenant)\",
@@ -122,4 +176,5 @@ route[CGR_CALL_END] {
\"Destination\":\"$dlg_var(cgrDestination)\",
\"AnswerTime\":\"$dlg(start_ts)\",
\"Usage\":\"$var(callDur)\"}");
}
}

View File

@@ -1,7 +1,7 @@
#!KAMAILIO
# Sample demo config for Kamailio-CGRateS communication
# tested against Kamailio 5.0
# tested against Kamailio 5.1
####### Defined Values #########
@@ -28,10 +28,6 @@ dns_retr_no=1
dns_servers_no=1
dns_use_search_list=no
listen=udp:eth0:5060
listen=udp:127.0.0.1:5080
listen=tcp:127.0.0.1:5060
####### Modules Section ########
mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
@@ -93,23 +89,12 @@ modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)")
modparam("usrloc", "nat_bflag", FLB_NATB)
# ----- htable params -----
modparam("htable", "htable", "users=>size=8;")
modparam("htable", "htable", "cgrconn=>size=1;")
####### Routing Logic ########
include_file "kamailio-cgrates.cfg"
event_route[htable:mod-init] {
$sht(users=>1001) = "CGRateS.org";
$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";
}
# Main SIP request routing logic
request_route {
@@ -140,9 +125,6 @@ request_route {
}
t_check_trans();
# authentication
route(AUTH);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
@@ -157,8 +139,11 @@ request_route {
### requests for my local domains
# handle registrations
route(REGISTRAR);
# SIMPLE AUTH methods
if is_method("REGISTER|SUBSCRIBE|PUBLISH") {
route(CGRATES_SIMPLEAUTH_REQUEST);
exit;
}
if ($rU==$null) {
# request with no Username in RURI
@@ -166,43 +151,65 @@ request_route {
exit;
}
# user location service
route(LOCATION);
if !is_method("INVITE") {
route(RELAY);
}
dlg_manage();
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(cgrOriginID) = $dlg(callid) + ";" + $dlg(from_tag);
$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(RELAY);
sl_send_reply("503", "Unsupported method");
exit;
}
route(CGRATES_SESSIONAUTH_REQUEST);
exit;
}
# Here will land requests after processing them with CGRateS.
route[CGRATES_SIMPLEAUTH_REPLY] {
if $var(cgrError) != "" {
xlog("CGR_PROFILE_ERROR: $var(cgrError)");
sl_send_reply("503","CGR_ERROR");
exit;
}
# parse the CGRateS attributes
route(PARSE_CGRATES_ATTRIBUTES);
# password based auth
route(AUTH);
if is_method("REGISTER") {
route(REGISTRAR);
exit;
}
# other methods going over location
route(LOCATION);
route(RELAY);
}
# Here will land requests after processing them with CGRateS. Call RELAY or other routes following this route
route[CGRATES_AUTH_REPLY] {
route[CGRATES_SESSIONAUTH_REPLY] {
if $var(cgrError) != "" {
xlog("CGR_AUTH_ERROR: $var(cgrError)");
sl_send_reply("503","CGR_ERROR");
exit;
}
# parse the CGRateS attributes
route(PARSE_CGRATES_ATTRIBUTES);
# password based auth
route(AUTH);
# track the dialog so we can set it's timeout and channel variables to store in CDRs
# cannot initialize the dialog sooner due to AUTH
dlg_manage();
$dlg_var(cgrOriginID) = $dlg(callid) + ";" + $dlg(from_tag);
$dlg_var(cgrTenant) = "cgrates.org";
$dlg_var(cgrReqType) = $avp(RequestType);
$dlg_var(cgrAccount) = $fU;
$dlg_var(cgrDestination) = $rU;
if $var(cgrMaxUsage) != -1 {
if $var(cgrMaxUsage) == 0 { // Not enough balance, do not allow the call to go through
sl_send_reply("403","Insufficient credit");
@@ -212,12 +219,20 @@ route[CGRATES_AUTH_REPLY] {
exit;
}
}
if $var(cgrSuppliers) != "" { # Enforce the supplier variable to the first one received from CGRateS, here more for demo purposes
$dlg_var(cgrSupplier) = $(var(cgrSuppliers){s.select,0,,});
}
# user location service
route(LOCATION);
# send out
route(RELAY);
}
# Wrapper for relaying requests
route[RELAY] {
# enable additional event routes for forwarded requests
@@ -293,8 +308,6 @@ route[WITHINDLG] {
# Handle SIP registrations
route[REGISTRAR] {
if (!is_method("REGISTER")) return;
if(isflagset(FLT_NATS)) {
setbflag(FLB_NATB);
}
@@ -321,15 +334,16 @@ route[LOCATION] {
}
}
# user uthentication
route[AUTH] {
if (is_method("REGISTER")) {
if ( strempty($au) || !pv_www_authenticate("$td", "$sht(users=>$au)", "0") ) {
if ( strempty($au) || !pv_www_authenticate("$td", "$avp(Password)", "0") ) {
www_challenge("$td", "0");
exit;
}
} else { # All other methods here
if ( strempty($au) || !pv_proxy_authenticate("$td", "$sht(users=>$au)", "0") ) {
if ( strempty($au) || !pv_proxy_authenticate("$td", "$avp(Password)", "0") ) {
proxy_challenge("$td", "0");
exit;
}
@@ -338,6 +352,7 @@ route[AUTH] {
return;
}
# Caller NAT detection
route[NATDETECT] {
force_rport();
@@ -414,3 +429,4 @@ failure_route[MANAGE_FAILURE] {
exit;
}
}