###################################################################### # Originating, Intial Requests ###################################################################### 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"); # Process route headers, if any: loose_route(); if (!pcscf_is_registered("location")) { send_reply("403","Forbidden - You must register first with a S-CSCF"); exit; } # We do not trust the user, let's remove the P-Asserted-Identity, if any: remove_hf("P-Asserted-Identity"); remove_hf("P-Preferred-Identity"); # Add P-Charging-Vector sip_p_charging_vector("g"); if (is_present_hf("P-Preferred-Identity") && pcscf_assert_identity("location", "$hdr(P-Preferred-Identity)") && $hdr(P-Preferred-Identity) =~ "sip:.*") { append_hf("P-Asserted-Identity: $hdr(P-Preferred-Identity)\r\n"); } else if (is_present_hf("P-Asserted-Identity") && pcscf_assert_identity("location", "$hdr(P-Asserted-Identity)") && $hdr(P-Asserted-Identity) =~ "sip:.*") { append_hf("P-Asserted-Identity: $hdr(P-Asserted-Identity)\r\n"); } else if (pcscf_assert_identity("location", "$(fu{tobody.uri})")) { # For broken SIP implementation in Samsung devices if ($fu =~ "tel:.*") { $var(new_hdr) = $(fu{tobody.uri}) + "@NETWORKNAME"; $var(new_hdr) = $(var(new_hdr){re.subst,/tel:/sip:/g}); append_hf("P-Asserted-Identity: <$var(new_hdr)>\r\n"); $fu = $var(new_hdr); } else { append_hf("P-Asserted-Identity: <$(fu{tobody.uri})>\r\n"); } } else { append_hf("P-Asserted-Identity: <$pcscf_asserted_identity>\r\n"); } if (!pcscf_follows_service_routes("location")){ #Variant 1 - deny access to the network #send_reply("400","Bad Request - Not following indicated service routes"); #break; #Variant 2 - enforce routes and let the dialog continue pcscf_force_service_routes("location"); } # add IBCF/THIG route here if required # Check for "sec-agree" in the Require header: if (is_present_hf("Require") && $hdr(Require) =~ ".*sec-agree.*") { # Remove the old Require-Header: remove_hf("Require"); # Replace ", sec-agree" with "" $var(new_hdr) = $(hdr(Require){re.subst,/[, ]*sec-agree//gi}); if ($(var(new_hdr){s.len}) > 0) { append_hf("Require: $var(new_hdr)\r\n"); } } # 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_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"); #!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_hf("Feature-Caps"); append_hf("Feature-Caps: $hdr(Feature-Caps);+g.3gpp.trf=\"\"\r\n"); } else { append_hf("Feature-Caps: *;+g.3gpp.trf=\"\"\r\n"); } #!endif # Add a visited Network-ID-Header: if (is_present_hf("P-Visited-Network-ID")) { $var(new_hdr) = "NETWORKNAME, "+$hdr(P-Visited-Network-ID); append_hf("P-Visited-Network-ID: $var(new_hdr)\r\n"); } else { append_hf("P-Visited-Network-ID: NETWORKNAME\r\n"); } set_dlg_profile("orig"); t_on_reply("MO_reply"); } #!ifdef WITH_N5 # Route Logic for N5 Requests route[N5_INIT_REQ] { # 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; 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"); $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(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"); # 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); 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"); $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"); $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"); $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"); # 5G VoNR N5 NPCF Authorization request xlog("L_DBG", "IMS: INVITE ORIG TO $tU\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"); $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"); # 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"); $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"); # Build the N5 Request xlog("L_INFO","Preparing QoS N5 Message to PCF for the INVITE\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)"); # 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)"); 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"); # 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)" # 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}) == "/") { break; } } # 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)}); xlog("L_INFO", "AppSession Id for user $fU is: $var(app_session)\n"); $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; } } #!endif ###################################################################### # Replies to Originating Initial Requests ###################################################################### 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"); if (is_present_hf("C-Params")) { remove_hf("Contact"); remove_hf("C-Params"); append_hf("Contact: $ct;$hdr(C-Params)\r\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_INFO", "Dropping retransmitted reply which is still currently suspended\n"); drop(); } route(N5_PATCH_REQ); } # 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"); $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 # In case of 1xx and 2xx do NAT if(status=~"[12][0-9][0-9]") route(NATMANAGE); #!ifdef WITH_RX 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","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; } } } route[MO_aar_reply] { # 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; } } #!endif } ###################################################################### # In-Dialog-Mo-Requests ###################################################################### route[MO_indialog] { #!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 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"); $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"); setflag(FLT_MOBILE_ORIG); t_on_reply("MO_indialog_reply"); # 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); } } #!endif } 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"); #!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 # In case of 1xx and 2xx do NAT if(status=~"[12][0-9][0-9]") route(NATMANAGE); #!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", "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; } } } route[MO_indialog_aar_reply] { # 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; } } #!endif } #!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"); # 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(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)"); # 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)"); # 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-$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; default: xlog("L_ERR", "N5 QoS Session modification faild - reason code: $rc\n"); send_reply("412", "MOC N5 QoS Session modify faild"); exit; } } #!endif