Files
2025-08-21 01:07:07 +00:00

495 lines
14 KiB
INI

#
# OpenSIPS residential configuration script
# by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This script was generated via "make menuconfig", from
# the "Residential" scenario.
# You can enable / disable more features / functionalities by
# re-generating the scenario with different options.#
#
# Please refer to the Core CookBook at:
# https://opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#
####### Global Parameters #########
/* uncomment the following lines to enable debugging */
#debug_mode=yes
log_level=3
xlog_level=3
#mem_log=6
log_stderror=yes
log_stdout=yes
log_facility=LOG_LOCAL0
udp_workers=4
/* uncomment the next line to enable the auto temporary blacklisting of
not available destinations (default disabled) */
#disable_dns_blacklist=no
/* uncomment the next line to enable IPv6 lookup after IPv4 dns
lookup failures (default disabled) */
#dns_try_ipv6=yes
dns=no
socket=udp:PCSCF_IP:5060
socket=tcp:PCSCF_IP:5060
socket=ipsec:PCSCF_IP:6100,5100
alias="pcscf.IMS_DOMAIN"
#set module path
mpath="/usr/local/opensips/modules"
####### Modules Section ########
#### MYSQL module
loadmodule "db_mysql.so"
#### SIGNALING module
loadmodule "signaling.so"
#### StateLess module
loadmodule "sl.so"
#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)
#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)
#### MAX ForWarD module
loadmodule "maxfwd.so"
#### NATHELPER module
loadmodule "nathelper.so"
#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"
#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/var/run/opensips/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)
#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "mi_dump_kv_store", 1)
modparam("usrloc", "working_mode_preset", "single-instance-no-db")
#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)
#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
if you enable this parameter, be sure to enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
#### proto_udp module
loadmodule "dispatcher.so"
loadmodule "proto_udp.so"
loadmodule "proto_tcp.so"
loadmodule "proto_ipsec.so"
loadmodule "dialog.so"
#### dbtext module
loadmodule "db_text.so"
modparam("dispatcher", "db_url", "text:///etc/opensips/db")
modparam("proto_ipsec", "min_spi", 10000)
modparam("proto_ipsec", "max_spi", 10100)
modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null, hmac-md5-96=null")
#### RTPENGINE module
loadmodule "rtpengine.so"
modparam("rtpengine", "rtpengine_sock", "udp:RTPENGINE_IP:2223")
loadmodule "event_route.so"
loadmodule "json.so"
#### PRESENCE modules
loadmodule "presence.so"
loadmodule "presence_reginfo.so"
loadmodule "pua.so"
modparam("pua|presence","db_url", "mysql://opensips_pcscf:heslo@MYSQL_IP/opensips_pcscf")
loadmodule "pua_reginfo.so"
modparam("pua_reginfo", "ul_domain", "location")
modparam("pua_reginfo", "ul_identities_key", "identities")
modparam("pua_reginfo", "default_domain", "IMS_DOMAIN")
modparam("pua_reginfo", "server_address", "sip:reginfo@pcscf.IMS_DOMAIN")
##### N5 HTTP2 Modules and setting
loadmodule "rest_client.so"
modparam("rest_client", "curl_timeout", 7)
modparam("rest_client", "connection_timeout", 4)
modparam("rest_client", "curl_http_version", 5)
####### Routing Logic ########
# main request routing logic
route{
xlog("L_INFO", "[$ci] Start route time [$Tf] method ($rm) r-uri ($ru) \n");
set_via_handling("force-rport");
if (!mf_process_maxfwd_header(10)) {
send_reply(483,"Too Many Hops");
exit;
}
if (has_totag()) {
# handle hop-by-hop ACK (no routing required)
if ( is_method("ACK") && t_check_trans() ) {
t_relay();
exit;
}
# sequential request within a dialog should
# take the path determined by record-routing
if ( !loose_route() ) {
# we do record-routing for all our traffic, so we should not
# receive any sequential requests without Route hdr.
send_reply(404,"Not here");
exit;
}
if (is_method("BYE")) {
# do accounting even if the transaction fails
do_accounting("log","failed");
route(session_termination);
}
if (is_method("UPDATE")) {
if ($si != "SCSCF_IP")
rtpengine_offer("replace-origin");
else
t_on_reply("rtpengine_answer");
}
if (is_method("SUBSCRIBE|NOTIFY") && is_myself($rd)) {
route(handle_presence);
exit;
}
# route it out to whatever destination was set by loose_route()
# in $du (destination URI).
route(relay);
exit;
}
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans())
t_relay();
exit;
}
# absorb retransmissions, but do not create transaction
t_check_trans();
if (is_method("REGISTER")) {
xlog("L_INFO", "[$ci] Received REGISTER for $tu - relaying to I-CSCF\n");
append_hf("Path: <sip:term@pcscf.IMS_DOMAIN;lr>\r\n");
if ($hdr(Security-Client)) {
setflag("SEC_AGREE");
append_hf("P-Visited-Network-ID: IMS_DOMAIN\r\n");
}
t_on_reply("register_reply");
route(relay);
exit;
} else if (is_method("SUBSCRIBE|PUBLISH")) {
xlog("L_INFO", "[$ci] Received $rm for $tu - handling\n");
route(handle_presence);
exit;
} else if (is_method("INVITE")) {
if (loose_route()) {
xlog("L_INFO", "[$ci] Received INVITE for $tu - relaying to S-CSCF ($ru/$du)\n");
remove_hf("Security-Verify");
if (list_hdr_has_option("Require", "sec-agree"))
list_hdr_remove_option("Require", "sec-agree");
if (list_hdr_has_option("Proxy-Require", "sec-agree"))
list_hdr_remove_option("Proxy-Require", "sec-agree");
append_hf("P-Visited-Network-ID: IMS_DOMAIN\r\n");
$socket_out = "tcp:PCSCF_IP:5060";
$avp(si) = $si;
$avp(sub_id) = "imsi-" + $fU;
rtpengine_offer("replace-origin");
} else {
xlog("L_INFO", "[$ci] Received INVITE for $tu - looking up from S-CSCF ($ru/$du/$tu)\n");
$rU = $(tU{s.select,0,;});
$avp(sub_id) = "imsi-" + $tU;
if (!lookup("location")) {
xlog("L_ERR", "[$ci] user $rU not found\n");
t_reply(404, "Not here");
exit;
}
}
route(extract_ip_port);
$avp(ip) = $var(ip);
$avp(port) = $var(port);
$avp(rtcp) = $var(rtcp);
$avp(stream) = $(rb{sdp.stream,0});
t_on_reply("invite_reply");
if (!record_route()) {
xlog("L_ERR", "[$ci] Cannot do record_route()\n");
t_reply(503, "Internal Error");
exit;
}
if (!create_dialog()) {
xlog("L_ERR", "[$ci] Cannot create_dialog()\n");
t_reply(503, "Internal Error");
exit;
}
if (!t_relay()) {
xlog("L_ERR", "[$ci] Cannot relay to $ru/$du\n");
t_reply(503, "Internal Error");
exit;
}
exit;
}
send_reply(405,"Method Not Allowed");
exit;
}
route[relay] {
if (!t_relay()) {
send_reply(500,"Internal Error");
}
exit;
}
onreply_route[register_reply] {
xlog("L_INFO","[$ci] Received REGISTER reply $rs from $si for $tu\n");
if ($T_reply_code == 401) {
if (!isflagset("SEC_AGREE") || ipsec_create())
route(dm_send_aar, "control");
} else if ($T_reply_code == 200) {
for ($var(item) in $(hdr(P-Associated-URI)[*])) {
$var(uri_len) = $(var(item){s.len}) - 2;
$var(uri) = $(var(item){s.substr, 1, $var(uri_len)});
if (!save("location", "no-reply, path-off", $var(uri))) {
xlog("L_ERR", "[$ci] could not save aor [$var(uri)]\n");
} else {
ul_add_key("location", "$tU@$td", "identities", "$var(uri)");
}
}
reginfo_update("$tU@$td");
}
}
onreply_route[invite_reply] {
if (!has_body_part("application/sdp")) {
xlog("L_INFO","[$ci] Received INVITE reply $rs from $si for $tu - without SDP\n");
return;
} else if (isflagset("INVITE_AAA")) {
xlog("L_INFO","[$ci] Received INVITE reply $rs from $si for $tu - AAA done\n");
return;
}
xlog("L_INFO","[$ci] Received INVITE reply $rs from $si for $tu - doing AAR\n");
route(extract_ip_port);
if ($avp(si) == NULL) {
rtpengine_answer("replace-origin");
$avp(si) = $si;
$var(tmp_ip) = $avp(ip);
$var(tmp_port) = $avp(port);
$avp(ip) := $var(ip);
$avp(port) := $var(port);
$var(ip) = $var(tmp_ip);
$var(port) = $var(tmp_port);
}
route(dm_send_aar, "audio");
setflag("INVITE_AAA");
}
onreply_route[rtpengine_answer] {
if (!has_body_part("application/sdp"))
return;
rtpengine_answer("replace-origin");
}
route[dm_send_aar] {
switch ($param(1)) {
case "control":
if ($ipsec(ip) != NULL) {
$var(src_ip) = $ipsec_ue(ip);
$var(src_port) = $ipsec_ue(port-c);
$var(dst_ip) = $ipsec(ip);
$var(dst_port) = $ipsec(port-s);
$var(sess_port) = $ipsec_ue(port-s);
} else {
$var(src_ip) = $si;
$var(src_port) = $sp;
$var(dst_ip) = $socket_in(ip);
$var(dst_port) = $socket_in(port);
$var(sess_port) = $sp;
}
$var(afAppId) = "+g.3gpp.icsi-ref=\\\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\\\"";
$var(dnn) = "ims";
$json(array1) := "[\"permit in ip from "+$var(src_ip)+" "+$var(src_port)+" to "+$var(dst_ip)+" "+$var(dst_port)+"\", \"permit out ip from "+$var(dst_ip)+" "+$var(dst_port)+" to "+$var(src_ip)+" "+$var(src_port)+"\"]";
$var(events) = "[{\"event\": \"QOS_NOTIF\", \"notifMethod\": \"PERIODIC\"}, {\"event\": \"ANI_REPORT\", \"notifMethod\": \"ONE_TIME\"}]";
$var(notifUri) = "http://N5_BIND_IP:N5_BIND_PORT";
$var(sponStatus) = "SPONSOR_DISABLED";
$var(supi) = "imsi-"+ $au;
$var(suppFeat) = "2";
$var(ueIpv4) = $var(src_ip);
$json(nf_reg_body) = "{
\"ascReqData\":{
\"afAppId\": \""+$var(afAppId)+"\",
\"dnn\": \""+$var(dnn)+"\" ,
\"medComponents\":{
\"0\":{
\"medCompN\":0,
\"qosReference\":\"qosVoNR\",
\"medType\":\"CONTROL\",
\"medSubComps\":{
\"0\":{
\"fNum\":0,
\"fDescs\": "+$json(array1)+",
\"fStatus\":\"ENABLED\",
\"flowUsage\":\"AF_SIGNALLING\"
}
}
}
},
\"evSubsc\":{ \"events\": "+$var(events)+"},
\"notifUri\": \""+$var(notifUri)+"\" ,
\"sponStatus\": \""+$var(sponStatus)+"\",
\"supi\": \""+$var(supi)+"\",
\"suppFeat\": \""+$var(suppFeat)+"\",
\"ueIpv4\": \""+$var(ueIpv4)+"\"
}
}";
rest_post("http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$json_pretty(nf_reg_body)", "application/json" , $var(resp), $var(ct), $var(rcode));
xlog("L_INFO", "N5 Response: [$(hdr(location)) ] \n");
xlog("L_INFO", "N5 Response: [$var(resp)] \n");
xlog("L_INFO", "N5 Response: [$var(ct)] \n");
xlog("L_INFO", "N5 Response: [$var(rcode)] \n");
break;
case "audio":
$var(afAppId) = "+g.3gpp.icsi-ref=\\\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\\\"";
$var(dnn) = "ims";
$json(array1) := "[\"permit in ip from "+$avp(ip)+" "+$avp(port)+" to "+$var(ip)+" "+$var(port)+"\", \"permit out ip from "+$var(ip)+" "+$var(port)+" to "+$avp(ip)+" "+$avp(port)+"\"]";
$json(array2) := "[\"permit in ip from "+$avp(ip)+" "+$avp(rtcp)+" to "+$var(ip)+" "+$var(rtcp)+"\", \"permit out ip from "+$var(ip)+" "+$var(rtcp)+" to "+$avp(ip)+" "+$avp(rtcp)+"\"]";
$var(events) = "[{\"event\": \"QOS_NOTIF\", \"notifMethod\": \"PERIODIC\"}, {\"event\": \"ANI_REPORT\", \"notifMethod\": \"ONE_TIME\"}]";
$var(notifUri) = "http://N5_BIND_IP:N5_BIND_PORT";
$var(sponStatus) = "SPONSOR_DISABLED";
$var(supi) = $avp(sub_id);
$var(suppFeat) = "2";
$var(ueIpv4) = $avp(ip);
$json(nf_call_body) = "{
\"ascReqData\": {
\"afAppId\": \""+$var(afAppId)+"\",
\"dnn\": \""+$var(dnn)+"\" ,
\"medComponents\":{
\"0\":{
\"medCompN\":0,
\"qosReference\":\"qosVoNR\",
\"medType\":\"AUDIO\",
\"medSubComps\":{
\"0\":{
\"fNum\":1,
\"fDescs\": "+$json(array1)+",
\"fStatus\":\"ENABLED\",
\"marBwDl\":\"5000 Kbps\",
\"marBwUl\":\"3000 Kbps\",
\"flowUsage\":\"NO_INFO\"
},
\"1\":{
\"fNum\":2,
\"fDescs\": "+$json(array2)+",
\"fStatus\":\"ENABLED\",
\"marBwDl\":\"5000 Kbps\",
\"marBwUl\":\"3000 Kbps\",
\"flowUsage\":\"RTCP\"
}
}
}
},
\"evSubsc\":{ \"events\": "+$var(events)+"},
\"notifUri\": \""+$var(notifUri)+"\" ,
\"sponStatus\": \""+$var(sponStatus)+"\",
\"supi\": \""+$var(supi)+"\",
\"suppFeat\": \""+$var(suppFeat)+"\",
\"ueIpv4\": \""+$var(ueIpv4)+"\"
}
}";
rest_post("http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$json_pretty(nf_call_body)", "application/json" , $var(resp), $var(ct), $var(rcode));
xlog("L_INFO", "N5 Response: [$(hdr(location)) ] \n");
xlog("L_INFO", "N5 Response: [$var(resp)] \n");
xlog("L_INFO", "N5 Response: [$var(ct)] \n");
xlog("L_INFO", "N5 Response: [$var(rcode)] \n");
break;
}
}
route[session_termination] {
if ($si != "SCSCF_IP")
rtpengine_delete();
xlog("L_INFO","[$ci] Received BYE from $si for $tu - can't terminate N5: WIP N5 Termination logic\n");
}
route[extract_ip_port] {
$var(ip) = $(rb{sdp.line,c}{s.select,2, });
$var(port) = $(rb{sdp.line,m}{s.select,1, });
$var(rtcp) = $(var(port){s.int}) + 1;
}
route[handle_presence] {
if (!t_newtran()){
sl_reply_error();
exit;
}
if ($hdr(Event) != "reg") {
xlog("L_ERR", "[$ci] Unhandled event $hdr(Event)\n");
send_reply(489, "Bad Event");
exit;
}
if (is_method("PUBLISH"))
handle_publish();
if (is_method("SUBSCRIBE"))
handle_subscribe();
}