35 Commits

Author SHA1 Message Date
herlesupreeth
46d6f8f3c1 Update srsRAN_Project commit, fixing VoNR calling issue 2025-02-19 17:52:22 +01:00
herlesupreeth
0ef73a943a Configure name for docker network and volumes 2025-01-11 20:06:02 +01:00
herlesupreeth
f0df0e220a Remove TUN interface name from SMF configuration files 2025-01-11 16:49:03 +01:00
herlesupreeth
89b24759a3 Use latest commits of open5gs repo 2025-01-11 16:31:52 +01:00
herlesupreeth
d779b57644 Minor refactor and cosmetic changes in PCSCF cfg files 2024-12-31 13:53:16 +01:00
herlesupreeth
e73e1c32af Use latest srsRAN QoS configuration file 2024-12-26 20:38:15 +01:00
Nacho Mata
eb5c8fc687 Use latest srsRAN gnb config file syntax (#398) 2024-12-13 19:05:45 +01:00
herlesupreeth
9d36c45e9d Use latest srsRAN code containing fix for VoNR call 2024-12-12 17:43:07 +01:00
Abdulkarim Barbour
1f8a419635 fix RTP/RTCP Port in N5 Request on term side (#391)
* fix RTP/RTCP Port in N5 Request

Fix storing and retrieving SDP RTP/RTCP Ports from Orig User on term side

* fix RTP/RTCP Port in N5 Request

Fix storing and retrieving SDP RTP/RTCP Ports from Orig User on term side
2024-11-18 20:11:13 +01:00
Abdulkarim Barbour
9560e618b4 optimizing the N5 routing Logic more (#389)
* Improving N5 Routing Logic

Change NFType to "AF"

* Improving N5 Routing Logic

Change NFType to "AF" to comply with 3GPP

* Improving N5 Routing Logic

Add failing condition in case QoS N5 fails 
Remove/adjust logging to console
Improving the request sent to PCF

* Improving N5 Routing Logic

Add failing condition in case QoS N5 fails 
Remove/adjust logging to console
Improving the request sent to PCF

* Improving N5 Routing Logic

Add failing condition in case QoS N5 fails 
Remove/adjust logging to console
Improving the request sent to PCF

* set maxcontact to one

set maxcontact to one
2024-11-14 19:12:32 +01:00
herlesupreeth
6b6cd6f95a Use ubuntu jammy image for building UERANSIM 2024-08-29 16:03:00 +02:00
NUCLEAR-WAR
12c29605d4 adding QoS N5 to MT Routing
adding QoS N5 to MT Routing to enable N5 QoS on Term UE
2024-08-26 08:47:00 +02:00
herlesupreeth
1644fc8554 Change subnet configuration as per new format in open5gs 2024-08-22 10:07:39 +02:00
herlesupreeth
68c44433c1 Change logging configuration as per new format for open5gs components 2024-08-22 09:49:15 +02:00
herlesupreeth
b4c9492b39 Encompass N5 HTTP2 code with ifdef 2024-08-12 10:32:41 +02:00
NUCLEAR-WAR
726dc91b7a removing unnecessary log outputs 2024-08-12 08:19:35 +02:00
NUCLEAR-WAR
36b0191cbe moving the N5 Route logic to its own Route and improve it
move the INIT Req to its own route
move the modify req into its own logic
adding calls to the suitable logic ( INIT Req, ReqReply, Indialog req) in the suitable routeing block
2024-08-12 08:19:35 +02:00
NUCLEAR-WAR
3915449019 add content-type for PATCH Method and some minor changes
added content-type to the patch method to be compatible with RFC7386 and soem other minor changes
2024-08-12 08:19:35 +02:00
NUCLEAR-WAR
ac0252d636 added the N5 to the initial INVITE
added the N5 to the initial INVITE and then update the session with HTTP PATCH after receiving 180/183/200/ with SDP.
2024-08-12 08:19:35 +02:00
NUCLEAR-WAR
e29d02828d Update mo.cfg 2024-08-12 08:19:35 +02:00
NUCLEAR-WAR
c693732158 remove names fom code 2024-08-12 08:18:50 +02:00
NUCLEAR-WAR
2379624b2c adding another two HTable to store SIP connectivity Infos
adding another two HTable to store SIP connectivity Infos to associate users to there IP Addresses and save them in the Htable.
2024-08-12 08:18:50 +02:00
NUCLEAR-WAR
6abee093a6 Update kamailio_pcscf.cfg 2024-08-12 08:18:50 +02:00
NUCLEAR-WAR
c361c21a03 move N5 logic to its own route block and call to it from other logics
moved both N5 creation and deletion requests to own route block.
add calls to the N5 route logic in the main route where needed.
change SuppFeat to 2 instead of 4
2024-08-12 08:14:29 +02:00
NUCLEAR-WAR
8991a2e3b2 Update register.cfg 2024-08-12 08:14:29 +02:00
herlesupreeth
b11e54131b Use latest code from open5gs, srsRAN_4G and srsRAN_Project repo 2024-08-11 18:45:23 +02:00
herlesupreeth
75617b97c0 Enable N5 interface only in 5G deployment 2024-08-11 17:59:47 +02:00
herlesupreeth
bf83a12165 Remove pyHSS db fix patch file 2024-08-11 17:48:56 +02:00
herlesupreeth
019496f103 Use latest tag for pyHSS 2024-08-11 17:47:06 +02:00
herlesupreeth
3cc94c912d Use latest commits from pyHSS 2024-08-11 17:47:04 +02:00
herlesupreeth
3b2c22dfab Change log levels of osmomsc and osmohlr to debug 2024-08-11 17:41:33 +02:00
herlesupreeth
f1d55deef0 Fix SGsAP functioning with latest osmomsc and omsohlr 2024-08-11 16:18:03 +02:00
herlesupreeth
14911cc6a2 Add NRF-NFM subscription for PCF registration notification 2024-08-06 08:49:52 +02:00
herlesupreeth
3f4b520acb Support NRF-NFM in P-CSCF 2024-08-06 08:49:41 +02:00
herlesupreeth
5c2a2f58af Add HTTP2 server and HTTP client module initialization for N5 support 2024-08-06 08:49:12 +02:00
55 changed files with 1683 additions and 367 deletions

View File

@@ -338,9 +338,14 @@ services:
ipv4_address: ${GRAFANA_IP}
networks:
default:
name: docker_open5gs_default
ipam:
config:
- subnet: ${TEST_NETWORK}
volumes:
mongodbdata: {}
dbdata: {}
grafana_data:
name: grafana_data
mongodbdata:
name: docker_open5gs_mongodbdata
dbdata:
name: docker_open5gs_dbdata

View File

@@ -474,9 +474,14 @@ services:
ipv4_address: ${GRAFANA_IP}
networks:
default:
name: docker_open5gs_default
ipam:
config:
- subnet: ${TEST_NETWORK}
volumes:
mongodbdata: {}
dbdata: {}
grafana_data:
name: grafana_data
mongodbdata:
name: docker_open5gs_mongodbdata
dbdata:
name: docker_open5gs_dbdata

View File

@@ -63,6 +63,7 @@ docker build --no-cache --force-rm -t docker_ueransim .
cd ..
set -a
source .env
set +a
sudo ufw disable
sudo sysctl -w net.ipv4.ip_forward=1
sudo cpupower frequency-set -g performance

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/amf.log
file:
path: /open5gs/install/var/log/open5gs/amf.log
sbi:
server:

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/ausf.log
file:
path: /open5gs/install/var/log/open5gs/ausf.log
sbi:
server:

View File

@@ -68,7 +68,7 @@ RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg -
# Get open5gs code and install
RUN git clone --recursive https://github.com/open5gs/open5gs && cd open5gs && \
git checkout 322719f3e729aafacf531e85552d7a977fff3e2a && meson build --prefix=`pwd`/install && \
git checkout 04ec945e1d334ca5917705a885eff80ad30e1e38 && meson build --prefix=`pwd`/install && \
ninja -C build && cd build && ninja install && \
mkdir -p /open5gs/install/include

View File

@@ -1,7 +1,8 @@
db_uri: mongodb://MONGO_IP/open5gs
logger:
file: /open5gs/install/var/log/open5gs/bsf.log
file:
path: /open5gs/install/var/log/open5gs/bsf.log
sbi:
server:

View File

@@ -682,9 +682,15 @@ services:
ipv4_address: ${GRAFANA_IP}
networks:
default:
name: docker_open5gs_default
ipam:
config:
- subnet: ${TEST_NETWORK}
volumes:
mongodbdata: {}
dbdata: {}
grafana_data:
name: grafana_data
mongodbdata:
name: docker_open5gs_mongodbdata
dbdata:
name: docker_open5gs_dbdata

View File

@@ -173,7 +173,7 @@ TLS_CA = "/open5gs/install/etc/freeDiameter/cacert.pem";
# algorithms. In addition the "0xffffff" application is advertised in CER/CEA
# exchanges.
# Default: Relaying is enabled.
#NoRelay;
NoRelay;
# Number of server threads that can handle incoming messages at the same time.
# Default: 4

View File

@@ -1,7 +1,8 @@
db_uri: mongodb://MONGO_IP/open5gs
logger:
file: /open5gs/install/var/log/open5gs/hss.log
file:
path: /open5gs/install/var/log/open5gs/hss.log
global:
max:

View File

@@ -34,7 +34,7 @@ RUN apt-get update && \
gcc flex bison libmysqlclient-dev make libssl-dev libcurl4-openssl-dev \
libxml2-dev libpcre2-dev bash-completion g++ autoconf libmnl-dev \
libsctp-dev libradcli-dev libradcli4 libjson-c-dev pkg-config iproute2 net-tools \
iputils-ping libgcrypt20-dev libjansson-dev libevent-dev libnghttp2-dev
iputils-ping libgcrypt20-dev libjansson-dev libevent-dev libnghttp2-dev uuid-dev
# Fetch Kamailio code
RUN mkdir -p /usr/local/src/ && cd /usr/local/src/ && \

View File

@@ -7,7 +7,7 @@ modules_dirs:=modules
cfg_group_include=
# the list of extra modules to compile
include_modules= cdp cdp_avp db_mysql dialplan enum http_async_client http_client ims_auth ims_charging ims_dialog ims_diameter_server ims_icscf ims_ipsec_pcscf ims_isc ims_ocs ims_qos ims_registrar_pcscf ims_registrar_scscf ims_usrloc_pcscf ims_usrloc_scscf jansson json nghttp2 outbound presence presence_conference presence_dialoginfo presence_mwi presence_profile presence_reginfo presence_xml pua pua_bla pua_dialoginfo pua_reginfo pua_rpc pua_usrloc pua_xmpp sctp tls utils xcap_client xcap_server xmlops xmlrpc
include_modules= cdp cdp_avp db_mysql dialplan enum http_async_client http_client ims_auth ims_charging ims_dialog ims_diameter_server ims_icscf ims_ipsec_pcscf ims_isc ims_ocs ims_qos ims_registrar_pcscf ims_registrar_scscf ims_usrloc_pcscf ims_usrloc_scscf jansson json nghttp2 outbound presence presence_conference presence_dialoginfo presence_mwi presence_profile presence_reginfo presence_xml pua pua_bla pua_dialoginfo pua_reginfo pua_rpc pua_usrloc pua_xmpp sctp tls utils uuid xcap_client xcap_server xmlops xmlrpc
# the list of static modules
static_modules=
@@ -16,7 +16,7 @@ static_modules=
skip_modules=
# the list of modules to exclude from compile list
exclude_modules= malloc_test app_sqlang acc_json acc_radius app_java app_lua app_lua_sr app_mono app_perl app_python app_python3 app_python3s app_ruby app_ruby_proc auth_ephemeral auth_identity auth_radius cnxcc cplc crypto db2_ldap db_berkeley db_cassandra db_mongodb db_oracle db_perlvdb db_postgres db_redis db_sqlite db_unixodbc dnssec erlang evapi geoip geoip2 gzcompress h350 janssonrpcc jsonrpcc jwt kafka kazoo lcr ldap log_systemd lost lwsc memcached microhttpd misc_radius mqtt nats ndb_cassandra ndb_mongodb ndb_redis nsq osp peering phonenum rabbitmq regex rls rtp_media_server ruxc secsipid secsipid_proc slack snmpstats stirshaken systemdops tls_wolfssl tlsa topos_redis uuid websocket xhttp_pi xmpp $(skip_modules)
exclude_modules= malloc_test app_sqlang acc_json acc_radius app_java app_lua app_lua_sr app_mono app_perl app_python app_python3 app_python3s app_ruby app_ruby_proc auth_ephemeral auth_identity auth_radius cnxcc cplc crypto db2_ldap db_berkeley db_cassandra db_mongodb db_oracle db_perlvdb db_postgres db_redis db_sqlite db_unixodbc dnssec erlang evapi geoip geoip2 gzcompress h350 janssonrpcc jsonrpcc jwt kafka kazoo lcr ldap log_systemd lost lwsc memcached microhttpd misc_radius mqtt nats ndb_cassandra ndb_mongodb ndb_redis nsq osp peering phonenum rabbitmq regex rls rtp_media_server ruxc secsipid secsipid_proc slack snmpstats stirshaken systemdops tls_wolfssl tlsa topos_redis websocket xhttp_pi xmpp $(skip_modules)
modules_all= $(filter-out modules/CVS,$(wildcard modules/*))
modules_noinc= $(filter-out $(addprefix modules/, $(exclude_modules) $(static_modules)), $(modules_all))

View File

@@ -174,7 +174,7 @@ TLS_CA = "/open5gs/install/etc/freeDiameter/cacert.pem";
# algorithms. In addition the "0xffffff" application is advertised in CER/CEA
# exchanges.
# Default: Relaying is enabled.
#NoRelay;
NoRelay;
# Number of server threads that can handle incoming messages at the same time.
# Default: 4

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/mme.log
file:
path: /open5gs/install/var/log/open5gs/mme.log
global:
max:

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/nrf.log
file:
path: /open5gs/install/var/log/open5gs/nrf.log
sbi:
server:

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/nssf.log
file:
path: /open5gs/install/var/log/open5gs/nssf.log
sbi:
server:

View File

@@ -39,4 +39,4 @@ RUN wget $OSMOCOM_REPO/Release.key && \
apt-get update && apt-get install -f && apt-get --install-suggests -y install osmo-hlr
CMD /mnt/osmohlr/osmohlr_init.sh && \
cd /mnt/osmohlr && /usr/bin/osmo-hlr -c /etc/osmocom/osmo-hlr.cfg
cd /mnt/osmohlr && /usr/bin/osmo-hlr -c /etc/osmocom/osmo-hlr.cfg --db-upgrade

View File

@@ -16,5 +16,6 @@ line vty
ctrl
bind 127.0.0.1
hlr
subscriber-create-on-demand 5 cs+ps
gsup
bind ip OSMOHLR_IP

View File

@@ -1,11 +1,17 @@
!
! OsmoMSC configuration saved from vty
!
log stderr
logging filter all 1
logging color 1
logging print category 1
logging timestamp 1
logging print extended-timestamp 1
logging level all debug
logging level linp error
!
line vty
no login
bind 127.0.0.1
ctrl
bind 127.0.0.1
!
network
network country code MCC
@@ -15,6 +21,17 @@ network
encryption a5 0
rrlp mode none
mm info 1
mgw 0
remote-ip 127.0.0.1
remote-port 2427
local-port 2728
cs7 instance 0
point-code 0.23.1
asp asp-clnt-OsmoMSC-A-Iu 2905 0 m3ua
! where to reach the STP:
remote-ip 127.0.0.5
role asp
sctp-role client
msc
assign-tmsi
auth-tuple-max-reuse-count 3

View File

@@ -1,7 +1,8 @@
db_uri: mongodb://MONGO_IP/open5gs
logger:
file: /open5gs/install/var/log/open5gs/pcf.log
file:
path: /open5gs/install/var/log/open5gs/pcf.log
sbi:
server:

View File

@@ -175,7 +175,7 @@ TLS_CA = "/open5gs/install/etc/freeDiameter/cacert.pem";
# algorithms. In addition the "0xffffff" application is advertised in CER/CEA
# exchanges.
# Default: Relaying is enabled.
#NoRelay;
NoRelay;
# Number of server threads that can handle incoming messages at the same time.
# Default: 4

View File

@@ -1,7 +1,8 @@
db_uri: mongodb://MONGO_IP/open5gs
logger:
file: /open5gs/install/var/log/open5gs/pcrf.log
file:
path: /open5gs/install/var/log/open5gs/pcrf.log
global:
max:

View File

@@ -228,6 +228,13 @@ loadmodule "cdp_avp"
loadmodule "ims_qos"
#!endif
#!ifdef WITH_N5
loadmodule "http_client"
loadmodule "jansson"
loadmodule "nghttp2"
loadmodule "uuid"
#!endif
#!ifdef CAPTURE_NODE
loadmodule "siptrace"
#!endif
@@ -433,6 +440,35 @@ modparam("ims_qos", "recv_mode", 1)
modparam("ims_qos", "dialog_direction", RX_IMS_REG_DIALOG_DIRECTION)
#!endif
#!ifdef WITH_N5
# Tables to store users and their session details
modparam("htable", "htable", "user_data=>size=8;autoexpire=3600;")
modparam("htable", "htable", "user_ids=>size=8;autoexpire=3600;")
modparam("htable", "htable", "user_sdps_ip=>size=8;autoexpire=3600;")
modparam("htable", "htable", "user_sdps_port=>size=8;autoexpire=3600;")
modparam("htable", "htable", "user_sdps_rtcp_port=>size=8;autoexpire=3600;")
modparam("htable", "htable", "user_sip_ips=>size=8;autoexpire=3600;")
modparam("htable", "htable", "user_sip_ports=>size=8;autoexpire=3600;")
# HTTP2 for 5G -- Modules Parameters
modparam("http_client", "httpredirect", 1)
modparam("http_client", "useragent", "AF")
modparam("http_client", "maxdatasize", 64535)
modparam("http_client", "connection_timeout", 2)
modparam("http_client", "keep_connections", 1)
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 e.g. Open5gs PCF
# modparam("nghttp2", "tls_private_key", "/mnt/pcscf/http2_key.pem")
# modparam("nghttp2", "tls_public_key", "/mnt/pcscf/http2_tr.pem")
modparam("rtimer", "timer", "name=NRF_NFM;interval=5;mode=1;")
modparam("rtimer", "exec", "timer=NRF_NFM;route=NRF_NFM")
#!endif
# -- pua params --
#!ifdef WITH_REGINFO
#!ifdef DB_URL
@@ -474,9 +510,6 @@ modparam("statistics", "variable", "register_success")
modparam("statistics", "variable", "register_failed")
modparam("statistics", "variable", "register_time")
####### Routing Logic ########
# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
route {
@@ -961,7 +994,7 @@ route[preload_pcscf] {
$shv(preload_pcscf) = 1;
sql_query("pcscf", "select aor, received, received_port, received_proto from location;", "resultset");
xlog("Preloading NAT-PING. Rows: $dbr(resultset=>rows)\n");
xlog("L_INFO", "Preloading NAT-PING. Rows: $dbr(resultset=>rows)\n");
if($dbr(resultset=>rows)>0) {
$var(i) = 0;
while($var(i) < $dbr(resultset=>rows)) {
@@ -983,6 +1016,177 @@ route[preload_pcscf] {
}
#!endif
#!ifdef WITH_N5
# 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
if ($nghttp2(path) == "/nf-status-notify") {
nghttp2_reply_header("Content-Type", "text/html");
nghttp2_reply_header("Server:", "AF");
nghttp2_reply("200", "<html><body>PCF registered at PCSCF</body></html>");
} else if ($nghttp2(path) == "/terminate") {
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("204", "No Content");
} else {
# 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("404", "Not Found");
}
}
route[NRF_NFM] {
if ($var(n5_hb_fail_count) > 5) {
xlog("L_ERR", "PCSCF NF no longer registered at SCP. Re-attempting registration!!\n");
$var(n5_initalized) = 0;
}
$var(time_now) = $_s($timef(%a, %d %b %Y %H:%M:%S %Z));
# TODO: Send at heartbeat intervals received in reponse to NF registration
if ($var(n5_initalized) == 1) {
# Send Heartbeat
$var(nf_hb_headers) = "content-type: application/json-patch+json\r\n";
$var(nf_hb_headers) = $var(nf_hb_headers) + "accept: application/json,application/problem+json\r\n";
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n";
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-max-rsp-time: 10000\r\n";
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-discovery-service-names: nnrf-nfm\r\n";
$var(nf_hb_headers) = $var(nf_hb_headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now);
$var(nf_hb_json_body) ='[]';
$var(nf_hb_body) = '{
"op": "replace",
"path": "/nfStatus",
"value": "REGISTERED"
}';
jansson_append("obj", "", $var(nf_hb_body), "$var(nf_hb_json_body)");
$var(nf_hb_body) = '{
"op": "replace",
"path": "/load",
"value": 0
}';
jansson_append("obj", "", $var(nf_hb_body), "$var(nf_hb_json_body)");
http_client_request_v2pk("PATCH", "http://SCP_BIND_IP:SCP_BIND_PORT/nnrf-nfm/v1/nf-instances/$var(pcscf_uuid)", "$var(nf_hb_json_body)", "$var(nf_hb_headers)", "$var(nf_hb_result)");
switch ($rc) {
case 204:
$var(n5_hb_fail_count) = 0;
break;
default:
$var(n5_hb_fail_count) = $var(n5_hb_fail_count) + 1;
return;
}
return;
}
# Generate UUID for PCSCF
$var(pcscf_uuid) = $uuid(g);
# Register NF
$var(nf_reg_headers) = "content-type: application/json\r\n";
$var(nf_reg_headers) = $var(nf_reg_headers) + "accept: application/json,application/problem+json\r\n";
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n";
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-max-rsp-time: 10000\r\n";
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-discovery-service-names: nnrf-nfm\r\n";
$var(nf_reg_headers) = $var(nf_reg_headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now);
$var(nf_reg_body) = '{
"nfInstanceId": "PCSCF_UUID",
"nfType": "AF",
"nfStatus": "REGISTERED",
"ipv4Addresses": ["N5_BIND_IP"],
"allowedNfTypes": ["SCP", "PCF"],
"priority": 0,
"capacity": 100,
"load": 0,
"nfServiceList": {
"PCSCF_UUID": {
"serviceInstanceId": "PCSCF_UUID",
"serviceName": "npcf-policyauthorization",
"versions": [
{
"apiVersionInUri": "v2",
"apiFullVersion": "2.0.0"
}
],
"scheme": "http",
"nfServiceStatus": "REGISTERED",
"ipEndPoints": [
{
"ipv4Address": "N5_BIND_IP",
"port": N5_BIND_PORT
}
],
"allowedNfTypes": [
"PCF"
],
"priority": 0,
"capacity": 100,
"load": 0
}
},
"nfProfileChangesSupportInd": true
}';
$var(nf_reg_body) = $(var(nf_reg_body){re.subst,/PCSCF_UUID/$var(pcscf_uuid)/g});
jansson_append("obj", "", "$var(nf_reg_body)", "$var(nf_reg_json_body)");
http_client_request_v2pk("PUT", "http://SCP_BIND_IP:SCP_BIND_PORT/nnrf-nfm/v1/nf-instances/$var(pcscf_uuid)", "$var(nf_reg_json_body)", "$var(nf_reg_headers)", "$var(nf_reg_result)");
switch ($rc) {
case 201:
xlog("L_INFO", "P-CSCF NF registered successfully at SCP\n");
$var(n5_initalized) = 1;
$var(n5_hb_fail_count) = 0;
route(NRF_NFM_SUBSCRIBE_PCF);
break;
default:
xlog("L_ERR", "P-CSCF NF failed to register at SCP with code=$rc\n");
return;
}
}
route[NRF_NFM_SUBSCRIBE_PCF] {
# Subscribe to PCF NF registration notification
$var(time_now) = $_s($timef(%a, %d %b %Y %H:%M:%S %Z));
$var(pcf_subc_headers) = "content-type: application/json\r\n";
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "accept: application/json,application/problem+json\r\n";
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-discovery-target-nf-type: NRF\r\n";
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-callback: Nnrf_NFManagement_NFStatusNotify\r\n";
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-max-rsp-time: 10000\r\n";
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-discovery-service-names: nnrf-nfm\r\n";
$var(pcf_subc_headers) = $var(pcf_subc_headers) + "3gpp-sbi-sender-timestamp: " + $var(time_now);
$var(pcf_subc_body) = '{
"nfStatusNotificationUri": "http://N5_BIND_IP:N5_BIND_PORT/nnrf-nfm/v1/nf-status-notify",
"reqNfInstanceId": "PCSCF_UUID",
"subscrCond": {
"nfType": "PCF"
},
"reqNfType": "AF",
"requesterFeatures": "1"
}';
$var(pcf_subc_body) = $(var(pcf_subc_body){re.subst,/PCSCF_UUID/$var(pcscf_uuid)/g});
jansson_append("obj", "", "$var(pcf_subc_body)", "$var(pcf_subc_json_body)");
http_client_request_v2pk("POST", "http://SCP_BIND_IP:SCP_BIND_PORT/nnrf-nfm/v1/subscriptions", "$var(pcf_subc_json_body)", "$var(pcf_subc_headers)", "$var(pcf_subc_result)");
switch ($rc) {
case 201:
xlog("L_INFO", "P-CSCF NF subscribed for PCF NF registration notification\n");
break;
default:
xlog("L_ERR", "P-CSCF NF failed to subscribe for PCF NF registration notification\n");
return;
}
}
#!endif
#!ifdef WITH_XMLRPC
include_file "route/xmlrpc.cfg"
#!endif

View File

@@ -36,6 +36,15 @@ listen=tcp:PCSCF_IP:5060
# Uncomment the below line only when UE is behind double NAT (e.g. VoIP calling over WiFi/ CN behind a NAT)
##!define RX_AF_SIGNALING_IP "PCSCF_PUB_IP"
# IP and Port for incoming requests over N5 from 5G Core
#!substdef "/N5_BIND_IP/PCSCF_IP/g"
#!substdef "/N5_BIND_PORT/7777/g"
# SCP IP and Port for NF registration and heartbeat
#!substdef "/SCP_BIND_IP/SCP_IP/g"
#!substdef "/SCP_BIND_PORT/7777/g"
alias=pcscf.IMS_DOMAIN
#!define MY_WS_PORT 80
@@ -45,9 +54,9 @@ alias=pcscf.IMS_DOMAIN
#!define TCP_PROCESSES 8
#!subst "/NETWORKNAME/IMS_DOMAIN/"
#!subst "/HOSTNAME/pcscf.IMS_DOMAIN/"
#!subst "/PCRF_REALM/EPC_DOMAIN/"
#!subst "/NETWORKNAME/IMS_DOMAIN/g"
#!subst "/HOSTNAME/pcscf.IMS_DOMAIN/g"
#!subst "/PCRF_REALM/EPC_DOMAIN/g"
# SIP-Address of capturing node, if not set, capturing is disabled.
##!define CAPTURE_NODE "sip:127.0.0.1:9060"
@@ -125,8 +134,7 @@ alias=pcscf.IMS_DOMAIN
##!define WITH_IPBLOCK
##!define WITH_ANTIFLOOD
#!define WITH_RX
#!define WITH_RX_REG
#!define WITH_RX_CALL
##!define WITH_N5
#!define WITH_TCP
##!define WITH_RTPIPV4
##!define WITH_SBC

View File

@@ -70,11 +70,11 @@ fi
if [[ ${DEPLOY_MODE} == 5G ]];
then
sed -i 's|#!define WITH_RX\b|##!define WITH_RX|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|#!define WITH_RX_REG\b|##!define WITH_RX_REG|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|#!define WITH_RX_CALL\b|##!define WITH_RX_CALL|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|##!define WITH_N5\b|#!define WITH_N5|g' /etc/kamailio_pcscf/pcscf.cfg
fi
sed -i 's|PCSCF_IP|'$PCSCF_IP'|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|SCP_IP|'$SCP_IP'|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|PCSCF_PUB_IP|'$PCSCF_PUB_IP'|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' /etc/kamailio_pcscf/pcscf.cfg
sed -i 's|EPC_DOMAIN|'$EPC_DOMAIN'|g' /etc/kamailio_pcscf/pcscf.cfg

View File

@@ -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,27 +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");
#!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=\"<sip:$var(trf);lr>\"\r\n");
} else {
} else {
append_hf("Feature-Caps: *;+g.3gpp.trf=\"<sip:$var(trf);lr>\"\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);
@@ -97,75 +103,355 @@ route[MO]
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");
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");
}
#!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")){
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
}
######################################################################
# 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");
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");
@@ -176,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);
}
}
@@ -185,9 +471,21 @@ 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
# In case of 1xx and 2xx do NAT
if(status=~"[12][0-9][0-9]")
@@ -196,39 +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
}
#!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

View File

@@ -2,13 +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");
set_dlg_profile("term");
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");
}
@@ -17,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");
}
@@ -28,51 +37,69 @@ onreply_route[MT_reply] {
# 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")){
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
}
@@ -81,32 +108,60 @@ route[MT_aar_reply]
# In-Dialog-MT-Requests
######################################################################
route[MT_indialog] {
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);
#!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
if (is_method("BYE|CANCEL")) {
xlog("L_INFO"," InDialog Call End/Cancel/Error. Terminating N5 QoS Session\n");
route(N5_MTC_TERM);
}
#!endif
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");
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
# In case of 1xx and 2xx do NAT
if(status=~"[12][0-9][0-9]")
route(NATMANAGE);
@@ -119,34 +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
}
#!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
$var(term_ue_ip) = $dd;
$var(term_sip_ue_port) = $rp;
$var(pcscf_sip_ip) = $Ri;
$var(pcscf_sip_port) = $Rp;
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");
$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");
$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");
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);
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);
$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");
$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(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);
$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");
xlog("L_INFO", "Preparing QoS N5 Message to PCF for INVITE To term UE\n");
$var(events) = '[]';
$var(medComponents) = '{}';
$var(medSubComps) = '{}';
$var(evSubsc) = '{}';
$var(payload) = '{}';
# 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)");
# 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)");
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");
# 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}) == "/") {
# We've found the last slash
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(mtc_app_session) = $(var(url){s.substr,$var(start_pos),$var(substring_length)});
xlog("L_INFO", "AppSession Id for user $tU is: $var(mtc_app_session)\n");
$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;
}
}
# 5G VoNR N5 Policy Authorization PATCH request
route[N5_PATCH_MT_REQ] {
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");
$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_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");
# 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");
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 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;
default:
xlog("L_ERR", "N5 QoS Session modification faild - reason code: $rc\n");
send_reply("412", "MTC N5 QoS Session modify faild");
exit;
}
}
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");
# 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);
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

View File

@@ -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,6 +21,21 @@ route[REGISTER] {
exit;
}
#!ifdef WITH_N5
$var(reg_exp) = $expires(min);
xlog("L_INFO","Expire for $fu is :$var(reg_exp)\n");
# 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;
if ($hdr(Security-Client) =~ ".*ipsec-3gpp.*") {
@@ -257,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) {
@@ -284,9 +299,9 @@ onreply_route[REGISTER_reply]
}
xnotice("New header - WWW-Authenticate=$var(new_hdr)\n");
}
}
}
#!endif
}
}
exit;
}
@@ -294,6 +309,14 @@ onreply_route[REGISTER_reply]
######################################################################
failure_route[REGISTER_failure]
{
#!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]")) {
if ($sht(failedauth=>$si) != $null)
@@ -305,12 +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
# 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");
$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 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)");
# 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", "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)");
# 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);
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");
# 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)"
# 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);
# 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
$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)});
xlog("L_INFO", "AppSession Id for user $au is: $var(app_session)\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");
$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;
}
}
# N5 Policy Authorization - Application session termination for SIP De-registration
route[REG_N5_TERMINATE]
{
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

View File

@@ -41,12 +41,20 @@ RUN apt-get update && \
libmysqlclient-dev \
libsctp-dev \
gcc \
mysql-server
mysql-server \
lsb-release \
curl \
gpg
RUN curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg && \
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/redis.list && \
apt-get update && \
apt-get install -y --no-install-recommends redis
# Get pyhss code and install
RUN git clone https://github.com/nickvsnetworking/pyhss && \
cd pyhss && git checkout fa059d56330f6e565a9b546d5a9ed4071c2c9ab6
cd pyhss && git checkout tags/1.0.2
RUN cd pyhss && pip3 install -r requirements.txt
RUN mkdir -p /pyhss/log/

View File

@@ -1,5 +1,7 @@
## HSS Parameters
hss:
# Transport Type. "TCP" and "SCTP" are valid options.
# Note: SCTP works but is still experimental. TCP has been load-tested and performs in a production environment.
transport: "TCP"
#IP Addresses to bind on (List) - For TCP only the first IP is used, for SCTP all used for Transport (Multihomed).
bind_ip: ["PYHSS_IP"]
@@ -30,17 +32,14 @@ hss:
#IMSI of Test Subscriber for Unit Checks (Optional)
test_sub_imsi: '001021234567890'
#Device Watchdog Request Interval (In Seconds - If set to 0 disabled)
device_watchdog_request_interval: 5
#Async Queue Check Interval (In Seconds - If set to 0 disabled)
async_check_interval: 0
#The maximum time to wait, in seconds, before disconnecting a client when no data is received.
client_socket_timeout: 120
#The maximum amount of times a failed diameter response/query should be resent before considering the peer offline and terminating their connection
diameter_max_retries: 1
#The maximum time to wait, in seconds, before discarding a diameter request.
diameter_request_timeout: 3
#The amount of time, in seconds, before purging a disconnected client from the Active Diameter Peers key in redis.
active_diameter_peers_timeout: 10
#Prevent updates from being performed without a valid 'Provisioning-Key' in the header
lock_provisioning: False
@@ -56,34 +55,50 @@ hss:
#Default Initial Filter Criteria for IMS Subscribers
#Jinja Formatted Template, see the example for variables passed to it.
Default_iFC: 'default_ifc.xml'
Default_iFC: 'INSTALL_PREFIX/default_ifc.xml'
#Default Sh User Data
Default_Sh_UserData: 'default_sh_user_data.xml'
Default_Sh_UserData: 'INSTALL_PREFIX/default_sh_user_data.xml'
#S-CSCF Pool
scscf_pool:
- 'sip:scscf.IMS_DOMAIN:6060'
roaming:
outbound:
# Whether or not to a subscriber to connect to an undefined network when outbound roaming.
allow_undefined_networks: True
# SCTP Socket Parameters
sctp:
rtoMax: 5000
rtoMin: 500
rtoInitial: 1000
api:
page_size: 200
# Whether or not to return key-based data when querying the AUC. Disable in production systems.
enable_insecure_auc: True
external:
external_webhook_notification_enabled: False
external_webhook_notification_url: https://api.example.com/webhook
benchmarking:
# Whether to enable benchmark logging
enabled: True
# How often to report, in seconds. Not all benchmarking supports interval reporting.
reporting_interval: 3600
eir:
imsi_imei_logging: True #Store current IMEI / IMSI pair in backend
sim_swap_notify_webhook: http://PYHSS_IP:5000/webhooks/sim_swap_notify/
no_match_response: 2 #Greylist
tac_database_csv: '/etc/pyhss/tac_database_Nov2022.csv'
store_offnet_imsi: False # Whether or not to store an IMEI / IMSI pair that doesn't exist in the AUC
simSwapNotification: False # If the IMEI for a stored IMSI/IMEI combo changes, notify the webhook endpoint
logging:
level: WARNING
level: INFO
logfiles:
hss_logging_file: log/hss.log
diameter_logging_file: log/diameter.log
database_logging_file: log/db.log
hss_logging_file: INSTALL_PREFIX/log/hss.log
diameter_logging_file: INSTALL_PREFIX/log/diameter.log
geored_logging_file: INSTALL_PREFIX/log/geored.log
metric_logging_file: INSTALL_PREFIX/log/metrics.log
log_to_terminal: True
sqlalchemy_sql_echo: True
sqlalchemy_pool_recycle: 15
@@ -97,6 +112,14 @@ database:
username: pyhss
password: ims_db_pass
database: ims_hss_db
readCacheEnabled: True
readCacheInterval: 60
## External Webhook Notifications
webhooks:
enabled: False
endpoints:
- 'http://127.0.0.1:8181'
## Geographic Redundancy Parameters
geored:
@@ -106,17 +129,22 @@ geored:
- 'http://hss01.mnc001.mcc001.3gppnetwork.org:8080'
- 'http://hss02.mnc001.mcc001.3gppnetwork.org:8080'
## Stats Parameters
#Redis is required to run PyHSS. An instance running on a local network is recommended for production.
redis:
enabled: False
clear_stats_on_boot: True
host: PYHSS_IP
# Which connection type to attempt. Valid options are: tcp, unix, sentinel
# tcp - Connection via a standard TCP socket to a given host and port.
# unix - Connect to redis via a unix socket, provided by unixSocketPath.
# sentinel - Connect to one or more redis sentinel hosts.
connectionType: "tcp"
unixSocketPath: '/var/run/redis/redis-server.sock'
host: 127.0.0.1
port: 6379
prometheus:
enabled: False
port: 8081 #If the API is run the API runs on the next port number up from this
async_subscriber_count: False #If enabled the subscriber count will be updated asynchronously for Prometheus
snmp:
port: 1161
listen_address: PYHSS_IP
listen_address: 127.0.0.1

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--This is the default iFC template used by PyHSS, variables come from the Jinja2 template passed inside diameter.py where you can additional variables if required -->
<Sh-Data>
<IMSPrivateUserIdentity>{{ Sh_template_vars['imsi'] }}@ims.mnc{{ Sh_template_vars['mnc'] }}.mcc{{ Sh_template_vars['mcc'] }}.3gppnetwork.org</IMSPrivateUserIdentity>
<!-- This provides the Public Identifiers to the Application Server -->
<PublicIdentifiers>
<IMSPublicIdentity>sip:{{ Sh_template_vars['msisdn'] }}@ims.mnc{{ Sh_template_vars['mnc'] }}.mcc{{ Sh_template_vars['mcc'] }}.3gppnetwork.org</IMSPublicIdentity>
@@ -20,9 +21,9 @@
</EPSLocationInformation>
</Extension>
<!-- This container for the XCAP Data for the Subscriber -->
<Sh-IMS-Data>
<S-CSCFName>{{ Sh_template_vars['scscf'] }}</S-CSCFName>
<IMSUserState>{{ Sh_template_vars['imsUserState'] }}</IMSUserState>
</Sh-IMS-Data>
<!-- XCAP data from Database -->
{{ Sh_template_vars['sh_profile'] }}
</Sh-Data>
</Sh-Data>

View File

@@ -51,17 +51,26 @@ cp /mnt/pyhss/config.yaml ./
cp /mnt/pyhss/default_ifc.xml ./
cp /mnt/pyhss/default_sh_user_data.xml ./
INSTALL_PREFIX="/pyhss"
sed -i 's|PYHSS_IP|'$PYHSS_IP'|g' ./config.yaml
sed -i 's|PYHSS_BIND_PORT|'$PYHSS_BIND_PORT'|g' ./config.yaml
sed -i 's|IMS_DOMAIN|'$IMS_DOMAIN'|g' ./config.yaml
sed -i 's|OP_MCC|'$MCC'|g' ./config.yaml
sed -i 's|OP_MNC|'$MNC'|g' ./config.yaml
sed -i 's|MYSQL_IP|'$MYSQL_IP'|g' ./config.yaml
sed -i 's|INSTALL_PREFIX|'$INSTALL_PREFIX'|g' ./config.yaml
# Sync docker time
#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
export FLASK_APP=PyHSS_API.py
flask run --host=$PYHSS_IP --port=8080 &
redis-server --daemonize yes
python3 hss.py
cd services
python3 apiService.py --host=$PYHSS_IP --port=8080 &
# Sleep is needed to let db be populated in a non-overlapping fashion
sleep 5
python3 diameterService.py &
# Sleep is needed to let db be populated in a non-overlapping fashion
sleep 5
python3 hssService.py

View File

@@ -323,8 +323,12 @@ services:
ipv4_address: ${GRAFANA_IP}
networks:
default:
name: docker_open5gs_default
ipam:
config:
- subnet: ${TEST_NETWORK}
volumes:
mongodbdata: {}
grafana_data:
name: grafana_data
mongodbdata:
name: docker_open5gs_mongodbdata

View File

@@ -508,9 +508,14 @@ services:
ipv4_address: ${GRAFANA_IP}
networks:
default:
name: docker_open5gs_default
ipam:
config:
- subnet: ${TEST_NETWORK}
volumes:
mongodbdata: {}
dbdata: {}
grafana_data:
name: grafana_data
mongodbdata:
name: docker_open5gs_mongodbdata
dbdata:
name: docker_open5gs_dbdata

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/scp.log
file:
path: /open5gs/install/var/log/open5gs/scp.log
sbi:
server:

View File

@@ -222,8 +222,8 @@ modparam("rr", "custom_user_avp", "$avp(RR_CUSTOM_USER_AVP)")
# -- usrloc params --
modparam("ims_usrloc_scscf", "enable_debug_file", 0)
modparam("ims_usrloc_scscf", "matching_mode", 0)
modparam("ims_usrloc_scscf", "maxcontact", 5)
modparam("ims_usrloc_scscf", "maxcontact_3gpp", 5)
modparam("ims_usrloc_scscf", "maxcontact", 1) # set to one as workaround for instable Link
modparam("ims_usrloc_scscf", "maxcontact_3gpp", 1) # set to one as workaround for instable Link
modparam("ims_registrar_scscf", "max_contacts", 5)
modparam("ims_usrloc_scscf", "maxcontact_behaviour", 2) #overwrite
#!ifdef DB_URL

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/sgwc.log
file:
path: /open5gs/install/var/log/open5gs/sgwc.log
global:
max:

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/sgwu.log
file:
path: /open5gs/install/var/log/open5gs/sgwu.log
global:
max:

View File

@@ -60,8 +60,7 @@ def start(ip_range):
raise ValueError('Invalid UE IPv4 range. Only one IP given')
else:
first_ip_addr = first_ip_addr.exploded
ip_netmask_prefix = ip_range.prefixlen
print(str(first_ip_addr) + '/' + str(ip_netmask_prefix))
print(str(first_ip_addr))
if __name__ == '__main__':
try:

View File

@@ -174,7 +174,7 @@ TLS_CA = "/open5gs/install/etc/freeDiameter/cacert.pem";
# algorithms. In addition the "0xffffff" application is advertised in CER/CEA
# exchanges.
# Default: Relaying is enabled.
#NoRelay;
NoRelay;
# Number of server threads that can handle incoming messages at the same time.
# Default: 4

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/smf.log
file:
path: /open5gs/install/var/log/open5gs/smf.log
sbi:
server:
@@ -37,18 +38,18 @@ smf:
upf:
- address: UPF_IP
session:
- subnet: UE_IPV4_INTERNET_TUN_IP
- subnet: UE_IPV4_INTERNET_SUBNET
gateway: UE_IPV4_INTERNET_TUN_IP
dnn: internet
dev: ogstun
- subnet: 2001:230:cafe::1/48
- subnet: 2001:230:cafe::/48
gateway: 2001:230:cafe::1
dnn: internet
dev: ogstun
- subnet: UE_IPV4_IMS_TUN_IP
- subnet: UE_IPV4_IMS_SUBNET
gateway: UE_IPV4_IMS_TUN_IP
dnn: ims
dev: ogstun2
- subnet: 2001:230:babe::1/48
- subnet: 2001:230:babe::/48
gateway: 2001:230:babe::1
dnn: ims
dev: ogstun2
dns:
- SMF_DNS1
- SMF_DNS2

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/smf.log
file:
path: /open5gs/install/var/log/open5gs/smf.log
sbi:
server:
@@ -28,18 +29,18 @@ smf:
upf:
- address: UPF_IP
session:
- subnet: UE_IPV4_INTERNET_TUN_IP
- subnet: UE_IPV4_INTERNET_SUBNET
gateway: UE_IPV4_INTERNET_TUN_IP
dnn: internet
dev: ogstun
- subnet: 2001:230:cafe::1/48
- subnet: 2001:230:cafe::/48
gateway: 2001:230:cafe::1
dnn: internet
dev: ogstun
- subnet: UE_IPV4_IMS_TUN_IP
- subnet: UE_IPV4_IMS_SUBNET
gateway: UE_IPV4_IMS_TUN_IP
dnn: ims
dev: ogstun2
- subnet: 2001:230:babe::1/48
- subnet: 2001:230:babe::/48
gateway: 2001:230:babe::1
dnn: ims
dev: ogstun2
dns:
- SMF_DNS1
- SMF_DNS2

View File

@@ -51,7 +51,9 @@ sed -i 's|UPF_IP|'$UPF_IP'|g' install/etc/open5gs/smf.yaml
sed -i 's|SMF_DNS1|'$SMF_DNS1'|g' install/etc/open5gs/smf.yaml
sed -i 's|SMF_DNS2|'$SMF_DNS2'|g' install/etc/open5gs/smf.yaml
sed -i 's|UE_IPV4_INTERNET_TUN_IP|'$UE_IPV4_INTERNET_TUN_IP'|g' install/etc/open5gs/smf.yaml
sed -i 's|UE_IPV4_INTERNET_SUBNET|'$UE_IPV4_INTERNET'|g' install/etc/open5gs/smf.yaml
sed -i 's|UE_IPV4_IMS_TUN_IP|'$UE_IPV4_IMS_TUN_IP'|g' install/etc/open5gs/smf.yaml
sed -i 's|UE_IPV4_IMS_SUBNET|'$UE_IPV4_IMS'|g' install/etc/open5gs/smf.yaml
sed -i 's|PCSCF_IP|'$PCSCF_IP'|g' install/etc/open5gs/smf.yaml
sed -i 's|MAX_NUM_UE|'$MAX_NUM_UE'|g' install/etc/open5gs/smf.yaml
sed -i 's|SMF_IP|'$SMF_IP'|g' install/etc/freeDiameter/smf.conf

View File

@@ -54,7 +54,7 @@ RUN git clone https://github.com/myriadrf/LimeSuite.git && \
# Get BladeRF, compile and install
RUN git clone https://github.com/Nuand/bladeRF.git && \
cd bladeRF/host/ && \
cd bladeRF/host/ && git checkout tags/2024.05 && \
mkdir build && cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DINSTALL_UDEV_RULES=ON -DBLADERF_GROUP=plugdev ../ && make && make install && \
ldconfig && \
@@ -84,7 +84,7 @@ RUN git clone https://github.com/srsran/srsGUI && \
# Get srsLTE, compile and install
RUN git clone https://github.com/srsran/srsRAN_4G.git && \
cd srsRAN_4G && \
git checkout 4eb990c9c6ad9b0af943bba71d0f8355b3ebb259 && \
git checkout ec29b0c1ff79cebcbe66caa6d6b90778261c42b8 && \
mkdir build && cd build && \
cmake ../ && make -j`nproc` && make install && \
ldconfig

View File

@@ -40,7 +40,7 @@ RUN add-apt-repository ppa:ettusresearch/uhd && \
# Get srsRAN_Project, compile and install
RUN git clone https://github.com/srsran/srsRAN_Project.git && \
cd srsRAN_Project && git checkout 55c984b55736d0dd2d2ee328f1ae8d9de97e3e19 && \
cd srsRAN_Project && git checkout a041e3162d7ea94a7963437f32df372fae5d21ea && \
mkdir build && cd build && \
cmake ../ -DENABLE_EXPORT=ON -DENABLE_ZEROMQ=ON && make -j`nproc` && make install && \
ldconfig

View File

@@ -1,6 +1,13 @@
amf:
addr: AMF_IP # The address or hostname of the AMF.
bind_addr: SRS_GNB_IP # A local IP that the gNB binds to for traffic from the AMF.
cu_cp:
amf:
addr: AMF_IP # The address or hostname of the AMF.
bind_addr: SRS_GNB_IP # A local IP that the gNB binds to for traffic from the AMF.
supported_tracking_areas: # Sets the list of tracking areas supported by this AMF.
- tac: 1 # Tracking area code (needs to match the core configuration).
plmn_list: # The list of PLMN items supported for this Tracking Area.
- plmn: "PLMN" # PLMN broadcasted by the gNB.
tai_slice_support_list: # The list of TAI slices for this PLMN item.
- sst: 1 # Sets the Slice Service Type.
ru_sdr:
device_driver: uhd # The RF driver name.
@@ -35,6 +42,8 @@ pcap:
e1ap_enable: false # Set to true to enable E1AP PCAPs.
e1ap_filename: /mnt/srsran/gnb_e1ap.pcap # Path where the E1AP PCAP is stored.
e2ap_enable: false # Set to true to enable E2AP PCAPs.
e2ap_filename: /mnt/srsran/gnb_e2ap.pcap # Path where the E2AP PCAP is stored.
gtpu_enable: false # Set to true to enable GTP-U PCAPs.
gtpu_filename: /mnt/srsran/gnb_gtpu.pcap # Path where the GTP-U PCAP is stored.
e2ap_cu_cp_filename: /mnt/srsran/cu_cp_e2ap.pcap # Path where E2AP CU-CP PCAP is stored.
e2ap_cu_up_filename: /mnt/srsran/cu_up_e2ap.pcap # Path where E2AP CU-UP PCAP is stored.
e2ap_du_filename: /mnt/srsran/du_e2ap.pcap # Path where E2AP CU PCAP is stored.
n3_enable: false # Set to true to enable N3 PCAPs.
n3_filename: /mnt/srsran/gnb_n3.pcap # Path where the N3 PCAP is stored.

View File

@@ -1,6 +1,13 @@
amf:
addr: AMF_IP # The address or hostname of the AMF.
bind_addr: SRS_GNB_IP # A local IP that the gNB binds to for traffic from the AMF.
cu_cp:
amf:
addr: AMF_IP # The address or hostname of the AMF.
bind_addr: SRS_GNB_IP # A local IP that the gNB binds to for traffic from the AMF.
supported_tracking_areas: # Sets the list of tracking areas supported by this AMF.
- tac: 1 # Tracking area code (needs to match the core configuration).
plmn_list: # The list of PLMN items supported for this Tracking Area.
- plmn: "PLMN" # PLMN broadcasted by the gNB.
tai_slice_support_list: # The list of TAI slices for this PLMN item.
- sst: 1 # Sets the Slice Service Type.
ru_sdr:
device_driver: zmq # The RF driver name.
@@ -41,6 +48,8 @@ pcap:
e1ap_enable: false # Set to true to enable E1AP PCAPs.
e1ap_filename: /mnt/srsran/gnb_e1ap.pcap # Path where the E1AP PCAP is stored.
e2ap_enable: false # Set to true to enable E2AP PCAPs.
e2ap_filename: /mnt/srsran/gnb_e2ap.pcap # Path where the E2AP PCAP is stored.
gtpu_enable: false # Set to true to enable GTP-U PCAPs.
gtpu_filename: /mnt/srsran/gnb_gtpu.pcap # Path where the GTP-U PCAP is stored.
e2ap_cu_cp_filename: /mnt/srsran/cu_cp_e2ap.pcap # Path where E2AP CU-CP PCAP is stored.
e2ap_cu_up_filename: /mnt/srsran/cu_up_e2ap.pcap # Path where E2AP CU-UP PCAP is stored.
e2ap_du_filename: /mnt/srsran/du_e2ap.pcap # Path where E2AP CU PCAP is stored.
n3_enable: false # Set to true to enable N3 PCAPs.
n3_filename: /mnt/srsran/gnb_n3.pcap # Path where the N3 PCAP is stored.

View File

@@ -7,17 +7,7 @@
qos:
-
five_qi: 1 # E.g. Conversational Voice
rlc:
mode: um-bidir
um-bidir:
tx:
sn: 12
queue-size: 4096
rx:
sn: 12
t-reassembly: 50
pdcp:
integrity_required: false
tx:
sn: 12
discard_timer: -1
@@ -26,28 +16,23 @@ qos:
sn: 12
t_reordering: 80
out_of_order_delivery: false
f1u_du:
backoff_timer: 10
f1u_cu_up:
backoff_timer: 10
mac:
lc_priority: 4
lc_group_id: 1
bucket_size_duration_ms: 5
prioritized_bit_rate_kBps: 65537
f1u_du:
backoff_timer: 10
rlc:
mode: um-bidir
um-bidir:
tx:
sn: 12
queue-size: 16384
queue-bytes: 6172672
rx:
sn: 12
t-reassembly: 50
-
five_qi: 2 # E.g. Conversational Video
rlc:
mode: um-bidir
um-bidir:
tx:
sn: 12
queue-size: 4096
rx:
sn: 12
t-reassembly: 50
pdcp:
integrity_required: false
tx:
sn: 12
discard_timer: -1
@@ -56,15 +41,20 @@ qos:
sn: 12
t_reordering: 80
out_of_order_delivery: false
f1u_du:
backoff_timer: 10
f1u_cu_up:
backoff_timer: 10
mac:
lc_priority: 4
lc_group_id: 1
bucket_size_duration_ms: 5
prioritized_bit_rate_kBps: 65537
f1u_du:
backoff_timer: 10
rlc:
mode: um-bidir
um-bidir:
tx:
sn: 12
queue-size: 16384
queue-bytes: 6172672
rx:
sn: 12
t-reassembly: 50
-
five_qi: 5 # E.g. IMS signaling
rlc:
@@ -76,7 +66,8 @@ qos:
max-retx-threshold: 4
poll-pdu: 64
poll-byte: 125
queue-size: 4096
queue-size: 16384
queue-bytes: 6172672
rx:
sn: 12
t-reassembly: 80
@@ -95,73 +86,59 @@ qos:
backoff_timer: 10
f1u_cu_up:
backoff_timer: 10
mac:
lc_priority: 5
lc_group_id: 2
bucket_size_duration_ms: 5
prioritized_bit_rate_kBps: 65537
-
five_qi: 7 # E.g. Voice, Video (live streaming)
pdcp:
integrity_required: false
tx:
sn: 12
discard_timer: -1
status_report_required: false
rx:
sn: 12
t_reordering: 80
out_of_order_delivery: false
f1u_cu_up:
backoff_timer: 10
f1u_du:
backoff_timer: 10
rlc:
mode: um-bidir
um-bidir:
tx:
sn: 12
queue-size: 4096
queue-size: 16384
queue-bytes: 6172672
rx:
sn: 12
t-reassembly: 50
t-reassembly: 100
-
five_qi: 9 # E.g. Buffered video streaming, TCP-based traffic
pdcp:
integrity_required: false
tx:
sn: 12
sn: 18
discard_timer: -1
status_report_required: false
rx:
sn: 12
t_reordering: 80
sn: 18
t_reordering: 220
out_of_order_delivery: false
f1u_du:
backoff_timer: 10
f1u_cu_up:
backoff_timer: 10
mac:
lc_priority: 4
lc_group_id: 1
bucket_size_duration_ms: 5
prioritized_bit_rate_kBps: 65537
-
five_qi: 9 # E.g. Buffered video streaming, TCP-based traffic
f1u_du:
backoff_timer: 10
rlc:
mode: am
am:
tx:
sn: 12
t-poll-retransmit: 80
max-retx-threshold: 4
poll-pdu: 64
poll-byte: 125
queue-size: 4096
sn: 18
t-poll-retransmit: 20
max-retx-threshold: 32
poll-pdu: 16
poll-byte: -1
queue-size: 16384
queue-bytes: 6172672
rx:
sn: 12
t-reassembly: 80
sn: 18
t-reassembly: 20
t-status-prohibit: 10
pdcp:
integrity_required: false
tx:
sn: 12
discard_timer: -1
status_report_required: false
rx:
sn: 12
t_reordering: 80
out_of_order_delivery: false
f1u_du:
backoff_timer: 10
f1u_cu_up:
backoff_timer: 10
mac:
lc_priority: 5
lc_group_id: 2
bucket_size_duration_ms: 5
prioritized_bit_rate_kBps: 65537

View File

@@ -52,7 +52,7 @@ sed -i 's|SRS_UE_IP|'$SRS_UE_IP'|g' /etc/srsran/gnb.yml
# For dbus not started issue when host machine is running Ubuntu 22.04
service dbus start && service avahi-daemon start
gnb -c /etc/srsran/gnb.yml -c /etc/srsran/qos.yml
exec gnb -c /etc/srsran/gnb.yml -c /etc/srsran/qos.yml $@
# Sync docker time
#ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/udm.log
file:
path: /open5gs/install/var/log/open5gs/udm.log
sbi:
server:

View File

@@ -11,7 +11,8 @@ global:
ue: MAX_NUM_UE
logger:
file: /open5gs/install/var/log/open5gs/udr.log
file:
path: /open5gs/install/var/log/open5gs/udr.log
udr:
sbi:

View File

@@ -24,7 +24,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
FROM ubuntu:focal as builder
FROM ubuntu:jammy as builder
ENV DEBIAN_FRONTEND=noninteractive
@@ -43,19 +43,8 @@ RUN apt-get update && \
ifupdown \
iputils-ping \
wget \
libssl-dev
RUN version=3.20 && \
build=0 && \
mkdir ~/temp && \
cd ~/temp && \
wget https://cmake.org/files/v$version/cmake-$version.$build.tar.gz && \
tar -xzvf cmake-$version.$build.tar.gz && \
cd cmake-$version.$build/ && \
./bootstrap && \
make -j`nproc` && \
make install && ldconfig && \
cmake --version
libssl-dev \
cmake
# Clone and build UERANSIM
RUN git clone https://github.com/aligungr/UERANSIM && \
@@ -63,7 +52,7 @@ RUN git clone https://github.com/aligungr/UERANSIM && \
make -j`nproc`
# Build final image
FROM ubuntu:focal
FROM ubuntu:jammy
ENV DEBIAN_FRONTEND=noninteractive

View File

@@ -60,8 +60,7 @@ def start(ip_range):
raise ValueError('Invalid UE IPv4 range. Only one IP given')
else:
first_ip_addr = first_ip_addr.exploded
ip_netmask_prefix = ip_range.prefixlen
print(str(first_ip_addr) + '/' + str(ip_netmask_prefix))
print(str(first_ip_addr))
if __name__ == '__main__':
try:

View File

@@ -1,5 +1,6 @@
logger:
file: /open5gs/install/var/log/open5gs/upf.log
file:
path: /open5gs/install/var/log/open5gs/upf.log
global:
max:
@@ -17,16 +18,20 @@ upf:
- address: UPF_IP
advertise: UPF_ADVERTISE_IP
session:
- subnet: UE_IPV4_INTERNET_TUN_IP
dev: ogstun
- subnet: UE_IPV4_INTERNET_SUBNET
gateway: UE_IPV4_INTERNET_TUN_IP
dnn: internet
- subnet: 2001:230:cafe::1/48
dev: ogstun
- subnet: 2001:230:cafe::/48
gateway: 2001:230:cafe::1
dnn: internet
- subnet: UE_IPV4_IMS_TUN_IP
dev: ogstun
- subnet: UE_IPV4_IMS_SUBNET
gateway: UE_IPV4_IMS_TUN_IP
dnn: ims
dev: ogstun2
- subnet: 2001:230:babe::1/48
- subnet: 2001:230:babe::/48
gateway: 2001:230:babe::1
dnn: ims
dev: ogstun2
metrics:

View File

@@ -41,7 +41,9 @@ cp /mnt/upf/upf.yaml install/etc/open5gs
sed -i 's|UPF_IP|'$UPF_IP'|g' install/etc/open5gs/upf.yaml
sed -i 's|SMF_IP|'$SMF_IP'|g' install/etc/open5gs/upf.yaml
sed -i 's|UE_IPV4_INTERNET_TUN_IP|'$UE_IPV4_INTERNET_TUN_IP'|g' install/etc/open5gs/upf.yaml
sed -i 's|UE_IPV4_INTERNET_SUBNET|'$UE_IPV4_INTERNET'|g' install/etc/open5gs/upf.yaml
sed -i 's|UE_IPV4_IMS_TUN_IP|'$UE_IPV4_IMS_TUN_IP'|g' install/etc/open5gs/upf.yaml
sed -i 's|UE_IPV4_IMS_SUBNET|'$UE_IPV4_IMS'|g' install/etc/open5gs/upf.yaml
sed -i 's|UPF_ADVERTISE_IP|'$UPF_ADVERTISE_IP'|g' install/etc/open5gs/upf.yaml
sed -i 's|MAX_NUM_UE|'$MAX_NUM_UE'|g' install/etc/open5gs/upf.yaml