diff --git a/pcscf/kamailio_pcscf.cfg b/pcscf/kamailio_pcscf.cfg index 5b3b7f4..d278b2e 100644 --- a/pcscf/kamailio_pcscf.cfg +++ b/pcscf/kamailio_pcscf.cfg @@ -461,7 +461,7 @@ modparam("http_client", "response_headers", 1) modparam("http_client", "query_result", 1) modparam("nghttp2", "listen_addr", "N5_BIND_IP") modparam("nghttp2", "listen_port", "N5_BIND_PORT") -# Replace the following with your own Key and Cert, you can use HAProxy to terminate TLS towards Clients (Open5gs) +# Replace the following with your own Key and Cert, you can use HAProxy to terminate TLS towards Clients e.g. Open5gs PCF # modparam("nghttp2", "tls_private_key", "/mnt/pcscf/http2_key.pem") # modparam("nghttp2", "tls_public_key", "/mnt/pcscf/http2_tr.pem") @@ -1021,8 +1021,8 @@ route[preload_pcscf] { # 5G N5 HTTP2 Server routing script basic code event_route[nghttp2:request] { xinfo("request: $nghttp2(method) - url: $nghttp2(path) - data: [$nghttp2(data)]\n"); - - // Check if the requested URL is /nf-status-notify + + # Check if the requested URL is /nf-status-notify if ($nghttp2(path) == "/nf-status-notify") { nghttp2_reply_header("Content-Type", "text/html"); nghttp2_reply_header("Server:", "AF"); @@ -1034,11 +1034,11 @@ event_route[nghttp2:request] { nghttp2_reply_header("Server", "AF"); nghttp2_reply("204", "No Content"); } else { - // Optionally handle other URLs or do nothing + # Optionally handle other URLs or do nothing nghttp2_reply_header("accept", "application/json"); nghttp2_reply_header("accept", "application/problem+json"); nghttp2_reply_header("Content-Type", "application/json"); - nghttp2_reply_header("Server", "AF"); + nghttp2_reply_header("Server", "AF"); nghttp2_reply("404", "Not Found"); } } diff --git a/pcscf/route/mo.cfg b/pcscf/route/mo.cfg index 596d920..ffc9b31 100644 --- a/pcscf/route/mo.cfg +++ b/pcscf/route/mo.cfg @@ -6,9 +6,9 @@ route[MO] # Strip Transport from RURI: $ru = $(ru{re.subst,/;transport=[A-Za-z]*//g}); xnotice("PCSCF MO: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); # Process route headers, if any: loose_route(); @@ -65,35 +65,33 @@ route[MO] # Check for "sec-agree" in the Proxy-Require header: if (is_present_hf("Proxy-Require") && $hdr(Proxy-Require) =~ ".*sec-agree.*") { - # Remove the old Proxy-Require-Header: + # Remove the old Proxy-Require-Header: remove_hf("Proxy-Require"); # Replace ", sec-agree" with "" $var(new_hdr) = $(hdr(Proxy-Require){re.subst,/[, ]*sec-agree//gi}); if ($(var(new_hdr){s.len}) > 0) { append_hf("Proxy-Require: $var(new_hdr)\r\n"); } - } + } remove_hf("Security-Verify"); - -# -#Route N5 Request -# - if(is_method("INVITE")) { - route(N5_INIT_REQ); - } +#!ifdef WITH_N5 + if(is_method("INVITE")) { + route(N5_INIT_REQ); + } +#!endif #!ifdef TRF_FUNCTION $var(trf) = TRF_FUNCTION; # Check for "sec-agree" in the Proxy-Require header: if (is_present_hf("Feature-Caps")) { - # Remove the old Proxy-Require-Header: + # Remove the old Proxy-Require-Header: remove_hf("Feature-Caps"); append_hf("Feature-Caps: $hdr(Feature-Caps);+g.3gpp.trf=\"\"\r\n"); - } else { + } else { append_hf("Feature-Caps: *;+g.3gpp.trf=\"\"\r\n"); } -#!endif +#!endif # Add a visited Network-ID-Header: if (is_present_hf("P-Visited-Network-ID")) { $var(new_hdr) = "NETWORKNAME, "+$hdr(P-Visited-Network-ID); @@ -105,249 +103,213 @@ route[MO] t_on_reply("MO_reply"); } +#!ifdef WITH_N5 -################################# -## Route Logic for N5 Requests ## -################################# +# Route Logic for N5 Requests route[N5_INIT_REQ] { -## Storing IDs and IPs from UE into variables to use them later in the N5 Request: + # Storing IDs and IPs of UE into variables to use them later in the N5 Request + $var(orig_ue_ip) = $si; + $var(orig_ue_port) = $sp; + $var(pcscf_ip) = $Ri; + $var(pcscf_port) = $Rp; - - $var(orig_ue_ip) = $si; - $var(orig_ue_port) = $sp; - $var(pcscf_ip) = $Ri; - $var(pcscf_port) = $Rp; - -# now checking it on console if I got what I wanted : - xlog("L_INFO", "connection Info for UE $var(orig_ue_ip) $var(orig_ue_port)\n"); - xlog("L_INFO", "connection Info for P-CSCF is: $var(pcscf_ip) $var(pcscf_port)\n"); + xlog("L_INFO", "Connection Info for UE $var(orig_ue_ip) $var(orig_ue_port)\n"); + xlog("L_INFO", "Connection Info for P-CSCF is: $var(pcscf_ip) $var(pcscf_port)\n"); -# now trying some way to store IP of Orig UE - $var(user_id_req_ip) = $fU; # should get the user part of the Orig UE from request - - # Store the IP in the hash table associated with the UE - $sht(user_sip_ips=>$var(user_id_req_ip)) = $var(orig_ue_ip); - xlog("L_INFO", "IP Info for UE MSISDN $var(user_id_req_ip): $var(orig_ue_ip)\n"); - -# now trying some way to store Port of Orig UE - $var(user_id_req_port) = $fU; # should get the user part of the Orig UE from request - - # Store the Port in the hash table associated with the UE - $sht(user_sip_ports=>$var(user_id_req_port)) = $var(orig_ue_port); - xlog("L_INFO", "Port Info for UE MSISDN $var(user_id_req_port): $var(orig_ue_port)\n"); - -## now saving SDP Info from UE to variables to use them later in the N5 Flow Fdecs : + $var(user_id_req_ip) = $fU; + # Store the IP in the hash table associated with the UE + $sht(user_sip_ips=>$var(user_id_req_ip)) = $var(orig_ue_ip); + xlog("L_INFO", "IP Info for UE MSISDN $var(user_id_req_ip): $var(orig_ue_ip)\n"); -$var(sdp_src_ip) = $sdp(c:ip); -$var(sdp_src_port) = $sdp(m0:rtp:port); -$var(sdp_src_rtcp_port) = $sdp(m0:rtcp:port); -$var(sdp_mline_raw) = $sdp(m0:raw); + $var(user_id_req_port) = $fU; + # Store the Port in the hash table associated with the UE + $sht(user_sip_ports=>$var(user_id_req_port)) = $var(orig_ue_port); + xlog("L_INFO", "Port Info for UE MSISDN $var(user_id_req_port): $var(orig_ue_port)\n"); -xlog("L_INFO", "SDP Info : Connection IP is $var(sdp_src_ip) Port is $var(sdp_src_port) Mline dump $var(sdp_mline_raw) \n"); + # Storing SDP Info of UE to variables to use them later in the N5 Flow Fdecs + $var(sdp_src_ip) = $sdp(c:ip); + $var(sdp_src_port) = $sdp(m0:rtp:port); + $var(sdp_src_rtcp_port) = $sdp(m0:rtcp:port); + $var(sdp_mline_raw) = $sdp(m0:raw); -# now trying some way to store SDP SRC_IP of Orig UE - $var(user_id_sdp_ip) = $fU; # should get the user part of the Orig UE from request + xlog("L_INFO", "SDP Info : Connection IP is $var(sdp_src_ip) Port is $var(sdp_src_port) Mline dump $var(sdp_mline_raw) \n"); - # Store the AppSession in the hash table associated with the UE - $sht(user_sdps_ip=>$var(user_id_sdp_ip)) = $var(sdp_src_ip); - xlog("L_INFO", "SDP SRC_IP of Orig UE $var(user_id_sdp_ip): $var(sdp_src_ip)\n"); + $var(user_id_sdp_ip) = $fU; + # Store the SDP source IP in the hash table associated with the UE + $sht(user_sdps_ip=>$var(user_id_sdp_ip)) = $var(sdp_src_ip); + xlog("L_INFO", "SDP source IP of Orig UE $var(user_id_sdp_ip): $var(sdp_src_ip)\n"); -# now trying some way to store SDP Media_Port of Orig UE - $var(user_id_sdp_port) = $fU; # should get the user part of the Orig UE from request + $var(user_id_sdp_port) = $fU; + # Store the SDP Media_Port in the hash table associated with the UE + $sht(user_sdps_port=>$var(user_id_sdp_port)) = $var(sdp_src_port); + xlog("L_INFO", "SDP Media Port of Orig UE $var(user_id_sdp_port): $var(sdp_src_port)\n"); - # store SDP Media_Port in the hash table associated with the UE - $sht(user_sdps_port=>$var(user_id_sdp_port)) = $var(sdp_src_port); - xlog("L_INFO", "SDP Media_Port of Orig UE $var(user_id_sdp_port): $var(sdp_src_port)\n"); + $var(user_id_sdp_rtcp_port) = $fU; + # Store the RTCP Media Port in the hash table associated with the UE + $sht(user_sdps_rtcp_port=>$var(user_id_sdp_rtcp_port)) = $var(sdp_src_rtcp_port); + xlog("L_INFO", "SDP RTCP Media Port of Orig UE $var(user_id_sdp_rtcp_port): $var(sdp_src_rtcp_port)\n"); -# now trying some way to store SDP RTCP_Media_Port of Orig UE - $var(user_id_sdp_rtcp_port) = $fU; # should get the user part of the Orig UE from request + # 5G VoNR N5 NPCF Authorization request + xlog("L_DBG", "IMS: INVITE ORIG TO $tU\n"); - # Store the RTCP_Media_Port in the hash table associated with the UE - $sht(user_sdps_rtcp_port=>$var(user_id_sdp_rtcp_port)) = $var(sdp_src_rtcp_port); - xlog("L_INFO", "SDP RTCP_Media_Port of Orig UE $var(user_id_sdp_rtcp_port): $var(sdp_src_rtcp_port)\n"); + # Retrieve the IP/Port of UE + $var(orig_ue_ip) = $fU; + $var(ue_ip_addr) = $sht(user_sip_ips=>$var(orig_ue_ip)); + xlog("L_INFO", "IP for UE $var(orig_ue_ip) is: $var(ue_ip_addr)\n"); -#### 5G VoNR N5 NPCF Authorization reuqest + $var(orig_ue_port) = $fU; + $var(ue_port_sip) = $sht(user_sip_ports=>$var(orig_ue_port)); + xlog("L_INFO", "IP for UE $var(orig_ue_port) is: $var(ue_port_sip)\n"); - if(is_method("INVITE")){ - xlog("L_DBG", "IMS: INVITE ORIG TO $tU\n"); + # Retrieving SDP Connection Info and Media Port for UE + $var(sdp_id_ue) = $fU; + $var(ue_sdp_ip) = $sht(user_sdps_ip=>$var(sdp_id_ue)); + xlog("L_INFO", "SDP IP for UE with MSISDN $var(sdp_id_ue) is: $var(ue_sdp_ip)\n"); -### Getting the IP/Port of UE - $var(orig_ue_ip) = $fU; # User Part of the from Header to get the USER - $var(ue_ip_addr) = $sht(user_sip_ips=>$var(orig_ue_ip)); - xlog("L_INFO", "IP for UE $var(orig_ue_ip) is: $var(ue_ip_addr)\n"); - - $var(orig_ue_port) = $fU; # User Part of the from Header to get the USER - $var(ue_port_sip) = $sht(user_sip_ports=>$var(orig_ue_port)); - xlog("L_INFO", "IP for UE $var(orig_ue_port) is: $var(ue_port_sip)\n"); - -## retrieving SDP Connection Info and Media Port for UE - $var(sdp_id_ue) = $fU; # User Part of the from Header to get the USER - $var(ue_sdp_ip) = $sht(user_sdps_ip=>$var(sdp_id_ue)); - xlog("L_INFO", "SDP IP for UE with MSISDN $var(sdp_id_ue) is: $var(ue_sdp_ip)\n"); - - $var(sdp_id_ue_port) = $fU; # User Port of the from Header to get the USER - $var(ue_sdp_port) = $sht(user_sdps_port=>$var(sdp_id_ue_port)); - xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_port) is: $var(ue_sdp_port)\n"); + $var(sdp_id_ue_port) = $fU; + $var(ue_sdp_port) = $sht(user_sdps_port=>$var(sdp_id_ue_port)); + xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_port) is: $var(ue_sdp_port)\n"); - $var(sdp_id_ue_rtcp_port) = $fU; # User Port of the from Header to get the USER - $var(ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_id_ue_rtcp_port)); - xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_rtcp_port) is: $var(ue_sdp_rtcp_port)\n"); - + $var(sdp_id_ue_rtcp_port) = $fU; + $var(ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_id_ue_rtcp_port)); + xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_rtcp_port) is: $var(ue_sdp_rtcp_port)\n"); -#### now start to build the N5 Request + # Build the N5 Request + xlog("L_INFO","Preparing QoS N5 Message to PCF for the INVITE\n"); - xlog("L_INFO","Preparing QoS N5 Message to PCF for the INVITE\n"); - - xlog("L_INFO","Initialize empty arrays and objects\n"); - -### Initialize empty arrays and objects - $var(events) = '[]'; - $var(medComponents) = '{}'; - $var(medSubComps) = '{}'; - $var(evSubsc) = '{}'; - $var(payload) = '{}'; - -### Set afAppId and dnn in payload - jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); # adding a note that this could be improved in future to get the value SIP Header - jansson_set("string", "dnn", "ims", "$var(payload)"); - -### Set medComponents - jansson_set("integer", "medCompN", 1, "$var(medComp)"); - jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); - jansson_set("string", "medType", "AUDIO", "$var(medComp)"); - jansson_set("array", "codecs", "[\"downlink\\noffer\\n\", \"uplink\\nanswer\\n\"]", "$var(medComp)"); - - ### RTP - jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); - jansson_set("array", "fDescs", "[\"permit out 17 from any to $var(ue_sdp_ip) $var(ue_sdp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_port) to any\"]", "$var(medSubComp1)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); - jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); - - - ### RTCP - jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); - jansson_set("array", "fDescs", "[\"permit out 17 from any to $var(ue_sdp_ip) $var(ue_sdp_rtcp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_rtcp_port) to any\"]", "$var(medSubComp2)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp2)"); - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp2)"); - jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); - - # Merging the flows under MediaSubComponent - jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); - jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); - jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); - - jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); - jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); - - xlog("L_INFO","Set evSubsc\n"); - -### Set evSubsc - jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); - jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); - jansson_append("obj", "", "$var(event1)", "$var(events)"); - jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); - jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); - jansson_append("obj", "", "$var(event2)", "$var(events)"); - jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); - - jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); - -### Set other parameters in payload - jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); - jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); - jansson_set("string", "gpsi", "msisdn-$fU", "$var(payload)"); - jansson_set("string", "suppFeat", "4", "$var(payload)"); - jansson_set("string", "ueIpv4", "$var(ue_ip_addr)", "$var(payload)"); - - ### Assemble the final JSON request - jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + $var(events) = '[]'; + $var(medComponents) = '{}'; + $var(medSubComps) = '{}'; + $var(evSubsc) = '{}'; + $var(payload) = '{}'; - xlog("L_INFO", "Set headers for the HTTP2 Request\n"); -### Set headers - $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); - xlog("L_INFO", "Today is $var(time_now)\n"); - - $var(headers) = "Content-Type: application/json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + # Set afAppId and dnn in payload + jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); # adding a note that this could be improved in future to get the value SIP Header + jansson_set("string", "dnn", "ims", "$var(payload)"); - - xlog("L_INFO","Sending the request to PCF\n"); -### Send the request to PCF - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$var(json_request)", "$var(headers)", "$var(result)" ); + # Set medComponents + jansson_set("integer", "medCompN", 1, "$var(medComp)"); + jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); + jansson_set("string", "medType", "AUDIO", "$var(medComp)"); + jansson_set("array", "codecs", "[\"downlink\\noffer\\n\", \"uplink\\nanswer\\n\"]", "$var(medComp)"); -### here we want to kill the dialog in case QoS faild or continue if QoS success. - switch ($rc) { + # RTP + jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); + jansson_set("array", "fDescs", "[\"permit out 17 from any to $var(ue_sdp_ip) $var(ue_sdp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_port) to any\"]", "$var(medSubComp1)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); + + + # RTCP + jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); + jansson_set("array", "fDescs", "[\"permit out 17 from any to $var(ue_sdp_ip) $var(ue_sdp_rtcp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_rtcp_port) to any\"]", "$var(medSubComp2)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); + + # Merging the flows under MediaSubComponent + jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); + jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); + jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); + + jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); + jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); + + xlog("L_INFO","Set evSubsc\n"); + + # Set evSubsc + jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); + jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); + jansson_append("obj", "", "$var(event1)", "$var(events)"); + jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); + jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); + jansson_append("obj", "", "$var(event2)", "$var(events)"); + jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); + + jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); + + # Set other parameters in payload + jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); + jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); + jansson_set("string", "gpsi", "msisdn-$fU", "$var(payload)"); + jansson_set("string", "suppFeat", "4", "$var(payload)"); + jansson_set("string", "ueIpv4", "$var(ue_ip_addr)", "$var(payload)"); + + # Assemble the final JSON request + jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + + xlog("L_INFO", "Set headers for the HTTP2 Request\n"); + # Set headers + $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); + xlog("L_INFO", "Today is $var(time_now)\n"); + + $var(headers) = "Content-Type: application/json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + + xlog("L_INFO","Sending the request to PCF\n"); + # Send the request to PCF + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$var(json_request)", "$var(headers)", "$var(result)"); + + switch ($rc) { + # Success case case 201: - xlog("L_INFO", "N5 QoS Session successfully Created $rc\n"); - xlog("L_INFO", "HTTP results: $var(result)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - xlog("L_INFO", "Location Header: $httprhdr(location)\n"); + xlog("L_INFO", "N5 QoS Session successfully Created $rc\n"); + xlog("L_INFO", "HTTP results: $var(result)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); + xlog("L_INFO", "Location Header: $httprhdr(location)\n"); -# Now I will retrieve the AppSessionID out of the location Header it should be always at the end -# Example URL: "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/(someSessionID)" - -# Firt store the url of the lcoation Header in var - $var(url) = $httprhdr(location); - - # Get the length of the URL - $var(len) = $(var(url){s.len}); - - # Initialize the position variable to the length of the URL - $var(pos) = $var(len); - - # Find the position of the last slash by iterating backwards - while ($var(pos) > 0) { - $var(pos) = $var(pos) - 1; - if ($(var(url){s.substr,$var(pos),1}) == "/") { - # We've found the last slash - break; - } - } - -# Extract the substring after the last slash -# now doing some magic -# Set the starting position after the last slash - $var(start_pos) = $var(pos) + 1; + # Retrieve the AppSession Id out of the location header in response + # Example URL: "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/(someSessionID)" - # Calculate the length of the substring after the last slash - $var(substring_length) = $var(len) - $var(start_pos); + # Store the url of the lcoation Header in var + $var(url) = $httprhdr(location); + # Get the length of the URL + $var(len) = $(var(url){s.len}); + # Initialize the position variable to the length of the URL + $var(pos) = $var(len); - # Extract the substring after the last slash - $var(app_session) = $(var(url){s.substr,$var(start_pos),$var(substring_length)}); + # Find the position of the last slash by iterating backwards + while ($var(pos) > 0) { + $var(pos) = $var(pos) - 1; + if ($(var(url){s.substr,$var(pos),1}) == "/") { + break; + } + } - -# now checking it on console if I got what I wanted : - xlog("L_INFO", "AppSession for user $fU is: $var(app_session)\n"); + # Extract the substring after the last slash + # Set the starting position after the last slash + $var(start_pos) = $var(pos) + 1; + # Calculate the length of the substring after the last slash + $var(substring_length) = $var(len) - $var(start_pos); + # Extract the substring after the last slash + $var(app_session) = $(var(url){s.substr,$var(start_pos),$var(substring_length)}); -# now trying some way to store AppSession with the registred UE - $var(user_id) = $fU; # should get the user part of the Orig UE + xlog("L_INFO", "AppSession Id for user $fU is: $var(app_session)\n"); - # Store the AppSession in the hash table associated with the UE - $sht(user_data=>$var(user_id)) = $var(app_session); - xlog("L_INFO", "Stored AppSession for user $var(user_id): $var(app_session)\n"); - break; - default: - xlog("L_ERR", "N5 QoS Session faild - Reason code: $rc\n"); - send_reply("412", "MOC N5 QoS Session Creation faild"); - exit; - } # switch ends here + $var(user_id) = $fU; + # Store the AppSession Id in the hash table associated with the UE + $sht(user_data=>$var(user_id)) = $var(app_session); + xlog("L_INFO", "Stored AppSession Id for user $var(user_id): $var(app_session)\n"); + break; + # Failure case + default: + xlog("L_ERR", "N5 QoS authorization failed - Reason code: $rc\n"); + send_reply("412", "Register N5 QoS authorization failed"); + exit; + } } -} - -##################################### -##### END OF N5 VoNR Request logic ## -##################################### +#!endif ###################################################################### # Replies to Originating Initial Requests @@ -355,58 +317,52 @@ xlog("L_INFO", "SDP Info : Connection IP is $var(sdp_src_ip) Port is $var(sdp_sr onreply_route[MO_reply] { xnotice("PCSCF MO_reply: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); if (is_present_hf("C-Params")) { remove_hf("Contact"); - remove_hf("C-Params"); + remove_hf("C-Params"); append_hf("Contact: $ct;$hdr(C-Params)\r\n"); } - -## N5 PATCH Request - - if (t_check_status("180|183|200") && has_body("application/sdp")){ - xlog("L_INFO", "received early answer in 18x, Patching N5 session in PCF...\n"); - xlog("L_INFO", "N5 PATCH: About to test if this is a retransmitted reply which is still currently suspended\n"); - if (t_is_retr_async_reply()) { - xlog("L_INFO", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } - route(N5_PATCH_REQ); - } + +#!ifdef WITH_N5 + # N5 PATCH Request for updating AppSession context + if (t_check_status("180|183|200") && has_body("application/sdp")) { + xlog("L_INFO", "Received early answer in 18x. Patching N5 session in PCF\n"); + if (t_is_retr_async_reply()) { + xlog("L_INFO", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } + route(N5_PATCH_REQ); + } -## Terminating N5 AppSession after BYE## + # Terminating N5 AppSession after BYE + if (is_method("BYE|CANCEL") || status=~"[45][0-9][0-9]") { + xlog("L_ALERT", "Terminating AppSession for Call fom User $fU due to call END or Call Failed\n"); + # Retrieve the AppSession Id from the hash table + $var(user_id_midcall_rel) = $fU; + $var(user_appsess_midcall_rel) = $sht(user_data=>$var(user_id_midcall_rel)); + xlog("L_INFO", "Terminating stored AppSession for user $var(user_id_midcall_rel): $var(user_appsess_midcall_rel)\n"); - if(is_method("BYE|CANCEL") || status=~"[45][0-9][0-9]"){ - - xlog("L_ALERT", "Terminating AppSession For Call fom User $fU due to call END or Call Faild\n"); - # Retrieveing - $var(user_id_midcall_rel) = $fU; # User Part of the from Header to get the USER - $var(user_appsess_midcall_rel) = $sht(user_data=>$var(user_id_midcall_rel)); - xlog("L_INFO", "Terminating Stored AppSession for user $var(user_id_midcall_rel): $var(user_appsess_midcall_rel)\n"); - - $var(headers) = "X-SIP-Status: De-Registration\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); - - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_midcall_rel)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); - xlog("L_INFO", "Termination resuts: $var(result)\n"); - xlog("L_INFO", "response header: $curlerror(error)\n"); - xlog("L_INFO", "response header: $var(response_code)\n"); - xlog("L_INFO", "response header: $httprhdr(location)\n"); - xlog("L_INFO", "response header: $rc\n"); + $var(headers) = "X-SIP-Status: De-Registration\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_midcall_rel)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); + xlog("L_INFO", "Termination resuts: $var(result)\n"); + xlog("L_INFO", "response header: $curlerror(error)\n"); + xlog("L_INFO", "response header: $var(response_code)\n"); + xlog("L_INFO", "response header: $httprhdr(location)\n"); + xlog("L_INFO", "response header: $rc\n"); + } +#!endif - } - - - #!ifdef WITH_IPSEC ipsec_forward("location", IPSEC_FORWARD_FLAGS); #!endif @@ -415,45 +371,42 @@ onreply_route[MO_reply] { route(NATMANAGE); #!ifdef WITH_RX - if (t_check_status("183|200") && has_body("application/sdp")){ + if (t_check_status("183|200") && has_body("application/sdp")) { xlog("L_DBG", "IMS: Received 183/200 inside orig_initial_reply\n"); if (t_is_retr_async_reply()) { - xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } + xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } - xlog("L_DBG","Diameter: Orig authorizing media via Rx\n"); + xlog("L_DBG","Diameter: Orig authorizing media via Rx\n"); $avp(FTAG_CUSTOM_AVP)=$ft; $avp(TTAG_CUSTOM_AVP)=$tt; $avp(CALLID_CUSTOM_AVP)=$ci; - if (Rx_AAR("MO_aar_reply","orig","",-1) == 0) { - exit; - } + if (Rx_AAR("MO_aar_reply","orig","",-1) == 0) { + exit; + } } - -## - } route[MO_aar_reply] { - #this is async so to know status we have to check the reply avp + # Check reply AVP since the operation is async switch ($avp(s:aar_return_code)) { case 1: - xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); + xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); break; default: xlog("L_ERR", "IMS: AAR failed Orig\n"); - xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); - #comment this if you want to allow even if Rx fails - if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ - dlg_terminate("all", "Sorry no QoS available"); - exit; - } + xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); + # Comment this if you want to allow even if Rx fails + if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ + dlg_terminate("all", "Sorry no QoS available"); + exit; + } } #!endif } @@ -463,45 +416,42 @@ route[MO_aar_reply] ###################################################################### route[MO_indialog] { -## N5 PATCH Request - - if(is_method("INVITE")){ - xlog("L_INFO"," InDialog SDP Answer N5 Request for reINVITE\n"); - route(N5_PATCH_REQ); - } +#!ifdef WITH_N5 + # N5 PATCH Request for updating AppSession context + if (is_method("INVITE")) { + xlog("L_INFO"," InDialog SDP Answer N5 Request for reINVITE\n"); + route(N5_PATCH_REQ); + } -## Terminating N5 AppSession after BYE## + # Terminating N5 AppSession after BYE + if (is_method("BYE|CANCEL")) { + xlog("L_ALERT","Terminating AppSession for Call from User $fU due to call END or Call Failed\n"); + # Retrieve the AppSession Id from the hash table + $var(user_id_call_rel) = $fU; + $var(user_appsess_call_rel) = $sht(user_data=>$var(user_id_call_rel)); + xlog("L_INFO", "Terminating stored AppSession for user $var(user_id_call_rel): $var(user_id_call_rel)\n"); - if(is_method("BYE|CANCEL")) - { - xlog("L_ALERT","Terminating AppSession For Call for User $fU due to call END or Call Faild\n"); - # Retrieveing - $var(user_id_call_rel) = $fU; # User Part of the from Header to get the USER - $var(user_appsess_call_rel) = $sht(user_data=>$var(user_id_call_rel)); - xlog("L_INFO", "Terminating Stored AppSession for user $var(user_id_call_rel): $var(user_id_call_rel)\n"); - - $var(headers) = "X-SIP-Status: De-Registration\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); - - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_call_rel)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); - xlog("L_INFO", "Termination resuls: $var(result)\n"); - xlog("L_INFO", "response header: $curlerror(error)\n"); - xlog("L_INFO", "response header: $var(response_code)\n"); - xlog("L_INFO", "response header: $httprhdr(location)\n"); - xlog("L_INFO", "response header: $rc\n"); - - } + $var(headers) = "X-SIP-Status: De-Registration\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_call_rel)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); + xlog("L_INFO", "Termination resuls: $var(result)\n"); + xlog("L_INFO", "response header: $curlerror(error)\n"); + xlog("L_INFO", "response header: $var(response_code)\n"); + xlog("L_INFO", "response header: $httprhdr(location)\n"); + xlog("L_INFO", "response header: $rc\n"); + } +#!endif xnotice("PCSCF MO_indialog: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); setflag(FLT_MOBILE_ORIG); t_on_reply("MO_indialog_reply"); @@ -512,7 +462,7 @@ route[MO_indialog] { #!ifdef WITH_IPSEC if ($dd != "" && $rd != "" && $fs != "") { - if ($rd =~ ".*" + $dd + ".*") { + if ($rd =~ ".*" + $dd + ".*") { ipsec_forward("location", IPSEC_FORWARD_FLAGS); } } @@ -521,25 +471,22 @@ route[MO_indialog] { onreply_route[MO_indialog_reply] { xnotice("PCSCF MO_indialog_reply: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); + +#!ifdef WITH_N5 + # N5 PATCH Request for updating AppSession context + if (t_check_status("180|183|200") && has_body("application/sdp")) { + xlog("L_DBG", "Received early answer in 18x. Patching N5 session in PCF\n"); + if (t_is_retr_async_reply()) { + xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } + route(N5_PATCH_REQ); + } +#!endif -## - -## N5 PATCH Request - - if (t_check_status("180|183|200") && has_body("application/sdp")){ - xlog("L_DBG", "received early answer in 18x, Patching N5 session in PCF...\n"); - xlog("L_DBG", "N5 PATCH: About to test if this is a retransmitted reply which is still currently suspended\n"); - if (t_is_retr_async_reply()) { - xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } - route(N5_PATCH_REQ); - } - - # In case of 1xx and 2xx do NAT if(status=~"[12][0-9][0-9]") route(NATMANAGE); @@ -547,191 +494,178 @@ onreply_route[MO_indialog_reply] { #!ifdef WITH_RX if (t_check_status("183|200") && has_body("application/sdp") && !is_method("PRACK")) { if (t_is_retr_async_reply()) { - xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } + xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } - xlog("L_DBG", "IMS: ORIG_SUBSEQUENT reply. This is a 200 OK to a re-INVITE\n"); - xlog("L_DBG","Diameter: Orig authorizing media via Rx\n"); + xlog("L_DBG", "IMS: ORIG_SUBSEQUENT reply. This is a 200 OK to a re-INVITE\n"); + xlog("L_DBG","Diameter: Orig authorizing media via Rx\n"); $avp(FTAG_CUSTOM_AVP)=$ft; $avp(TTAG_CUSTOM_AVP)=$tt; $avp(CALLID_CUSTOM_AVP)=$ci; if (Rx_AAR("MO_indialog_aar_reply","orig","",-1) == 0) { - exit; - } + exit; + } } } route[MO_indialog_aar_reply] { - #this is async so to know status we have to check the reply avp + # Check reply AVP since the operation is async switch ($avp(s:aar_return_code)) { - case 1: - xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); - break; - default: - xlog("L_ERR", "IMS: AAR failed Orig\n"); - xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); - #comment this if you want to allow even if Rx fails - if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ - dlg_terminate("all", "Sorry no QoS available"); - exit; - } - } + case 1: + xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); + break; + default: + xlog("L_ERR", "IMS: AAR failed Orig\n"); + xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); + # Comment this if you want to allow even if Rx fails + if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ + dlg_terminate("all", "Sorry no QoS available"); + exit; + } + } #!endif } -################################################### -#### 5G VoNR N5 NPCF Authorization PATCH reuqest ## -################################################### + +#!ifdef WITH_N5 + +# 5G VoNR N5 Policy Authorization PATCH request route[N5_PATCH_REQ] { - - - xlog("L_INFO", "IMS: Received 183/200 inside orig_initial_reply\n"); + xlog("L_INFO", "IMS: Received 183/200 inside orig_initial_reply\n"); - -### Getting the IP/Port of UE - $var(orig_id_ue_ip) = $fU; # User Part of the from Header to get the USER - $var(ue_sip_ip_addr) = $sht(user_sip_ips=>$var(orig_id_ue_ip)); - xlog("L_INFO", "IP for UE $var(orig_id_ue_ip) is: $var(ue_sip_ip_addr)\n"); - - $var(orig_ue_port) = $fU; # User Part of the from Header to get the USER - $var(ue_port_sip) = $sht(user_sip_ports=>$var(orig_ue_port)); - xlog("L_INFO", "IP for UE $var(orig_ue_port) is: $var(ue_port_sip)\n"); - -## retrieving SDP Connection Info and Media Port for UE - $var(sdp_id_ue) = $fU; # User Part of the from Header to get the USER - $var(ue_sdp_ip) = $sht(user_sdps_ip=>$var(sdp_id_ue)); - xlog("L_INFO", "SDP IP for UE with MSISDN $var(sdp_id_ue) is: $var(ue_sdp_ip)\n"); + # Retrieve the IP/Port of UE + $var(orig_id_ue_ip) = $fU; + $var(ue_sip_ip_addr) = $sht(user_sip_ips=>$var(orig_id_ue_ip)); + xlog("L_INFO", "IP for UE $var(orig_id_ue_ip) is: $var(ue_sip_ip_addr)\n"); - $var(sdp_id_ue_port) = $fU; # User Port of the from Header to get the USER - $var(ue_sdp_port) = $sht(user_sdps_port=>$var(sdp_id_ue_port)); - xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_port) is: $var(ue_sdp_port)\n"); + $var(orig_ue_port) = $fU; + $var(ue_port_sip) = $sht(user_sip_ports=>$var(orig_ue_port)); + xlog("L_INFO", "IP for UE $var(orig_ue_port) is: $var(ue_port_sip)\n"); + + # Retrieve SDP Connection Info and Media Port for UE + $var(sdp_id_ue) = $fU; + $var(ue_sdp_ip) = $sht(user_sdps_ip=>$var(sdp_id_ue)); + xlog("L_INFO", "SDP IP for UE with MSISDN $var(sdp_id_ue) is: $var(ue_sdp_ip)\n"); + + $var(sdp_id_ue_port) = $fU; + $var(ue_sdp_port) = $sht(user_sdps_port=>$var(sdp_id_ue_port)); + xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_port) is: $var(ue_sdp_port)\n"); + + $var(sdp_id_ue_rtcp_port) = $fU; + $var(ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_id_ue_rtcp_port)); + xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_rtcp_port) is: $var(ue_sdp_rtcp_port)\n"); + + # Retrieve SDP Connection Info from SDP Answer + $var(sdp_answ_ip) = $sdp(c:ip); + $var(sdp_answ_port) = $sdp(m0:rtp:port); + $var(sdp_answ_rtcp_port) = $sdp(m0:rtcp:port); + $var(sdp_answ_codec) = $(rb{line.sw,a=rtpmap}{s.select,1, }); + xlog("L_INFO", "SDP Answer connection Info is: $var(sdp_answ_ip), RTP port $var(sdp_answ_port), RTCP Port $var(sdp_answ_rtcp_port) and codec is $var(sdp_answ_codec)\n"); + + # Retrieve AppSession Id + $var(user_id_inv_rep) = $fU; + $var(user_appsess_inv_rep) = $sht(user_data=>$var(user_id_inv_rep)); + xlog("L_INFO", "Stored AppSession Id for user $var(user_id_inv_rep): $var(user_appsess_inv_rep)\n"); + + xlog("L_INFO","Preparing PATCH N5 Message for SDP Answer\n"); + + $var(events) = '[]'; + $var(medComponents) = '{}'; + $var(medSubComps) = '{}'; + $var(evSubsc) = '{}'; + $var(payload) = '{}'; + + # Set afAppId and dnn in payload + jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); + jansson_set("string", "dnn", "ims", "$var(payload)"); + + # Set media components + jansson_set("integer", "medCompN", 1, "$var(medComp)"); + jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); + jansson_set("string", "medType", "AUDIO", "$var(medComp)"); + jansson_set("array", "codecs", "[\"downlink\\n$var(sdp_answ_codec)\\n\", \"uplink\\n$var(sdp_answ_codec)\\n\"]", "$var(medComp)"); + + # RTP + jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); + jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_answ_ip) $var(sdp_answ_port) to $var(ue_sdp_ip) $var(ue_sdp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_port) to $var(sdp_answ_ip) $var(sdp_answ_port)\"]", "$var(medSubComp1)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); - $var(sdp_id_ue_rtcp_port) = $fU; # User Port of the from Header to get the USER - $var(ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_id_ue_rtcp_port)); - xlog("L_INFO", "SDP Port for UE with MSISDN $var(sdp_id_ue_rtcp_port) is: $var(ue_sdp_rtcp_port)\n"); - -## retrieving SDP Connection Info from SDP Answer - $var(sdp_answ_ip) = $sdp(c:ip); - $var(sdp_answ_port) = $sdp(m0:rtp:port); - $var(sdp_answ_rtcp_port) = $sdp(m0:rtcp:port); - $var(sdp_answ_codec) = $(rb{line.sw,a=rtpmap}{s.select,1, }); - xlog("L_INFO", "SDP Answer connection Info is: $var(sdp_answ_ip), RTP port $var(sdp_answ_port), RTCP Port $var(sdp_answ_rtcp_port) and codec is $var(sdp_answ_codec)\n"); - -## Retrieveing AppSession from initial INVITE N5 Request - $var(user_id_inv_rep) = $fU; # User Part of the from Header to get the USER - $var(user_appsess_inv_rep) = $sht(user_data=>$var(user_id_inv_rep)); - xlog("L_INFO", "Terminating Stored AppSession for user $var(user_id_inv_rep): $var(user_appsess_inv_rep)\n"); + # RTCP + jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); + jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_answ_ip) $var(sdp_answ_rtcp_port) to $var(ue_sdp_ip) $var(ue_sdp_rtcp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_rtcp_port) to $var(sdp_answ_ip) $var(sdp_answ_rtcp_port)\"]", "$var(medSubComp2)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); -#### now start to build the N5 Request + # Merging the flows under MediaSubComponent + jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); + jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); + jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); - xlog("L_INFO","Preparing PATCH N5 Message for SDP Answer\n"); - - xlog("L_INFO","Initialize empty arrays and objects\n"); - -### Initialize empty arrays and objects - $var(events) = '[]'; - $var(medComponents) = '{}'; - $var(medSubComps) = '{}'; - $var(evSubsc) = '{}'; - $var(payload) = '{}'; - -### Set afAppId and dnn in payload - jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); - jansson_set("string", "dnn", "ims", "$var(payload)"); - -### Set medComponents - jansson_set("integer", "medCompN", 1, "$var(medComp)"); - jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "medType", "AUDIO", "$var(medComp)"); - jansson_set("array", "codecs", "[\"downlink\\n$var(sdp_answ_codec)\\n\", \"uplink\\n$var(sdp_answ_codec)\\n\"]", "$var(medComp)"); - - ### RTP - jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); - jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_answ_ip) $var(sdp_answ_port) to $var(ue_sdp_ip) $var(ue_sdp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_port) to $var(sdp_answ_ip) $var(sdp_answ_port)\"]", "$var(medSubComp1)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); # commented out BW accourding to Open5GC code if they are not there they will be taken from WEBGUI, could be reenabled if needed - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); # commented out BW accourding to Open5GC code if they are not there they will be taken from WEBGUI, could be reenabled if needed - jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); - - - ### RTCP - jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); - jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_answ_ip) $var(sdp_answ_rtcp_port) to $var(ue_sdp_ip) $var(ue_sdp_rtcp_port)\", \"permit in 17 from $var(ue_sdp_ip) $var(ue_sdp_rtcp_port) to $var(sdp_answ_ip) $var(sdp_answ_rtcp_port)\"]", "$var(medSubComp2)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp2)"); # commented out BW accourding to Open5GC code if they are not there they will be taken from WEBGUI, could be reenabled if needed - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp2)"); # commented out BW accourding to Open5GC code if they are not there they will be taken from WEBGUI, could be reenabled if needed - jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); - - # Merging the flows under MediaSubComponent - jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); - jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); - jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); - - jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); - jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); - - xlog("L_INFO","DEBUG: Set evSubsc\n"); - -### Set evSubsc - jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); - jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); - jansson_append("obj", "", "$var(event1)", "$var(events)"); - jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); - jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); - jansson_append("obj", "", "$var(event2)", "$var(events)"); - jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); - - jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); - -### Set other parameters in payload - jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); - jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "gpsi", "msisdn-$fU", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "suppFeat", "4", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "ueIpv4", "$var(ue_sip_ip_addr)", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - - ### Assemble the final JSON request - jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); + jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); - xlog("L_INFO","Set headers for the HTTP2 Request\n"); -### Set headers - $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); - xlog("L_INFO", "Today is $var(time_now)\n"); - - $var(headers) = "Content-Type: application/merge-patch+json\r\n"; # added content-type an set it to "application/merge-patch+json" fo compatibility with RFC7386 for JSON PATCH/Merge - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + xlog("L_INFO","DEBUG: Set evSubsc\n"); - - xlog("L_INFO","Sending the request to PCF\n"); -### Send the request to PCF - http_client_request_v2pk("PATCH", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_inv_rep)", "$var(json_request)", "$var(headers)", "$var(result)" ); -#### here we want to kill the dialog in case QoS faild or contiue if QoS success, who knows ;( but this will help where we could have instability on RAN causing mutiple dead contacts with only one working causing INVITE Forks to dead contacts leading to 404 from PCF - switch ($rc) { + # Set evSubsc + jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); + jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); + jansson_append("obj", "", "$var(event1)", "$var(events)"); + jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); + jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); + jansson_append("obj", "", "$var(event2)", "$var(events)"); + jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); + + jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); + + # Set other parameters in payload + jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); + jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); + jansson_set("string", "gpsi", "msisdn-$fU", "$var(payload)"); + jansson_set("string", "suppFeat", "4", "$var(payload)"); + jansson_set("string", "ueIpv4", "$var(ue_sip_ip_addr)", "$var(payload)"); + + # Assemble the final JSON request + jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + + xlog("L_INFO","Set headers for the HTTP2 Request\n"); + # Set headers + $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); + xlog("L_INFO", "Today is $var(time_now)\n"); + + # Set Content-type to application/merge-patch+json for compatibility with RFC7386 for JSON PATCH/Merge + $var(headers) = "Content-Type: application/merge-patch+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + + xlog("L_INFO","Sending the request to PCF\n"); + # Send the request to PCF + http_client_request_v2pk("PATCH", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_inv_rep)", "$var(json_request)", "$var(headers)", "$var(result)" ); + switch ($rc) { case 200: - xlog("L_INFO", "N5 QoS Session modification success - reason code: $rc\n"); - xlog("L_INFO", "HTTP results: $var(result)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - xlog("L_INFO", "cURL Response: $curlerror(error)\n"); - xlog("L_INFO", "Location Header header: $httprhdr(location)\n"); - break; + xlog("L_INFO", "N5 QoS Session modification success - reason code: $rc\n"); + xlog("L_INFO", "HTTP results: $var(result)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); + xlog("L_INFO", "cURL Response: $curlerror(error)\n"); + xlog("L_INFO", "Location Header header: $httprhdr(location)\n"); + break; default: xlog("L_ERR", "N5 QoS Session modification faild - reason code: $rc\n"); send_reply("412", "MOC N5 QoS Session modify faild"); - exit; - } # switch ends here - + exit; + } } - -######################################## -######### END of 5G VoNR N5 Request #### -######################################## +#!endif diff --git a/pcscf/route/mt.cfg b/pcscf/route/mt.cfg index 4ee7109..74b2d5d 100644 --- a/pcscf/route/mt.cfg +++ b/pcscf/route/mt.cfg @@ -2,22 +2,22 @@ # Terminating, Initial requests ###################################################################### route[MT] { - xnotice("PCSCF MT: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); - xnotice("Term UE connection information : IP is $dd and Port is $rp \n"); - xnotice("Term P-CSCF connection information : IP is $RAi and Port is $RAp \n"); - set_dlg_profile("term"); - -#Route N5 Request -# - if(is_method("INVITE")) { - route(N5_INIT_MT_REQ); - } - + xnotice("PCSCF MT: \n Destination URI: $du\n Request URI: $ru\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); + xnotice("Term UE connection information : IP is $dd and Port is $rp \n"); + xnotice("Term P-CSCF connection information : IP is $RAi and Port is $RAp \n"); + set_dlg_profile("term"); + +#!ifdef WITH_N5 + if(is_method("INVITE")) { + route(N5_INIT_MT_REQ); + } +#!endif + #!ifdef WITH_IPSEC - ipsec_forward("location", IPSEC_FORWARD_FLAGS); + ipsec_forward("location", IPSEC_FORWARD_FLAGS); #!endif t_on_reply("MT_reply"); } @@ -26,10 +26,10 @@ route[MT] { # Replies to Originating Initial Requests ###################################################################### onreply_route[MT_reply] { - xnotice("PCSCF MT_reply: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); + xnotice("PCSCF MT_reply: \n Destination URI: $du\n Request URI: $ru\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); if (!strempty($(ct{tobody.params}))) { append_hf("C-Params: $(ct{tobody.params})\r\n"); } @@ -37,73 +37,69 @@ onreply_route[MT_reply] { # In case of 1xx and 2xx do NAT if(status=~"[12][0-9][0-9]") route(NATMANAGE); - -### N5 PATCH Request - if (t_check_status("180|183|200") && has_body("application/sdp")){ - xlog("L_INFO", "received early answer in 18x, Patching N5 session in PCF...\n"); - xlog("L_INFO", "N5 PATCH: About to test if this is a retransmitted reply which is still currently suspended\n"); - if (t_is_retr_async_reply()) { - xlog("L_INFO", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } - route(N5_PATCH_MT_REQ); - } - -## terminate QoS Session after Error response - - if(status=~"[45][0-9][0-9]") - { - xnotice("Received Error response ON the Call, going to terminate N5 Session\n"); - route(N5_MTC_TERM); - } - - -#!ifdef WITH_RX - if (t_check_status("183|200") && has_body("application/sdp")){ - xnotice("PCSCF MT_reply: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); - xlog("L_DBG", "IMS: Received 183 inside term_initial_reply\n"); - - xlog("L_DBG", "About to test if this is a retransmitted reply which is still currently suspended\n"); +#!ifdef WITH_N5 + # N5 PATCH Request for updating AppSession context + if (t_check_status("180|183|200") && has_body("application/sdp")) { + xlog("L_INFO", "Received early answer in 18x. Patching N5 session in PCF\n"); if (t_is_retr_async_reply()) { - xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } + xlog("L_INFO", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } + route(N5_PATCH_MT_REQ); + } - xlog("L_DBG","Diameter: Term authorizing media via Rx\n"); + # Terminating N5 AppSession after error response + if (status=~"[45][0-9][0-9]") { + xnotice("Received Error response for the Call. Going to terminate N5 Session\n"); + route(N5_MTC_TERM); + } +#!endif + +#!ifdef WITH_RX + if (t_check_status("183|200") && has_body("application/sdp")){ + xnotice("PCSCF MT_reply: \n Destination URI: $du\n Request URI: $ru\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); + xlog("L_DBG", "IMS: Received 183 inside term_initial_reply\n"); + + if (t_is_retr_async_reply()) { + xlog("L_DBG", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } + + xlog("L_DBG","Diameter: Term authorizing media via Rx\n"); $avp(FTAG_CUSTOM_AVP)=$ft; $avp(TTAG_CUSTOM_AVP)=$tt; $avp(CALLID_CUSTOM_AVP)=$ci; - if (Rx_AAR("MT_aar_reply","term","",-1) == 0) { - exit; - } + if (Rx_AAR("MT_aar_reply","term","",-1) == 0) { + exit; + } } } route[MT_aar_reply] { - xlog("L_DBG", "IMS: TERM_SESSION_AAR_REPLY\n"); + xlog("L_DBG", "IMS: TERM_SESSION_AAR_REPLY\n"); - #this is async so to know status we have to check the reply avp + # Check reply AVP since the operation is async switch ($avp(s:aar_return_code)) { - case 1: - xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); - break; - default: - xlog("L_ERR", "IMS: AAR failed Orig\n"); - xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); - #comment this if you want to allow even if Rx fails - if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ - dlg_terminate("all", "Sorry no QoS available"); - exit; - } - } + case 1: + xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); + break; + default: + xlog("L_ERR", "IMS: AAR failed Orig\n"); + xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); + # Comment this if you want to allow even if Rx fails + if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ + dlg_terminate("all", "Sorry no QoS available"); + exit; + } + } #!endif } @@ -113,63 +109,59 @@ route[MT_aar_reply] ###################################################################### route[MT_indialog] { -## N5 PATCH Request - - if(is_method("INVITE")){ - xlog("L_INFO"," InDialog SDP Change, sending N5 Request for it\n"); - route(N5_PATCH_REQ); - } +#!ifdef WITH_N5 + # N5 PATCH Request for updating AppSession context + if (is_method("INVITE")) { + xlog("L_INFO"," InDialog SDP Change. Sending N5 Request to update appSession context\n"); + route(N5_PATCH_REQ); + } -## Terminating N5 AppSession after BYE## + # Terminating N5 AppSession after BYE + if (is_method("BYE|CANCEL")) { + xlog("L_INFO"," InDialog Call End/Cancel/Error. Terminating N5 QoS Session\n"); + route(N5_MTC_TERM); + } +#!endif - if(is_method("BYE|CANCEL")) - { - xlog("L_INFO"," InDialog Call End/Cancel/Error, terminating N5 QoS Session ...\n"); - route(N5_MTC_TERM); - } - -#### END of N5 Request - - - xnotice("PCSCF MT_indialog: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); - #resetflag(FLT_MOBILE_ORIG); + xnotice("PCSCF MT_indialog: \n Destination URI: $du\n Request URI: $ru\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); + #resetflag(FLT_MOBILE_ORIG); t_on_reply("MT_indialog_reply"); - # Append rport only if its a request coming from UE + # Append rport only if its a request coming from UE if (is_request() && ($hdrc(Via) == 1)) { force_rport(); } #!ifdef WITH_IPSEC - if ($dd != "" && $rd != "" && $fs != "") { - if ($rd =~ ".*" + $dd + ".*") { - ipsec_forward("location", IPSEC_FORWARD_FLAGS); - } - } + if ($dd != "" && $rd != "" && $fs != "") { + if ($rd =~ ".*" + $dd + ".*") { + ipsec_forward("location", IPSEC_FORWARD_FLAGS); + } + } #!endif } onreply_route[MT_indialog_reply] { - xnotice("PCSCF MT_indialog_reply: \n Destination URI: $du\n Request URI: $ru\n"); - xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); - xnotice("Received IP and Port: ($Ri:$Rp)\n"); - xnotice("Contact header: $ct\n"); - -### N5 PATCH Request for Indialog reply + xnotice("PCSCF MT_indialog_reply: \n Destination URI: $du\n Request URI: $ru\n"); + xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); + xnotice("Received IP and Port: ($Ri:$Rp)\n"); + xnotice("Contact header: $ct\n"); + +#!ifdef WITH_N5 + # N5 PATCH Request for updating AppSession context for Indialog reply + if (t_check_status("180|183|200") && has_body("application/sdp")){ + xlog("L_INFO", "Received MT_indialog_reply. Patching N5 session in PCF\n"); + if (t_is_retr_async_reply()) { + xlog("L_INFO", "Dropping retransmitted reply which is still currently suspended\n"); + drop(); + } + route(N5_PATCH_MT_REQ); + } +#!endif - if (t_check_status("180|183|200") && has_body("application/sdp")){ - xlog("L_INFO", "received MT_indialog_reply, Patching N5 session in PCF...\n"); - xlog("L_INFO", "N5 PATCH: About to test if this is a retransmitted reply which is still currently suspended\n"); - if (t_is_retr_async_reply()) { - xlog("L_INFO", "Dropping retransmitted reply which is still currently suspended\n"); - drop(); - } - route(N5_PATCH_MT_REQ); - } - # In case of 1xx and 2xx do NAT if(status=~"[12][0-9][0-9]") route(NATMANAGE); @@ -182,446 +174,377 @@ onreply_route[MT_indialog_reply] { } xlog("L_DBG", "IMS: TERM_SUBSEQUENT reply. This is a 200 OK to a re-INVITE\n"); - xlog("L_DBG","Diameter: Term authorizing media via Rx\n"); + xlog("L_DBG","Diameter: Term authorizing media via Rx\n"); $avp(FTAG_CUSTOM_AVP)=$ft; $avp(TTAG_CUSTOM_AVP)=$tt; $avp(CALLID_CUSTOM_AVP)=$ci; if (Rx_AAR("MT_indialog_aar_reply","term","",-1) == 0) { - exit; - } + exit; + } } } route[MT_indialog_aar_reply] { - #this is async so to know status we have to check the reply avp + # Check reply AVP since the operation is async switch ($avp(s:aar_return_code)) { - case 1: - xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); - break; - default: - xlog("L_ERR", "IMS: AAR failed Orig\n"); - xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); - xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); - #comment this if you want to allow even if Rx fails - if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ - dlg_terminate("all", "Sorry no QoS available"); - exit; - } - } + case 1: + xlog("L_DBG", "Diameter: Orig AAR success on media authorization\n"); + break; + default: + xlog("L_ERR", "IMS: AAR failed Orig\n"); + xlog("L_ERR", "IMS: ttag: "+ "$avp(TTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: ftag: "+ "$avp(FTAG_CUSTOM_AVP)"); + xlog("L_ERR", "IMS: callid: "+ "$avp(CALLID_CUSTOM_AVP)"); + # Comment this if you want to allow even if Rx fails + if(dlg_get("$avp(CALLID_CUSTOM_AVP)","$avp(FTAG_CUSTOM_AVP)","$avp(TTAG_CUSTOM_AVP)")){ + dlg_terminate("all", "Sorry no QoS available"); + exit; + } + } #!endif } -################################# -## Route Logic for N5 Requests ## -################################# +#!ifdef WITH_N5 + +# Route Logic for N5 Requests route[N5_INIT_MT_REQ] { -## Storing IDs and IPs from UE into variables to use them later in the N5 Request: + # Storing IDs and IPs from UE into variables to use them later in the N5 Request + $var(term_ue_ip) = $dd; + $var(term_sip_ue_port) = $rp; + $var(pcscf_sip_ip) = $Ri; + $var(pcscf_sip_port) = $Rp; - - $var(term_ue_ip) = $dd; - $var(term_sip_ue_port) = $rp; - $var(pcscf_sip_ip) = $Ri; - $var(pcscf_sip_port) = $Rp; - -# now checking it on console if I got what I wanted : - xlog("L_INFO", "SIP connection Info for Term UE $var(term_ue_ip) $var(term_sip_ue_port)\n"); - xlog("L_INFO", "SIP connection Info for P-CSCF is: $var(pcscf_sip_ip) $var(pcscf_sip_port)\n"); + xlog("L_INFO", "SIP Connection Info for Term UE $var(term_ue_ip) $var(term_sip_ue_port)\n"); + xlog("L_INFO", "SIP Connection Info for P-CSCF is: $var(pcscf_sip_ip) $var(pcscf_sip_port)\n"); -# now trying some way to store IP of Term UE - $var(term_user_id_req_ip) = $tU; # should get the user part of the Orig UE from request - - # Store the IP in the hash table associated with the UE - $sht(user_sip_ips=>$var(term_user_id_req_ip)) = $var(term_ue_ip); - xlog("L_INFO", "SIP/SDP IP Info for Term UE MSISDN $var(term_user_id_req_ip): $var(term_ue_ip)\n"); - -# now trying some way to store Port of Term UE - $var(term_user_id_req_port) = $tU; # should get the user part of the Orig UE from request - - # Store the Port in the hash table associated with the UE - $sht(user_sip_ports=>$var(term_user_id_req_port)) = $var(term_sip_ue_port); - xlog("L_INFO", "SIP Port Info for UE MSISDN $var(term_user_id_req_port): $var(term_sip_ue_port)\n"); - -#### 5G VoNR N5 NPCF Authorization reuqest + $var(term_user_id_req_ip) = $tU; + # Store the IP in the hash table associated with the UE + $sht(user_sip_ips=>$var(term_user_id_req_ip)) = $var(term_ue_ip); + xlog("L_INFO", "SIP/SDP IP Info for Term UE MSISDN $var(term_user_id_req_ip): $var(term_ue_ip)\n"); - if(is_method("INVITE")){ - xlog("L_INFO", "IMS: MTC INVITE TO $tU\n"); + $var(term_user_id_req_port) = $tU; + # Store the Port in the hash table associated with the UE + $sht(user_sip_ports=>$var(term_user_id_req_port)) = $var(term_sip_ue_port); + xlog("L_INFO", "SIP Port Info for UE MSISDN $var(term_user_id_req_port): $var(term_sip_ue_port)\n"); - -## retrieving SDP Connection Info and Media Port for Orig UE ( in case we will start with INVITE): + xlog("L_INFO", "IMS: MTC INVITE TO $tU\n"); + # Retrieving SDP Connection Info and Media Port for UE + $var(sdp_src_ip) = $sdp(c:ip); + $var(sdp_src_port) = $sdp(m0:rtp:port); + $var(orig_ue_sdp_rtcp_port) = $sdp(m0:rtcp:port); + $var(sdp_mline_raw) = $sdp(m0:raw); -$var(sdp_src_ip) = $sdp(c:ip); -$var(sdp_src_port) = $sdp(m0:rtp:port); -$var(orig_ue_sdp_rtcp_port) = $sdp(m0:rtcp:port); -$var(sdp_mline_raw) = $sdp(m0:raw); + xlog("L_INFO", "SDP Info From INVITE: $sdp(c:ip) -- $sdp(m0:rtp:port) -- $sdp(m0:rtcp:port)\n"); - xlog("L_INFO", "SDP Info From INVITE: $sdp(c:ip) -- $sdp(m0:rtp:port) -- $sdp(m0:rtcp:port)\n"); + $var(call_id_sdp_ip) = $ci; + # Store the SDP IP in the hash table associated with the Call-Id + $sht(user_sdps_ip=>$var(call_id_sdp_ip)) = $var(sdp_src_ip); -# SDP IP Orig Party + $var(ret_call_id_sdp_ip) = $ci; + $var(sdp_src_ip) = $sht(user_sdps_ip=>$var(ret_call_id_sdp_ip)); + xlog("L_INFO", "SDP IP of orig UE $fU Call-ID $var(call_id_sdp_ip): $var(sdp_src_ip)\n"); - -# now trying some way to store SDP SRC_IP of Orig Party + $var(sdp_call_id_port) = $ci; + # Store SDP Media Port in the hash table associated with the Call-Id + $sht(user_sdps_port=>$var(sdp_call_id_port)) = $var(sdp_src_port); + xlog("L_INFO", "SDP Port for MTC Call-ID $var(sdp_call_id_port) is: $var(sdp_src_port)\n"); - $var(call_id_sdp_ip) = $ci; # call-ID + $var(sdp_call_id_rtcp_port) = $ci; + #Store SDP RTCP Port in the hash table associated with the Call-Id + $sht(user_sdps_rtcp_port=>$var(sdp_call_id_rtcp_port)) = $var(orig_ue_sdp_rtcp_port); - # Store the SDP IP in the hash table associated with the Call-ID - $sht(user_sdps_ip=>$var(call_id_sdp_ip)) = $var(sdp_src_ip); + $var(sdp_call_id_rtcp_port) = $ci; + $var(orig_ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_call_id_rtcp_port)); + xlog("L_INFO", "SDP RTCP Port for UE with MSISDN $fU is: $var(orig_ue_sdp_rtcp_port)\n"); -#Testing retrival + xlog("L_INFO", "Preparing QoS N5 Message to PCF for INVITE To term UE\n"); - $var(ret_call_id_sdp_ip) = $ci; # User Port of the from Header to get the USER - $var(sdp_src_ip) = $sht(user_sdps_ip=>$var(ret_call_id_sdp_ip)); - - xlog("L_INFO", "SDP IP of orig UE $fU Call-ID $var(call_id_sdp_ip): $var(sdp_src_ip)\n"); + $var(events) = '[]'; + $var(medComponents) = '{}'; + $var(medSubComps) = '{}'; + $var(evSubsc) = '{}'; + $var(payload) = '{}'; -# SDP RTP Port Orig Party - - $var(sdp_call_id_port) = $ci; # call-ID + # Set afAppId and dnn in payload + # TODO: Get the value from SIP Header + jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); + jansson_set("string", "dnn", "ims", "$var(payload)"); - # store SDP Media_Port in the hash table associated with the Call-ID - $sht(user_sdps_port=>$var(sdp_call_id_port)) = $var(sdp_src_port); + # Set medComponents + jansson_set("integer", "medCompN", 1, "$var(medComp)"); + jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); + jansson_set("string", "medType", "AUDIO", "$var(medComp)"); + jansson_set("array", "codecs", "[\"downlink\\noffer\\n\", \"uplink\\nanswer\\n\"]", "$var(medComp)"); - xlog("L_INFO", "SDP Port for MTC Call-ID $var(sdp_call_id_port) is: $var(sdp_src_port)\n"); + # RTP + jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); + jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_src_ip) $var(sdp_src_port) to $dd 49000-51000\", \"permit in 17 from $dd 49000-51000 to $var(sdp_src_ip) $var(sdp_src_port)\"]", "$var(medSubComp1)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); -# SDP RTCP Port Orig Party + # RTCP + jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); + jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_src_ip) $var(orig_ue_sdp_rtcp_port) to $dd 49000-51000\", \"permit in 17 from $dd 49000-51000 to $var(sdp_src_ip) $var(orig_ue_sdp_rtcp_port)\"]", "$var(medSubComp2)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); - $var(sdp_call_id_rtcp_port) = $ci; # User Port of the from Header to get the USER - #Store SDP RTCP Port in the hash table associated with the Call-ID - $sht(user_sdps_rtcp_port=>$var(sdp_call_id_rtcp_port)) = $var(orig_ue_sdp_rtcp_port); - + # Merging the flows under MediaSubComponent + jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); + jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); + jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); -#Testing retrival - $var(sdp_call_id_rtcp_port) = $ci; - $var(orig_ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_call_id_rtcp_port)); + jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); + jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); - xlog("L_INFO", "SDP RTCP Port for UE with MSISDN $fU is: $var(orig_ue_sdp_rtcp_port)\n"); - + xlog("L_INFO","DEBUG: Set evSubsc\n"); -#### now start to build the N5 Request + # Set evSubsc + jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); + jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); + jansson_append("obj", "", "$var(event1)", "$var(events)"); + jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); + jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); + jansson_append("obj", "", "$var(event2)", "$var(events)"); + jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); - xlog("L_INFO", "Preparing QoS N5 Message to PCF for INVITE TO term UE\n"); - - xlog("L_INFO", "Initialize empty arrays and objects\n"); - -### Initialize empty arrays and objects - $var(events) = '[]'; - $var(medComponents) = '{}'; - $var(medSubComps) = '{}'; - $var(evSubsc) = '{}'; - $var(payload) = '{}'; - -### Set afAppId and dnn in payload - jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); # adding a note that this could be improved in future to get the value SIP Header - jansson_set("string", "dnn", "ims", "$var(payload)"); - -### Set medComponents - jansson_set("integer", "medCompN", 1, "$var(medComp)"); - jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); - jansson_set("string", "medType", "AUDIO", "$var(medComp)"); - jansson_set("array", "codecs", "[\"downlink\\noffer\\n\", \"uplink\\nanswer\\n\"]", "$var(medComp)"); - - ### RTP - jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); - jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_src_ip) $var(sdp_src_port) to $dd 49000-51000\", \"permit in 17 from $dd 49000-51000 to $var(sdp_src_ip) $var(sdp_src_port)\"]", "$var(medSubComp1)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); - jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); - - - ### RTCP - jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); - jansson_set("array", "fDescs", "[\"permit out 17 from $var(sdp_src_ip) $var(orig_ue_sdp_rtcp_port) to $dd 49000-51000\", \"permit in 17 from $dd 49000-51000 to $var(sdp_src_ip) $var(orig_ue_sdp_rtcp_port)\"]", "$var(medSubComp2)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp2)"); - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp2)"); - jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); - - # Merging the flows under MediaSubComponent - jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); - jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); - jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); - - jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); - jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); - - xlog("L_INFO","DEBUG: Set evSubsc\n"); - -### Set evSubsc - jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); - jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); - jansson_append("obj", "", "$var(event1)", "$var(events)"); - jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); - jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); - jansson_append("obj", "", "$var(event2)", "$var(events)"); - jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); - - jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); - -### Set other parameters in payload - jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); - jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); - jansson_set("string", "gpsi", "msisdn-$tU", "$var(payload)"); - jansson_set("string", "suppFeat", "2", "$var(payload)"); - jansson_set("string", "ueIpv4", "$dd", "$var(payload)"); - - ### Assemble the final JSON request - jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); - xlog("L_INFO","DEBUG: Set headers for the HTTP2 Request\n"); -### Set headers - $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); - xlog("L_INFO", "Today is $var(time_now)\n"); - - $var(headers) = "Content-Type: application/json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + # Set other parameters in payload + jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); + jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); + jansson_set("string", "gpsi", "msisdn-$tU", "$var(payload)"); + jansson_set("string", "suppFeat", "2", "$var(payload)"); + jansson_set("string", "ueIpv4", "$dd", "$var(payload)"); - - xlog("L_INFO","Sending the request to PCF\n"); -### Send the request to PCF - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$var(json_request)", "$var(headers)", "$var(result)" ); + # Assemble the final JSON request + jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); -### here we want to kill the dialog in case QoS faild or continue if QoS success. - switch ($rc) { + xlog("L_INFO","DEBUG: Set headers for the HTTP2 Request\n"); + # Set headers + $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); + xlog("L_INFO", "Today is $var(time_now)\n"); + + $var(headers) = "Content-Type: application/json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + + xlog("L_INFO","Sending the request to PCF\n"); + # Send the request to PCF + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$var(json_request)", "$var(headers)", "$var(result)" ); + + switch ($rc) { + # Success case case 201: - xlog("L_INFO", "N5 QoS Session successfully Created $rc\n"); - xlog("L_INFO", "HTTP results: $var(result)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - xlog("L_INFO", "Location Header: $httprhdr(location)\n"); + xlog("L_INFO", "N5 QoS Session successfully Created $rc\n"); + xlog("L_INFO", "HTTP results: $var(result)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); + xlog("L_INFO", "Location Header: $httprhdr(location)\n"); -# Now I will retrieve the AppSessionID out of the location Header it should be always at the end -# Example URL: "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/(someSessionID)" - -# Firt store the url of the lcoation Header in var - $var(url) = $httprhdr(location); - - # Get the length of the URL - $var(len) = $(var(url){s.len}); - - # Initialize the position variable to the length of the URL - $var(pos) = $var(len); - - # Find the position of the last slash by iterating backwards - while ($var(pos) > 0) { - $var(pos) = $var(pos) - 1; - if ($(var(url){s.substr,$var(pos),1}) == "/") { - # We've found the last slash - break; - } - } - -# Extract the substring after the last slash -# now doing some magic -# Set the starting position after the last slash - $var(start_pos) = $var(pos) + 1; + # Retrieve the AppSession Id out of the location header in response + # Example URL: "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/(someSessionID)" - # Calculate the length of the substring after the last slash - $var(substring_length) = $var(len) - $var(start_pos); + # Store the url of the lcoation Header in var + $var(url) = $httprhdr(location); + # Get the length of the URL + $var(len) = $(var(url){s.len}); + # Initialize the position variable to the length of the URL + $var(pos) = $var(len); - # Extract the substring after the last slash - $var(mtc_app_session) = $(var(url){s.substr,$var(start_pos),$var(substring_length)}); + # Find the position of the last slash by iterating backwards + while ($var(pos) > 0) { + $var(pos) = $var(pos) - 1; + if ($(var(url){s.substr,$var(pos),1}) == "/") { + # We've found the last slash + break; + } + } -# now checking it on console if I got what I wanted : - xlog("L_INFO", "AppSession for user $tU is: $var(mtc_app_session)\n"); + # Extract the substring after the last slash + # Set the starting position after the last slash + $var(start_pos) = $var(pos) + 1; + # Calculate the length of the substring after the last slash + $var(substring_length) = $var(len) - $var(start_pos); + # Extract the substring after the last slash + $var(mtc_app_session) = $(var(url){s.substr,$var(start_pos),$var(substring_length)}); -# now trying some way to store AppSession with the registred UE - $var(term_user_id) = $tU; # should get the user part of the Orig UE + xlog("L_INFO", "AppSession Id for user $tU is: $var(mtc_app_session)\n"); - # Store the AppSession in the hash table associated with the UE - $sht(user_data=>$var(term_user_id)) = $var(mtc_app_session); - xlog("L_INFO", "Stored AppSession for user $var(term_user_id): $var(mtc_app_session)\n"); - break; - default: + $var(term_user_id) = $tU; + + # Store the AppSession Id in the hash table associated with the UE + $sht(user_data=>$var(term_user_id)) = $var(mtc_app_session); + xlog("L_INFO", "Stored AppSession for user $var(term_user_id): $var(mtc_app_session)\n"); + break; + default: xlog("L_ERR", "N5 QoS Session faild - Reason code: $rc\n"); send_reply("412", "MTC N5 QoS Session Creation faild"); - exit; - } # switch ends here - # } # else for AppSession not null ends here - } # If Methode INVITE ends here - + exit; + } } -############ -############# -############# + +# 5G VoNR N5 Policy Authorization PATCH request route[N5_PATCH_MT_REQ] { - - - xlog("L_INFO", "N5_PATCH_MT_REQ, building N5 PATCH Request\n"); + xlog("L_INFO", "N5_PATCH_MT_REQ, building N5 PATCH Request\n"); + # Retrieve SDP Connection Info and Media Port for UE + $var(sdp_call_id) = $ci; + $var(orig_ue_sdp_ip) = $sht(user_sdps_ip=>$var(sdp_call_id)); + xlog("L_INFO", "SDP IP for UE with MSISDN $fU Call-ID $var(sdp_call_id) is: $var(orig_ue_sdp_ip)\n"); -## retrieving SDP Connection Info and Media Port for UE - $var(sdp_call_id) = $ci; # Call-ID for INVITE - $var(orig_ue_sdp_ip) = $sht(user_sdps_ip=>$var(sdp_call_id)); - xlog("L_INFO", "SDP IP for UE with MSISDN $fU Call-ID $var(sdp_call_id) is: $var(orig_ue_sdp_ip)\n"); + $var(sdp_call_id_port) = $ci; + $var(orig_ue_sdp_port) = $sht(user_sdps_port=>$var(sdp_call_id_port)); + xlog("L_INFO", "SDP RTP Port for UE with MSISDN $fU Call-ID $var(sdp_call_id_port) is: $var(orig_ue_sdp_port)\n"); - $var(sdp_call_id_port) = $ci; # User Port of the from Header to get the USER - $var(orig_ue_sdp_port) = $sht(user_sdps_port=>$var(sdp_call_id_port)); - xlog("L_INFO", "SDP RTP Port for UE with MSISDN $fU Call-ID $var(sdp_call_id_port) is: $var(orig_ue_sdp_port)\n"); + $var(sdp_call_id_rtcp_port) = $ci; + $var(orig_ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_call_id_rtcp_port)); + xlog("L_INFO", "SDP RTCP Port for UE with MSISDN $fU Call-ID $var(sdp_call_id_rtcp_port) is: $var(orig_ue_sdp_rtcp_port)\n"); + # Retrieve SDP Connection Info from SDP Answer + $var(sdp_answ_ip) = $sdp(c:ip); + $var(sdp_answ_port) = $sdp(m0:rtp:port); + $var(sdp_answ_rtcp_port) = $sdp(m0:rtcp:port); + $var(sdp_answ_codec) = $(rb{line.sw,a=rtpmap}{s.select,1, }); + xlog("L_INFO", "SDP Answer connection Info is: $var(sdp_answ_ip), RTP port $var(sdp_answ_port), RTCP Port $var(sdp_answ_rtcp_port) and codec is $var(sdp_answ_codec)\n"); - $var(sdp_call_id_rtcp_port) = $ci; # Call ID for INVITE - $var(orig_ue_sdp_rtcp_port) = $sht(user_sdps_rtcp_port=>$var(sdp_call_id_rtcp_port)); - xlog("L_INFO", "SDP RTCP Port for UE with MSISDN $fU Call-ID $var(sdp_call_id_rtcp_port) is: $var(orig_ue_sdp_rtcp_port)\n"); - -## retrieving SDP Connection Info from SDP Answer - $var(sdp_answ_ip) = $sdp(c:ip); - $var(sdp_answ_port) = $sdp(m0:rtp:port); - $var(sdp_answ_rtcp_port) = $sdp(m0:rtcp:port); - $var(sdp_answ_codec) = $(rb{line.sw,a=rtpmap}{s.select,1, }); - xlog("L_INFO", "SDP Answer connection Info is: $var(sdp_answ_ip), RTP port $var(sdp_answ_port), RTCP Port $var(sdp_answ_rtcp_port) and codec is $var(sdp_answ_codec)\n"); - -## Retrieveing AppSession from initial INVITE N5 Request - $var(mtc_resp_app_id) = $tU; # User Part of the from Header to get the USER - $var(user_appsess_mtc_rep) = $sht(user_data=>$var(mtc_resp_app_id)); - xlog("L_INFO", "Stored MTC AppSession for user $var(mtc_resp_app_id): $var(user_appsess_mtc_rep)\n"); + # Retrieve AppSession + $var(mtc_resp_app_id) = $tU; + $var(user_appsess_mtc_rep) = $sht(user_data=>$var(mtc_resp_app_id)); + xlog("L_INFO", "Stored MTC AppSession for user $var(mtc_resp_app_id): $var(user_appsess_mtc_rep)\n"); -#### now start to build the N5 Request + xlog("L_INFO","Preparing PATCH N5 Message for SDP Answer\n"); - xlog("L_INFO","Preparing PATCH N5 Message for SDP Answer\n"); - - xlog("L_INFO","Initialize empty arrays and objects\n"); - -### Initialize empty arrays and objects - $var(events) = '[]'; - $var(medComponents) = '{}'; - $var(medSubComps) = '{}'; - $var(evSubsc) = '{}'; - $var(payload) = '{}'; - -### Set afAppId and dnn in payload - jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); - jansson_set("string", "dnn", "ims", "$var(payload)"); - -### Set medComponents - jansson_set("integer", "medCompN", 1, "$var(medComp)"); - jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "medType", "AUDIO", "$var(medComp)"); - jansson_set("array", "codecs", "[\"downlink\\n$var(sdp_answ_codec)\\n\", \"uplink\\n$var(sdp_answ_codec)\\n\"]", "$var(medComp)"); - - ### RTP - jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); - jansson_set("array", "fDescs", "[\"permit out 17 from $var(orig_ue_sdp_ip) $var(orig_ue_sdp_port) to $var(sdp_answ_ip) $var(sdp_answ_port)\", \"permit in 17 from $var(sdp_answ_ip) $var(sdp_answ_port) to $var(orig_ue_sdp_ip) $var(orig_ue_sdp_port)\"]", "$var(medSubComp1)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); - jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); - jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); - jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); - - - ### RTCP - jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); - jansson_set("array", "fDescs", "[\"permit out 17 from $var(orig_ue_sdp_ip) $var(orig_ue_sdp_rtcp_port) to $var(sdp_answ_ip) $var(sdp_answ_rtcp_port)\", \"permit in 17 from $var(sdp_answ_ip) $var(sdp_answ_rtcp_port) to $var(orig_ue_sdp_ip) $var(orig_ue_sdp_rtcp_port)\"]", "$var(medSubComp2)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); - jansson_set("string", "marBwDl", "6000 Kbps", "$var(medSubComp2)"); - jansson_set("string", "marBwUl", "5000 Kbps", "$var(medSubComp2)"); - jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); - - # Merging the flows under MediaSubComponent - jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); - jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); - jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); - - jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); - jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); - - xlog("L_INFO","DEBUG: Set evSubsc\n"); - -### Set evSubsc - jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); - jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); - jansson_append("obj", "", "$var(event1)", "$var(events)"); - jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); - jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); - jansson_append("obj", "", "$var(event2)", "$var(events)"); - jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); - - jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); - -### Set other parameters in payload - jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); - jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "gpsi", "msisdn-$tU", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "suppFeat", "2", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - jansson_set("string", "ueIpv4", "$si", "$var(payload)"); # not all element in PATCH/Merge request are needed only the chanegd one, could be reenabled if needed - - ### Assemble the final JSON request - jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + $var(events) = '[]'; + $var(medComponents) = '{}'; + $var(medSubComps) = '{}'; + $var(evSubsc) = '{}'; + $var(payload) = '{}'; - xlog("L_INFO","DEBUG: Set headers for the HTTP2 Request\n"); -### Set headers - $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); - xlog("L_INFO", "Today is $var(time_now)\n"); - - $var(headers) = "Content-Type: application/merge-patch+json\r\n"; # added content-type an set it to "application/merge-patch+json" fo compatibility with RFC7386 for JSON PATCH/Merge - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + # Set afAppId and dnn in payload + jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); + jansson_set("string", "dnn", "ims", "$var(payload)"); - - xlog("L_INFO","Sending the request to PCF\n"); -### Send the request to PCF - http_client_request_v2pk("PATCH", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_mtc_rep)", "$var(json_request)", "$var(headers)", "$var(result)" ); -#### here we want to kill the dialog in case QoS faild or continue if QoS success. - switch ($rc) { + # Set medComponents + jansson_set("integer", "medCompN", 1, "$var(medComp)"); + jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); + jansson_set("string", "medType", "AUDIO", "$var(medComp)"); + jansson_set("array", "codecs", "[\"downlink\\n$var(sdp_answ_codec)\\n\", \"uplink\\n$var(sdp_answ_codec)\\n\"]", "$var(medComp)"); + + # RTP + jansson_set("integer", "fNum", 1, "$var(medSubComp1)"); + jansson_set("array", "fDescs", "[\"permit out 17 from $var(orig_ue_sdp_ip) $var(orig_ue_sdp_port) to $var(sdp_answ_ip) $var(sdp_answ_port)\", \"permit in 17 from $var(sdp_answ_ip) $var(sdp_answ_port) to $var(orig_ue_sdp_ip) $var(orig_ue_sdp_port)\"]", "$var(medSubComp1)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp1)"); + jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp1)"); + jansson_set("string", "flowUsage", "NO_INFO", "$var(medSubComp1)"); + + # RTCP + jansson_set("integer", "fNum", 2, "$var(medSubComp2)"); + jansson_set("array", "fDescs", "[\"permit out 17 from $var(orig_ue_sdp_ip) $var(orig_ue_sdp_rtcp_port) to $var(sdp_answ_ip) $var(sdp_answ_rtcp_port)\", \"permit in 17 from $var(sdp_answ_ip) $var(sdp_answ_rtcp_port) to $var(orig_ue_sdp_ip) $var(orig_ue_sdp_rtcp_port)\"]", "$var(medSubComp2)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp2)"); + jansson_set("string", "marBwDl", "6000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "marBwUl", "5000 Kbps", "$var(medSubComp2)"); + jansson_set("string", "flowUsage", "RTCP", "$var(medSubComp2)"); + + # Merging the flows under MediaSubComponent + jansson_set("obj", "0", "$var(medSubComp1)", "$var(medSubComps)"); + jansson_set("obj", "1", "$var(medSubComp2)", "$var(medSubComps)"); + jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); + + jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); + jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); + + xlog("L_INFO","DEBUG: Set evSubsc\n"); + + # Set evSubsc + jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); + jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); + jansson_append("obj", "", "$var(event1)", "$var(events)"); + jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); + jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); + jansson_append("obj", "", "$var(event2)", "$var(events)"); + jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); + + jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); + + # Set other parameters in payload + jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); + jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); + jansson_set("string", "gpsi", "msisdn-$tU", "$var(payload)"); + jansson_set("string", "suppFeat", "2", "$var(payload)"); + jansson_set("string", "ueIpv4", "$si", "$var(payload)"); + + # Assemble the final JSON request + jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + + xlog("L_INFO","DEBUG: Set headers for the HTTP2 Request\n"); + # Set headers + $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); + xlog("L_INFO", "Today is $var(time_now)\n"); + + # Set Content-type to application/merge-patch+json for compatibility with RFC7386 for JSON PATCH/Merge + $var(headers) = "Content-Type: application/merge-patch+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + + xlog("L_INFO","Sending the request to PCF\n"); + # Send the request to PCF + http_client_request_v2pk("PATCH", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_mtc_rep)", "$var(json_request)", "$var(headers)", "$var(result)" ); + switch ($rc) { case 200: - xlog("L_INFO", "N5 QoS Session modification success - reason code: $rc\n"); - xlog("L_INFO", "HTTP results: $var(result)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - xlog("L_INFO", "cURL Response: $curlerror(error)\n"); - xlog("L_INFO", "Location Header header: $httprhdr(location)\n"); - break; + xlog("L_INFO", "N5 QoS Session modification success - reason code: $rc\n"); + xlog("L_INFO", "HTTP results: $var(result)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); + xlog("L_INFO", "cURL Response: $curlerror(error)\n"); + xlog("L_INFO", "Location Header header: $httprhdr(location)\n"); + break; default: xlog("L_ERR", "N5 QoS Session modification faild - reason code: $rc\n"); send_reply("412", "MTC N5 QoS Session modify faild"); - exit; - } # switch ends here - + exit; + } } -######################################## -######### END of 5G VoNR N5 Request #### -######################################## + route[N5_MTC_TERM] { + xlog("L_ALERT","Terminating AppSession For Call for User $tU due to call END\n"); + # Retrieve appSession based on To URI + $var(mtc_resp_app_id) = $tU; + $var(user_appsess_mtc_rep) = $sht(user_data=>$var(mtc_resp_app_id)); + if $var(user_appsess_mtc_rep) == 0 { + xlog("L_INFO", "No AppSession Id found to terminate. Trying using From URI\n"); -## something need to be clear here about BYE ;( To/From Headers!!! + # Retrieve appSession based on From URI + $var(mtc_resp_app_id) = $fU; + $var(user_appsess_mtc_rep) = $sht(user_data=>$var(mtc_resp_app_id)); + xlog("L_INFO", "Alt-Method : Terminating Stored AppSession for user $var(mtc_resp_app_id): $var(user_appsess_mtc_rep)\n"); + } else { + xlog("L_INFO", "Normal Method : MTC AppSession for user $var(mtc_resp_app_id): $var(user_appsess_mtc_rep)\n"); + } + $var(headers) = "X-SIP-Status: De-Registration\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); - xlog("L_ALERT","Terminating AppSession For Call for User $tU due to call END\n"); - # Retrieveing and paying attention to whom ended teh call - $var(mtc_resp_app_id) = $tU; # User Part of the from Header to get the USER - $var(user_appsess_mtc_rep) = $sht(user_data=>$var(mtc_resp_app_id)); - if $var(user_appsess_mtc_rep) == 0 { - xlog("L_INFO", "we dont have AppSessionID to terminate, doing alternative Method\n"); - - # Retrieveing and paying attention to whom ended teh call - $var(mtc_resp_app_id) = $fU; # User Part of the from Header to get the USER - $var(user_appsess_mtc_rep) = $sht(user_data=>$var(mtc_resp_app_id)); - xlog("L_INFO", "Alt-Method : Terminating Stored AppSession for user $var(mtc_resp_app_id): $var(user_appsess_mtc_rep)\n"); - } else { - xlog("L_INFO", "We have AppSessionID, doing normal Method\n"); - xlog("L_INFO", "Normal Method : Stored MTC AppSession for user $var(mtc_resp_app_id): $var(user_appsess_mtc_rep)\n"); - } - - - $var(headers) = "X-SIP-Status: De-Registration\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); - - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_mtc_rep)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); - xlog("L_INFO", "cURL header: $curlerror(error)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - -} + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_mtc_rep)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); + xlog("L_INFO", "cURL header: $curlerror(error)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); +} +#!endif diff --git a/pcscf/route/register.cfg b/pcscf/route/register.cfg index 1b12ef4..5679023 100644 --- a/pcscf/route/register.cfg +++ b/pcscf/route/register.cfg @@ -3,9 +3,9 @@ ###################################################################### route[REGISTER] { # Provide some statistics - if ($sht(a=>$ci::start_time) == $null || $sht(a=>$ci::start_time) == 0) { - $sht(a=>$ci::start_time) = $TV(Sn); - } + if ($sht(a=>$ci::start_time) == $null || $sht(a=>$ci::start_time) == 0) { + $sht(a=>$ci::start_time) = $TV(Sn); + } xnotice("PCSCF REGISTER: \n Destination URI: $du\n Request URI: $ru\n"); xnotice("Source IP and Port: ($si:$sp)\n Route-URI: $route_uri\n"); xnotice("Received IP and Port: ($Ri:$Rp)\n"); @@ -21,20 +21,20 @@ route[REGISTER] { exit; } -### N5 Request create and terminate - xlog("L_INFO","Checking if its a Registration and not a De-Reg for $fu\n"); - $var(reg_exp) = $expires(min); - xlog("L_INFO","Checking Expire $fu and it is : $var(reg_exp)\n"); - - # tying a dirty workaround to make it only excute after IPSec tunnel to prevent double excution - if ($expires(min) != 0 && is_present_hf("Security-Verify")) { - route(REGISTER_N5_Req); - } +#!ifdef WITH_N5 + $var(reg_exp) = $expires(min); + xlog("L_INFO","Expire for $fu is :$var(reg_exp)\n"); - if ($expires(min) == 0 ) { - xlog("L_ALERT","delete N5 Session for $fu due to de-register\n"); - route(REG_N5_TERMINATE); - } + # Trying a dirty workaround to make it only excute after IPSec tunnel to prevent double excution + if ($expires(min) != 0 && is_present_hf("Security-Verify")) { + route(REGISTER_N5_REQ); + } + + if ($expires(min) == 0) { + xlog("L_ALERT","Delete N5 Session for $fu due to de-register\n"); + route(REG_N5_TERMINATE); + } +#!endif #!ifdef WITH_IPSEC $sht(ipsec_clients=>$(ct{nameaddr.uri})) = $null; @@ -272,8 +272,8 @@ onreply_route[REGISTER_reply] update_stat("register_success", "+1"); update_stat("register_time", "$var(stat_add)"); #!ifdef WITH_IPSEC - ipsec_forward("location", IPSEC_FORWARD_FLAGS); - } + ipsec_forward("location", IPSEC_FORWARD_FLAGS); + } else { if (t_check_status("401")) { if($(T_req($hdr(Security-Client))) != $null && ipsec_create("location", IPSEC_DELETE_UNUSED_TUNNELS)!=1) { @@ -299,9 +299,9 @@ onreply_route[REGISTER_reply] } xnotice("New header - WWW-Authenticate=$var(new_hdr)\n"); } - } + } #!endif - } + } exit; } @@ -310,11 +310,12 @@ onreply_route[REGISTER_reply] failure_route[REGISTER_failure] { -# Terminate N5 Session on Reg Failure - - if (t_check_status("403|408|[5-6][0-9][0-9]")) { - route(REG_N5_TERMINATE); - } +#!ifdef WITH_N5 + # Terminate N5 Session on Reg Failure + if (t_check_status("403|408|[5-6][0-9][0-9]")) { + route(REG_N5_TERMINATE); + } +#!endif #!ifdef WITH_IPBLOCK if (t_check_status("403|[5-6][0-9][0-9]")) { @@ -327,198 +328,161 @@ failure_route[REGISTER_failure] xlog("Blocking traffic from $si\n"); $sht(ipban=>$si) = 1; } - update_stat("register_failed", "+1"); + update_stat("register_failed", "+1"); } #!endif if (t_check_status("408")) { send_reply("504","Server Time-Out"); - update_stat("register_failed", "+1"); + update_stat("register_failed", "+1"); exit; } - + } +#!ifdef WITH_N5 - - - -############################################# -##### 5G Experemntal PCF N5 Interface Reg ## -############################################# - -route[REGISTER_N5_Req] +# N5 Policy Authorization - Create Application session context for SIP Registration +route[REGISTER_N5_REQ] { - + xlog("L_INFO","SIP Registration - Starting N5 QoS Auth for $fu\n"); - xlog("L_INFO","its a Registration, starting N5 QoS Auth for $fu\n"); - - xlog("L_INFO","Initialize empty arrays and objects\n"); -### Initialize empty arrays and objects - $var(events) = '[]'; - $var(medComponents) = '{}'; - $var(medSubComps) = '{}'; - $var(evSubsc) = '{}'; - $var(payload) = '{}'; + $var(events) = '[]'; + $var(medComponents) = '{}'; + $var(medSubComps) = '{}'; + $var(evSubsc) = '{}'; + $var(payload) = '{}'; -### Set afAppId and dnn in payload - jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); # adding a note that this could be improved in future to get the value SIP Header - jansson_set("string", "dnn", "ims", "$var(payload)"); + # Set afAppId and dnn in payload + jansson_set("string", "afAppId", "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"", "$var(payload)"); # adding a note that this could be improved in future to get the value SIP Header + jansson_set("string", "dnn", "ims", "$var(payload)"); -### Set medComponents - jansson_set("integer", "medCompN", 0, "$var(medComp)"); - jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); - jansson_set("string", "medType", "CONTROL", "$var(medComp)"); + # Set media components in payload + jansson_set("integer", "medCompN", 0, "$var(medComp)"); + jansson_set("string", "qosReference", "qosVoNR", "$var(medComp)"); + jansson_set("string", "medType", "CONTROL", "$var(medComp)"); - jansson_set("integer", "fNum", 0, "$var(medSubComp)"); - jansson_set("array", "fDescs", "[\"permit out ip from $RAi $RAp to $si $sp\", \"permit in ip from $si $sp to $RAi $RAp\"]", "$var(medSubComp)"); - jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp)"); - jansson_set("string", "flowUsage", "AF_SIGNALLING", "$var(medSubComp)"); -# jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp)"); -# jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp)"); - jansson_set("obj", "0", "$var(medSubComp)", "$var(medSubComps)"); - jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); - - jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); - jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); + jansson_set("integer", "fNum", 0, "$var(medSubComp)"); + jansson_set("array", "fDescs", "[\"permit out ip from $RAi $RAp to $si $sp\", \"permit in ip from $si $sp to $RAi $RAp\"]", "$var(medSubComp)"); + jansson_set("string", "fStatus", "ENABLED", "$var(medSubComp)"); + jansson_set("string", "flowUsage", "AF_SIGNALLING", "$var(medSubComp)"); + # jansson_set("string", "marBwDl", "5000 Kbps", "$var(medSubComp)"); + # jansson_set("string", "marBwUl", "3000 Kbps", "$var(medSubComp)"); + jansson_set("obj", "0", "$var(medSubComp)", "$var(medSubComps)"); + jansson_set("obj", "medSubComps", "$var(medSubComps)", "$var(medComp)"); -xlog("L_INFO","Set evSubsc\n"); + jansson_set("obj", "0", "$var(medComp)", "$var(medComponents)"); + jansson_set("obj", "medComponents", "$var(medComponents)", "$var(payload)"); -### Set evSubsc - jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); - jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); - jansson_append("obj", "", "$var(event1)", "$var(events)"); - jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); - jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); - jansson_append("obj", "", "$var(event2)", "$var(events)"); - jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); + # Set evSubsc + jansson_set("string", "event", "QOS_NOTIF", "$var(event1)"); + jansson_set("string", "notifMethod", "PERIODIC", "$var(event1)"); + jansson_append("obj", "", "$var(event1)", "$var(events)"); + jansson_set("string", "event", "ANI_REPORT", "$var(event2)"); + jansson_set("string", "notifMethod", "ONE_TIME", "$var(event2)"); + jansson_append("obj", "", "$var(event2)", "$var(events)"); + jansson_set("array", "events", "$var(events)", "$var(evSubsc)"); - jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); + jansson_set("obj", "evSubsc", "$var(evSubsc)", "$var(payload)"); -### Set other parameters in payload - jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); - jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); - jansson_set("string", "supi", "imsi-$au", "$var(payload)"); - jansson_set("string", "suppFeat", "2", "$var(payload)"); - jansson_set("string", "ueIpv4", "$si", "$var(payload)"); + # Set other parameters in payload + jansson_set("string", "notifUri", "http://172.22.0.21:7777", "$var(payload)"); + jansson_set("string", "sponStatus", "SPONSOR_DISABLED", "$var(payload)"); + jansson_set("string", "supi", "imsi-$au", "$var(payload)"); + jansson_set("string", "suppFeat", "2", "$var(payload)"); + jansson_set("string", "ueIpv4", "$si", "$var(payload)"); -### Assemble the final JSON request - jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); + # Assemble the final JSON request + jansson_set("obj", "ascReqData", "$var(payload)", "$var(json_request)"); - xlog("L_INFO","Set headers for the HTTP2 Request\n"); -### Set headers - $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); - xlog("L_INFO", "Today is $var(time_now)\n"); - - $var(headers) = "Content-Type: application/json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); - - xlog("L_INFO","DEBUG: Sending the request to PCF\n"); -### Send the request to PCF - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$var(json_request)", "$var(headers)", "$var(result)" ); + # Set HTTP2 request headers + $var(time_now)=$_s($timef(%a, %d %b %Y %H:%M:%S %Z)); + $var(headers) = "Content-Type: application/json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); -### here we want to kill the dialog in case QoS faild or continue if QoS success. - switch ($rc) { + xlog("L_INFO","SIP Registration. Sending N5 QoS Auth for $fu to PCF\n"); + # Send the request to PCF + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions", "$var(json_request)", "$var(headers)", "$var(result)" ); + + switch ($rc) { + # Success case case 201: - xlog("L_INFO", "N5 QoS Session successfully Created $rc\n"); - xlog("L_INFO", "HTTP results: $var(result)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - xlog("L_INFO", "Location Header: $httprhdr(location)\n"); + xlog("L_INFO", "N5 QoS Session successfully Created $rc\n"); + xlog("L_INFO", "HTTP results: $var(result)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); + xlog("L_INFO", "Location Header: $httprhdr(location)\n"); + # Retrieve the AppSession Id out of the location Header if the resopnse is 201. + # Example URL: "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/(someSessionID)" - xlog("L_ALERT","Saving AppSessionID to HTABLE\n"); -# Now I will retrieve the AppSessionID out of the location Header it should be always at the end -# Example URL: "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/(someSessionID)" - -# Firt store the url of the lcoation Header in var - $var(url) = $httprhdr(location); - - # Get the length of the URL - $var(len) = $(var(url){s.len}); - - # Initialize the position variable to the length of the URL - $var(pos) = $var(len); - - # Find the position of the last slash by iterating backwards - while ($var(pos) > 0) { - $var(pos) = $var(pos) - 1; - if ($(var(url){s.substr,$var(pos),1}) == "/") { - # We've found the last slash - break; - } - } - -# Extract the substring after the last slash -# now doing some magic - $var(start_pos) = $var(pos) + 1; - $var(end_pos) = $var(len) - $var(start_pos); - $var(app_session) = $(var(url){s.substr,$var(start_pos),$var(end_pos)}); - -# now checking it on console if I got what I wanted : - xlog("L_INFO", "AppSession for user $au is: $var(app_session)\n"); + # Store the url of the location header + $var(url) = $httprhdr(location); + # Get the length of the URL + $var(len) = $(var(url){s.len}); + # Initialize the position variable to the length of the URL + $var(pos) = $var(len); -# now trying some way to store AppSession with the registred UE - $var(user_id) = $au; # should get the user part of the registred UE + # Find the position of the last slash by iterating backwards + while ($var(pos) > 0) { + $var(pos) = $var(pos) - 1; + if ($(var(url){s.substr,$var(pos),1}) == "/") { + break; + } + } - # Store the AppSession in the hash table associated with the UE - $sht(user_data=>$var(user_id)) = $var(app_session); - xlog("L_INFO", "Stored AppSession for user $var(user_id): $var(app_session)\n"); + # Extract the substring after the last slash + $var(start_pos) = $var(pos) + 1; + $var(end_pos) = $var(len) - $var(start_pos); + $var(app_session) = $(var(url){s.substr,$var(start_pos),$var(end_pos)}); -####### -## Storing IMSI for later use : -###### + xlog("L_INFO", "AppSession Id for user $au is: $var(app_session)\n"); - xlog("L_ALERT","Storing User IMSI to HTABLE for later use\n"); - $var(ue_imsi) = $au; - -# now checking it on console if I got what I wanted : - xlog("L_INFO", "IP for UE is: $var(ue_imsi)\n"); + $var(user_id) = $au; + # Store the AppSession Id in the hash table associated with the UE + $sht(user_data=>$var(user_id)) = $var(app_session); + xlog("L_INFO", "Stored AppSession Id for user $var(user_id): $var(app_session)\n"); -# now trying some way to store AppSession with the registred UE - $var(ue_imsi_reg_ip) = $si; # should get the user part of the registred UE - - # Store the AppSession in the hash table associated with the UE - $sht(user_ids=>$var(ue_imsi_reg_ip)) = $var(ue_imsi); - xlog("L_INFO", "Stored IMSI for IP $var(ue_imsi_reg_ip) is: $var(ue_imsi)\n"); - break; - # now contiue with Reg Proccess, Or: - default: - xlog("L_ERR", "N5 QoS Session faild - Reason code: $rc\n"); - send_reply("412", "Register N5 QoS Session Creation faild"); - exit; - } # switch ends here - -### N5 REQ Route END + $var(ue_imsi) = $au; + $var(ue_imsi_reg_ip) = $si; + # Store the AppSession in the hash table associated with the UE + $sht(user_ids=>$var(ue_imsi_reg_ip)) = $var(ue_imsi); + xlog("L_INFO", "Stored IMSI for IP $var(ue_imsi_reg_ip) is: $var(ue_imsi)\n"); + break; + # Failure case + default: + xlog("L_ERR", "N5 QoS Session authorization failed - Reason code: $rc\n"); + send_reply("412", "Register N5 QoS authorization failed"); + exit; + } } -########################### -## Terminating AppSession # -########################### +# N5 Policy Authorization - Application session termination for SIP De-registration route[REG_N5_TERMINATE] { - xlog("L_ALERT","its a De-Registration for $fu, terminating N5 AppSession\n"); - # Retrieveing - $var(user_id_dereg) = $fU; # User Part of the from Header to get the USER - $var(user_appsess_dereg) = $sht(user_data=>$var(user_id_dereg)); - xlog("L_INFO", "Terminating Stored AppSession for user $var(user_id_dereg): $var(user_appsess_dereg)\n"); - - $var(headers) = "X-SIP-Status: De-Registration\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; - $var(headers) = $var(headers) + "accept: application/json\r\n"; - $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; - $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); - - http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_dereg)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); - xlog("Termination resuls: $var(result)\n"); - xlog("L_ALERT", "cURL response: $curlerror(error)\n"); - xlog("L_INFO", "HTTP results: $var(result)\n"); - xlog("L_INFO", "HTTP response: $rc\n"); - xlog("L_INFO", "Location Header: $httprhdr(location)\n"); + xlog("L_ALERT","SIP De-Registration for $fu - Terminating N5 AppSession\n"); + # Retrieve the AppSession Id from the hash table + $var(user_id_dereg) = $fU; + $var(user_appsess_dereg) = $sht(user_data=>$var(user_id_dereg)); + xlog("L_INFO", "Terminating stored AppSession for user $var(user_id_dereg): $var(user_appsess_dereg)\n"); + $var(headers) = "X-SIP-Status: De-Registration\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n"; + $var(headers) = $var(headers) + "accept: application/json\r\n"; + $var(headers) = $var(headers) + "accept: application/problem+json\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-max-rsp-time: 10000\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-discovery-service-names: npcf-policyauthorization\r\n"; + $var(headers) = $var(headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now); + + http_client_request_v2pk("POST", "http://172.22.0.27:7777/npcf-policyauthorization/v1/app-sessions/$var(user_appsess_dereg)/delete", "$var(json_request)", "$var(headers)", "$var(result)" ); + xlog("Termination resuls: $var(result)\n"); + xlog("L_ALERT", "cURL response: $curlerror(error)\n"); + xlog("L_INFO", "HTTP results: $var(result)\n"); + xlog("L_INFO", "HTTP response: $rc\n"); + xlog("L_INFO", "Location Header: $httprhdr(location)\n"); } + +#!endif