# 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;
	}
}


# 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)");
        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,"})]}');
}

route[CGR_DLG_LIST] {
 if $sht(cgrconn=>cgr) == $null {
                sl_send_reply("503","Charging controller unreachable");
                exit;
        }
        jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.list","params":[]}');
		evapi_relay("{\"event\":\"CGR_DLG_LIST_REPLY\",
			\"jsonrpl_body\":$jsonrpl(body)}");
}


# 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_flags\":\"*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");
		exit;
	}
	evapi_async_relay("{\"event\":\"CGR_AUTH_REQUEST\",
		\"tr_index\":\"$T(id_index)\",
		\"tr_label\":\"$T(id_label)\",
		\"cgr_flags\":\"*attributes,*accounts,*suppliers,*resources,*thresholds\",
		\"reply_route\":\"CGR_SESSIONAUTH_REPLY\",
		\"Account\":\"$fU\",
		\"Destination\":\"$rU\",
		\"SetupTime\":\"$TS\"}");
}


# 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});

	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)", "ResourceAllocation", "$var(cgrResourceAllocation)");
	$var($var(cgrResourceAllocation)) = $(var(cgrResourceAllocation){s.rm,"});

	json_get_field("$evapi(msg)", "MaxUsage", "$var(MaxUsage)");
	$var(cgrMaxUsage) = $(var(MaxUsage){s.int});

	json_get_field("$evapi(msg)", "Suppliers", "$var(cgrSuppliers)");
	$var($var(cgrSuppliers)) = $(var(cgrSuppliers){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_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;
	}
	 evapi_relay("{\"event\":\"CGR_CALL_START\",
		\"h_entry\":\"$dlg(h_entry)\",
		\"h_id\":\"$dlg(h_id)\",
		\"cgr_flags\":\"*attributes,*accounts,*resources,*thresholds\",
		\"OriginID\":\"$dlg_var(cgrOriginID)\",
		\"RequestType\":\"$dlg_var(cgrReqType)\",
		\"Tenant\":\"$dlg_var(cgrTenant)\",
		\"Account\":\"$dlg_var(cgrAccount)\",
		\"Destination\":\"$dlg_var(cgrDestination)\",
		\"SetupTime\":\"$dlg_var(SetupTime)\",
		\"AnswerTime\":\"$TS\"}");
}


# Inform CGRateS about CALL_END (stop debit loops, perform accounting if desired in this way)
route[CGR_CALL_END] {
	if $sht(cgrconn=>cgr) == $null {
		xlog("Charging controller unreachable");
		exit;
	}
	$var(callDur) = $TS - $dlg(start_ts);
	 evapi_relay("{\"event\":\"CGR_CALL_END\",
		\"cgr_flags\":\"*accounts,*resources\",
		\"OriginID\":\"$dlg_var(cgrOriginID)\",
		\"RequestType\":\"$dlg_var(cgrReqType)\",
		\"Tenant\":\"$dlg_var(cgrTenant)\",
		\"Account\":\"$dlg_var(cgrAccount)\", 
		\"Destination\":\"$dlg_var(cgrDestination)\",
		\"AnswerTime\":\"$dlg(start_ts)\",
		\"PaypalAccount\":\"$dlg_var(paypalAccount)\",
		\"SetupTime\":\"$dlg_var(SetupTime)\",
		\"Usage\":\"$var(callDur)\"}");
}

