Commit b83ff606 authored by sagar arora's avatar sagar arora

Merge branch 'Release-v1.4.0' into 'master'

Release v1.4.0

See merge request oai/cn5g/oai-cn5g-smf!138
parents a69c3de7 baff3d96
# RELEASE NOTES: #
## v1.4.0 -- July 2022 ##
* Fix for handling S-NSSAI
* Add support for IMS
* HTTP/2 support for SBI interface
* Add usage report feature
* Flexiable MTU
* Support for Ubuntu 20.04 bare-metal installation
* Official images produced by CI are pushed to `oaisoftwarealliance` Docker-Hub Team account
* Reduce image size
## v1.3.0 -- January 2022 ##
* Update NWI from NF profile
......
......@@ -15,6 +15,7 @@ At the moment, it contains the following network elements:
* Unified Data Management (**UDM**)
* Unified Data Repository (**UDR**)
* User Plane Function (**UPF**)
* Network Slicing Selection Function (**NSSF**)
Each has its own repository: this repository (`oai-cn5g-smf`) is meant for SMF.
......
......@@ -67,9 +67,9 @@ install_fb_folly_from_source(){
ret=$?;[[ $ret -ne 0 ]] && return $ret
elif [[ $OS_DISTRO == "ubuntu" ]]; then
$SUDO $INSTALLER install $OPTION \
$CMAKE \
g++ \
libevent-dev \
libboost1.67-dev \
libdouble-conversion-dev \
libgoogle-glog-dev \
libgflags-dev \
......
......@@ -373,20 +373,22 @@ check_install_smf_deps() {
# PPA has 1.67
$SUDO add-apt-repository ppa:mhier/libboost-latest --yes
$SUDO $INSTALLER update
specific_packages="libconfig++-dev"
specific_packages="libconfig++-dev libboost-all-dev"
;;
"ubuntu20.04")
specific_packages="libconfig++-dev libasio-dev libboost-all-dev"
;;
*)
specific_packages="libconfig++-dev libasio-dev libboost-all-dev"
;;
;;
esac
# removed libspdlog-dev
PACKAGE_LIST="\
$specific_packages \
libboost1.67-dev \
guile-2.0-dev \
libcurl4-gnutls-dev \
libevent-dev \
libgcrypt11-dev \
libgcrypt?-dev \
libgmp-dev \
libhogweed? \
libidn2-0-dev \
......@@ -403,7 +405,7 @@ check_install_smf_deps() {
net-tools \
pkg-config \
wget \
libasan2"
libasan?"
elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
PACKAGE_LIST="\
guile-devel \
......@@ -430,6 +432,17 @@ check_install_smf_deps() {
fi
echo "Install distro libs"
$SUDO $INSTALLER install $OPTION $PACKAGE_LIST
# fix issue with libboost in U18 for a bare metal deployment
if [[ $OS_DISTRO == "ubuntu" ]]; then
case "$(get_distribution_release)" in
"ubuntu18.04")
$SUDO $INSTALLER remove $OPTION libboost1.65-dev || true
$SUDO $INSTALLER install $OPTION libboost1.67-dev
;;
esac
fi
ret=$?;[[ $ret -ne 0 ]] && return $ret
echo "distro libs installation complete"
......
......@@ -19,26 +19,73 @@ SMF_CONF[@SMF_INTERFACE_PORT_FOR_SBI@]='80'
SMF_CONF[@SMF_INTERFACE_HTTP2_PORT_FOR_SBI@]='9090'
SMF_CONF[@SMF_API_VERSION@]='v1'
SMF_CONF[@DNN_NI0@]='oai.ipv4'
SMF_CONF[@TYPE0@]='IPv4'
SMF_CONF[@DNN_RANGE0@]='12.1.1.2 - 12.1.1.128'
SMF_CONF[@DNN_NI1@]='default'
SMF_CONF[@TYPE1@]='IPv4'
SMF_CONF[@DNN_RANGE1@]='12.2.1.2 - 12.2.1.128'
SMF_CONF[@DNN_NI2@]='oai'
SMF_CONF[@TYPE2@]='IPv4'
SMF_CONF[@DNN_RANGE2@]='12.1.1.129 - 12.1.1.224'
SMF_CONF[@DNN_NI3@]='ims'
SMF_CONF[@TYPE3@]='IPv4'
SMF_CONF[@DNN_RANGE3@]='12.2.1.129 - 12.2.1.224'
SMF_CONF[@USE_NETWORK_INSTANCE@]='no'
SMF_CONF[@USE_LOCAL_SUBSCRIPTION_INFO@]='yes'
SMF_CONF[@DOMAIN_ACCESS@]='access.oai.org'
SMF_CONF[@DOMAIN_CORE@]='core.oai.org'
SMF_CONF[@USE_FQDN_DNS@]='no'
SMF_CONF[@ENABLE_USAGE_REPORTING@]='no'
SMF_CONF[@REGISTER_NRF@]='no'
SMF_CONF[@DISCOVER_UPF@]='no'
SMF_CONF[@HTTP_VERSION@]='1'
SMF_CONF[@UE_MTU@]='1358'
SMF_CONF[@NSSAI_SST0@]='222'
SMF_CONF[@NSSAI_SD0@]='123'
SMF_CONF[@NSSAI_SST1@]='1'
SMF_CONF[@NSSAI_SD1@]='0xFFFFFF'
SMF_CONF[@NSSAI_SST2@]='2'
SMF_CONF[@NSSAI_SD2@]='2'
SMF_CONF[@QOS_PROFILE_5QI0@]='6'
SMF_CONF[@QOS_PROFILE_5QI1@]='7'
SMF_CONF[@QOS_PROFILE_5QI2@]='8'
SMF_CONF[@SESSION_AMBR_UL0@]='20Mbps'
SMF_CONF[@SESSION_AMBR_UL1@]='220Mbps'
SMF_CONF[@SESSION_AMBR_UL2@]='20Mbps'
SMF_CONF[@SESSION_AMBR_DL0@]='20Mbps'
SMF_CONF[@SESSION_AMBR_DL1@]='220Mbps'
SMF_CONF[@SESSION_AMBR_DL2@]='20Mbps'
SMF_CONF[@UDM_IPV4_ADDRESS@]='172.16.1.103'
SMF_CONF[@UDM_PORT@]='80'
SMF_CONF[@UDM_API_VERSION@]='v2'
SMF_CONF[@UDM_FQDN@]='localhost'
SMF_CONF[@UDM_FQDN@]='oai-udm'
SMF_CONF[@AMF_IPV4_ADDRESS@]='192.168.74.195'
SMF_CONF[@AMF_PORT@]='80'
SMF_CONF[@AMF_API_VERSION@]='v1'
SMF_CONF[@AMF_FQDN@]='localhost'
SMF_CONF[@AMF_FQDN@]='oai-amf'
SMF_CONF[@UPF_IPV4_ADDRESS@]='192.168.12.245'
SMF_CONF[@UPF_FQDN@]='localhost'
SMF_CONF[@UPF_FQDN_0@]='oai-upf0'
SMF_CONF[@NRF_IPV4_ADDRESS@]='127.0.0.1'
SMF_CONF[@NRF_PORT@]='8080'
SMF_CONF[@NRF_API_VERSION@]='v1'
SMF_CONF[@NRF_FQDN@]='localhost'
SMF_CONF[@NRF_FQDN@]='oai-nrf'
SMF_CONF[@DEFAULT_DNS_IPV4_ADDRESS@]='8.8.8.8'
SMF_CONF[@DEFAULT_DNS_SEC_IPV4_ADDRESS@]='4.4.4.4'
......
......@@ -50,6 +50,9 @@ def SMF_BASE_IMAGE_TAG = params.SmfBaseImageTag
// Merge Request Link
def gitlabMergeRequestLink
// Docker Hub account to push to
def DH_Account = "oaisoftwarealliance"
//-------------------------------------------------------------------------------
// Pipeline start
pipeline {
......@@ -134,7 +137,6 @@ pipeline {
echo "MR TITLE is ${env.gitlabMergeRequestTitle}"
gitCommitAuthorEmailAddr = env.gitlabUserEmail
echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}"
sh "git fetch --prune --unshallow"
shortenShaOne = sh returnStdout: true, script: 'git log -1 --pretty=format:"%h" ' + env.gitlabMergeRequestLastCommit
shortenShaOne = shortenShaOne.trim()
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}"
......@@ -185,7 +187,7 @@ pipeline {
echo "Maybe a previous build went wrong"
}
// In case of push to `develop` branch we build from scratch
myShCmd('docker build --no-cache --target oai-smf --tag oai-smf:' + smf_tag + ' --file docker/Dockerfile.smf.ubuntu18 --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > archives/smf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker build --no-cache --target oai-smf --tag oai-smf:' + smf_tag + ' --file docker/Dockerfile.smf.ubuntu18 . > archives/smf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
}
if ("MERGE".equals(env.gitlabActionType)) {
try {
......@@ -200,6 +202,9 @@ pipeline {
myShCmd('docker image tag oai-smf-base:' +SMF_BASE_IMAGE_TAG + ' oai-smf-base:latest', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker build --no-cache --target oai-smf --tag oai-smf:' + smf_tag + ' --file ci-scripts/docker/Dockerfile.ci.ubuntu.18.04 . > archives/smf_docker_image_build.log 2>&1', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
}
// Putting a place holder to try out on the flattening of image.
// If not satisfactory, we can remove it.
myShCmd('python3 ./ci-scripts/flatten_image.py --tag oai-smf:' + smf_tag, rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd('docker image ls >> archives/smf_docker_image_build.log', rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
// We will keep also the TMP image in U18 case.
if ("MERGE".equals(env.gitlabActionType)) {
......@@ -242,10 +247,14 @@ pipeline {
}
myShCmd('sudo podman image prune --force', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
// Copy the RHEL Host certificates for building
myShCmd('mkdir -p tmp/ca tmp/entitlement', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('cp /etc/pki/entitlement/*pem tmp/entitlement', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo cp /etc/rhsm/ca/redhat-uep.pem tmp/ca', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman build --no-cache --target oai-smf --tag oai-smf:' + smf_tag + ' --file docker/Dockerfile.smf.rhel8 --build-arg NEEDED_GIT_PROXY="http://proxy.eurecom.fr:8080" . > archives/smf_podman_image_build.log 2>&1', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('mkdir -p ./etc-pki-entitlement ./rhsm-conf ./rhsm-ca', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('cp /etc/pki/entitlement/*pem ./etc-pki-entitlement', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo cp /etc/rhsm/rhsm.conf ./rhsm-conf', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo cp /etc/rhsm/ca/*pem ./rhsm-ca', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman build --no-cache --target oai-smf --tag oai-smf:' + smf_tag + ' --file docker/Dockerfile.smf.rhel8 . > archives/smf_podman_image_build.log 2>&1', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
// Putting a place holder to try out on the flattening of image.
// If not satisfactory, we can remove it.
myShCmd('python3 ./ci-scripts/flatten_image.py --tag oai-smf:' + smf_tag, rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
myShCmd('sudo podman image ls >> archives/smf_podman_image_build.log', rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
if ("MERGE".equals(env.gitlabActionType)) {
myShCmd('sudo podman image tag oai-smf:' + smf_tag + ' oai-smf:' + rhel_smf_tag, rem_rhel_host_flag, rem_rhel_host_user, rem_rhel_host)
......@@ -409,6 +418,36 @@ pipeline {
}
}
}
stage ('Testing the tutorials') {
steps {
script {
gitlabCommitStatus(name: "Test tutorials") {
localStatus = build job: 'OAI-CN5G-Tutorials-Check',
parameters: [
string(name: 'SMF_TAG', value: String.valueOf(smf_tag)),
string(name: 'SMF_BRANCH', value: String.valueOf(smf_branch))
], propagate: false
localResult = localStatus.getResult()
if (localStatus.resultIsBetterOrEqualTo('SUCCESS')) {
echo "Tutorials Test Job is OK"
} else {
echo "Tutorials Test Job is KO"
sh "ci-scripts/fail.sh"
}
}
}
}
post {
always {
script {
copyArtifacts(projectName: 'OAI-CN5G-Tutorials-Check',
filter: '*_results_oai_cn5g*.html',
selector: lastCompleted())
}
}
}
}
}
}
// For the moment it is Docker-Hub, but we might have a new one internally.
......@@ -421,9 +460,9 @@ pipeline {
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DockerHubCredentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password']
]) {
myShCmd("echo ${DH_Password} | docker login --username ${DH_Username} --password-stdin", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker image tag oai-smf:develop ${DH_Username}/oai-smf:develop", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker push ${DH_Username}/oai-smf:develop", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker rmi ${DH_Username}/oai-smf:develop", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker image tag oai-smf:develop ${DH_Account}/oai-smf:develop", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker push ${DH_Account}/oai-smf:develop", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker rmi ${DH_Account}/oai-smf:develop", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
myShCmd("docker logout", rem_u18_host_flag, rem_u18_host_user, rem_u18_host)
}
}
......
......@@ -139,6 +139,16 @@ then
exit 1
fi
# When running in a container, in /home folder
IS_CONTAINER=`egrep -c "docker|kubepods|podman|buildah|libpod" /proc/self/cgroup || true`
if [ $IS_CONTAINER -ne 0 ]
then
if [ $PWD = "/home/src" ]
then
git config --global --add safe.directory /home
fi
fi
# Merge request scenario
MERGE_COMMMIT=`git log -n1 --pretty=format:%H`
......
......@@ -36,7 +36,8 @@ RUN cp -Rf /openair-smf-ext-ref /openair-smf/build/ext
# Building SMF
WORKDIR /openair-smf/build/scripts
RUN ./build_smf --clean --Verbose --build-type Release --jobs && \
RUN ldconfig && \
./build_smf --clean --Verbose --build-type Release --jobs && \
ldd /openair-smf/build/smf/build/smf && \
mv /openair-smf/build/smf/build/smf /openair-smf/build/smf/build/oai_smf
......@@ -54,10 +55,10 @@ RUN apt-get update && \
net-tools \
tzdata \
bc \
tshark \
perl \
openssl \
libasan4 \
libgssapi-krb5-2 \
libldap-2.4-2 \
libgoogle-glog0v5 \
libdouble-conversion1 \
......@@ -74,6 +75,7 @@ COPY --from=oai-smf-builder \
WORKDIR /usr/local/lib/
COPY --from=oai-smf-builder \
/usr/local/lib/libpistache.so \
/usr/local/lib/libnghttp2.so.14 \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib/libboost_system.so.1.67.0 \
/usr/lib/libboost_thread.so.1.67.0 \
......
"""
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------------------
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
"""
import argparse
import re
import subprocess
import sys
def main() -> None:
args = _parse_args()
status = perform_flattening(args.tag)
sys.exit(status)
def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description='Flattening Image')
parser.add_argument(
'--tag', '-t',
action='store',
required=True,
help='Image Tag in image-name:image tag format',
)
return parser.parse_args()
def perform_flattening(tag):
# First detect which docker/podman command to use
cli = ''
image_prefix = ''
cmd = 'which podman || true'
podman_check = subprocess.check_output(cmd, shell=True, universal_newlines=True)
if re.search('podman', podman_check.strip()):
cli = 'sudo podman'
image_prefix = 'localhost/'
if cli == '':
cmd = 'which docker || true'
docker_check = subprocess.check_output(cmd, shell=True, universal_newlines=True)
if re.search('docker', docker_check.strip()):
cli = 'docker'
image_prefix = ''
if cli == '':
print ('No docker / podman installed: quitting')
return -1
print (f'Flattening {tag}')
# Creating a container
cmd = cli + ' run --name test-flatten --entrypoint /bin/true -d ' + tag
print (cmd)
subprocess.check_output(cmd, shell=True, universal_newlines=True)
# Export / Import trick
cmd = cli + ' export test-flatten | ' + cli + ' import '
# Bizarro syntax issue with podman
if cli == 'docker':
cmd += ' --change "ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" '
else:
cmd += ' --change "ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" '
cmd += ' --change "WORKDIR /openair-smf" '
cmd += ' --change "EXPOSE 80/tcp" '
cmd += ' --change "EXPOSE 8080/tcp" '
cmd += ' --change "EXPOSE 8805/udp" '
cmd += ' --change "CMD [\\"/openair-smf/bin/oai_smf\\", \\"-c\\", \\"/openair-smf/etc/smf.conf\\", \\"-o\\"]" '
cmd += ' --change "ENTRYPOINT [\\"/bin/bash\\", \\"/openair-smf/bin/entrypoint.sh\\"]" '
cmd += ' - ' + image_prefix + tag
print (cmd)
subprocess.check_output(cmd, shell=True, universal_newlines=True)
# Remove container
cmd = cli + ' rm -f test-flatten'
print (cmd)
subprocess.check_output(cmd, shell=True, universal_newlines=True)
# At this point the original image is a dangling image.
# CI pipeline will clean up (`image prune --force`)
return 0
if __name__ == '__main__':
main()
......@@ -853,7 +853,7 @@ class HtmlReport():
result = re.search('oai-smf *ci-tmp', line)
else:
result = re.search('oai-smf *develop', line)
if result is not None:
if result is not None and not status:
result = re.search('ago *([0-9A-Z ]+)', line)
if result is not None:
size = result.group(1)
......
......@@ -32,8 +32,12 @@ FROM registry.access.redhat.com/ubi8/ubi:latest AS oai-smf-builder
ARG NEEDED_GIT_PROXY
COPY tmp/ca/redhat-uep.pem /etc/rhsm/ca
COPY tmp/entitlement/*.pem /etc/pki/entitlement
# Copy the entitlements
COPY ./etc-pki-entitlement /etc/pki/entitlement
# Copy the subscription manager configurations
COPY ./rhsm-conf /etc/rhsm
COPY ./rhsm-ca /etc/rhsm/ca
RUN rm -f /etc/rhsm-host && \
yum repolist --disablerepo=* && \
......@@ -43,7 +47,8 @@ RUN rm -f /etc/rhsm-host && \
psmisc \
git \
diffutils \
file && \
file \
boost-devel &&\
rm -rf /var/lib/apt/lists/*
# Some GIT configuration command quite useful
......@@ -76,7 +81,8 @@ RUN yum update -y && \
procps-ng \
net-tools \
libevent && \
rm -rf /var/lib/apt/lists/*
yum clean all -y && \
rm -rf /var/cache/yum /var/cache/dnf
# Copying executable and generated libraries
WORKDIR /openair-smf/bin
......
......@@ -44,8 +44,8 @@ RUN apt-get update && \
rm -rf /var/lib/apt/lists/*
# Some GIT configuration command quite useful
RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi" && \
git config --global https.postBuffer 123289600 && \
RUN /bin/bash -c "if [[ -v NEEDED_GIT_PROXY ]]; then git config --global http.proxy $NEEDED_GIT_PROXY; fi"
RUN git config --global https.postBuffer 123289600 && \
git config --global http.sslverify false
# Copying source code
......@@ -73,10 +73,10 @@ RUN apt-get update && \
net-tools \
tzdata \
bc \
tshark \
perl \
openssl \
libasan4 \
libgssapi-krb5-2 \
libldap-2.4-2 \
libgoogle-glog0v5 \
libdouble-conversion1 \
......@@ -93,6 +93,7 @@ COPY --from=oai-smf-builder \
WORKDIR /usr/local/lib/
COPY --from=oai-smf-builder \
/usr/local/lib/libpistache.so \
/usr/local/lib/libnghttp2.so.14 \
/usr/local/lib/libnghttp2_asio.so.1 \
/usr/lib/libboost_system.so.1.67.0 \
/usr/lib/libboost_thread.so.1.67.0 \
......
......@@ -63,9 +63,13 @@ SMF =
DEFAULT_DNS_SEC_IPV4_ADDRESS = "@DEFAULT_DNS_SEC_IPV4_ADDRESS@"; # YOUR DNS CONFIG HERE
DEFAULT_DNS_IPV6_ADDRESS = "2001:4860:4860::8888"; # YOUR DNS CONFIG HERE
DEFAULT_DNS_SEC_IPV6_ADDRESS = "2001:4860:4860::8844"; # YOUR DNS CONFIG HERE
#Default P-CSCF server
DEFAULT_CSCF_IPV4_ADDRESS = "@DEFAULT_CSCF_IPV4_ADDRESS@";
DEFAULT_CSCF_IPV6_ADDRESS = "fe80::7915:f408:1787:db8b";
#Default UE MTU
UE_MTU = 1358;
UE_MTU = @UE_MTU@;
# SUPPORT FEATURES
SUPPORT_FEATURES:
......@@ -78,7 +82,8 @@ SMF =
USE_LOCAL_SUBSCRIPTION_INFO = "@USE_LOCAL_SUBSCRIPTION_INFO@"; # Set to yes if SMF uses local subscription information instead of from an UDM
USE_FQDN_DNS = "@USE_FQDN_DNS@"; # Set to yes if AMF/UDM/NRF/UPF will relying on a DNS to resolve FQDN
HTTP_VERSION = @HTTP_VERSION@; # Default: 1
USE_NETWORK_INSTANCE = "@USE_NETWORK_INSTANCE@" # Set yes if network instance is to be used for given UPF
USE_NETWORK_INSTANCE = "@USE_NETWORK_INSTANCE@" # Set yes if network instance is to be used for given UPF
ENABLE_USAGE_REPORTING = "@ENABLE_USAGE_REPORTING@" # Set yes if UE USAGE REPORTING is to be done at UPF
}
AMF :
......@@ -112,15 +117,15 @@ SMF =
LOCAL_CONFIGURATION :
{
SESSION_MANAGEMENT_SUBSCRIPTION_LIST = (
{ NSSAI_SST = @NSSAI_SST0@, NSSAI_SD = "@NSSAI_SD0@", DNN = "default", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 6, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"},
{ NSSAI_SST = @NSSAI_SST1@; NSSAI_SD = "@NSSAI_SD1@", DNN = "oai", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 7, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"},
{ NSSAI_SST = @NSSAI_SST2@; NSSAI_SD = "@NSSAI_SD2@", DNN = "oai.ipv4", DEFAULT_SESSION_TYPE = "IPV4", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = 8, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "20Mbps", SESSION_AMBR_DL = "22Mbps"}
{ NSSAI_SST = @NSSAI_SST0@, NSSAI_SD = "@NSSAI_SD0@", DNN = "@DNN_NI0@", DEFAULT_SESSION_TYPE = "@TYPE0@", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = @QOS_PROFILE_5QI0@, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "@SESSION_AMBR_UL0@", SESSION_AMBR_DL = "@SESSION_AMBR_DL0@"},
{ NSSAI_SST = @NSSAI_SST1@; NSSAI_SD = "@NSSAI_SD1@", DNN = "@DNN_NI1@", DEFAULT_SESSION_TYPE = "@TYPE1@", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = @QOS_PROFILE_5QI1@, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "@SESSION_AMBR_UL1@", SESSION_AMBR_DL = "@SESSION_AMBR_DL1@"},
{ NSSAI_SST = @NSSAI_SST2@; NSSAI_SD = "@NSSAI_SD2@", DNN = "@DNN_NI2@", DEFAULT_SESSION_TYPE = "@TYPE2@", DEFAULT_SSC_MODE = 1,
QOS_PROFILE_5QI = @QOS_PROFILE_5QI2@, QOS_PROFILE_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PRIORITY_LEVEL = 1, QOS_PROFILE_ARP_PREEMPTCAP = "NOT_PREEMPT",
QOS_PROFILE_ARP_PREEMPTVULN = "NOT_PREEMPTABLE", SESSION_AMBR_UL = "@SESSION_AMBR_UL2@", SESSION_AMBR_DL = "@SESSION_AMBR_DL2@"}
);
};
......
......@@ -5,17 +5,27 @@ set -euo pipefail
CONFIG_DIR="/openair-smf/etc"
# Default values
# (Default NWI Domain for all UPFs in OAI-Integration)
ENABLE_USAGE_REPORTING=${ENABLE_USAGE_REPORTING:-no}
USE_NETWORK_INSTANCE=${USE_NETWORK_INSTANCE:-no}
USE_LOCAL_SUBSCRIPTION_INFO=${USE_LOCAL_SUBSCRIPTION_INFO:-yes}
DOMAIN_ACCESS=${DOMAIN_ACCESS:-access.oai.org}
DOMAIN_CORE=${DOMAIN_CORE:-core.oai.org}
UE_MTU=${UE_MTU:-1358}
NSSAI_SST0=${NSSAI_SST0:-222}
NSSAI_SD0=${NSSAI_SD0:-123}
NSSAI_SST1=${NSSAI_SST1:-1}
NSSAI_SD1=${NSSAI_SD1:-1}
NSSAI_SST2=${NSSAI_SST2:-1}
NSSAI_SD2=${NSSAI_SD2:-1}
QOS_PROFILE_5QI0=${QOS_PROFILE_5QI0:-6}
QOS_PROFILE_5QI1=${QOS_PROFILE_5QI1:-7}
QOS_PROFILE_5QI2=${QOS_PROFILE_5QI2:-8}
SESSION_AMBR_UL0=${SESSION_AMBR_UL0:-20Mbps}
SESSION_AMBR_DL0=${SESSION_AMBR_DL0:-22Mbps}
SESSION_AMBR_UL1=${SESSION_AMBR_UL1:-20Mbps}
SESSION_AMBR_DL1=${SESSION_AMBR_DL1:-22Mbps}
SESSION_AMBR_UL2=${SESSION_AMBR_UL2:-20Mbps}
SESSION_AMBR_DL2=${SESSION_AMBR_DL2:-22Mbps}
if [[ ${USE_FQDN_DNS} == "yes" ]];then
AMF_IPV4_ADDRESS=${AMF_IPV4_ADDRESS:-0.0.0.0}
......@@ -23,6 +33,9 @@ if [[ ${USE_FQDN_DNS} == "yes" ]];then
UPF_IPV4_ADDRESS=${UPF_IPV4_ADDRESS:-0.0.0.0}
UDM_IPV4_ADDRESS=${UDM_IPV4_ADDRESS:-0.0.0.0}
fi
DEFAULT_CSCF_IPV4_ADDRESS=${DEFAULT_CSCF_IPV4_ADDRESS:-127.0.0.1}
HTTP_VERSION=${HTTP_VERSION:-1}
DNN_NI0=${DNN_NI0:-oai.ipv4}
......
......@@ -1169,6 +1169,8 @@ typedef struct usage_report_trigger_s {
uint16_t liusa : 1;
uint16_t timqu : 1;
uint16_t volqu : 1;
uint16_t tebur : 1;
uint16_t evequ : 1;
} usage_report_trigger_t;
//-------------------------------------
......@@ -1181,16 +1183,23 @@ typedef struct measurement_period_s {
// 8.2.43 Fully qualified PDN Connection Set Identifier (FQ-CSID)
// typedef fq_csid_t fq_csid_t;
// Extended as per Release 16.5.0, to handle stats related to packet count
//-------------------------------------
// 8.2.44 Volume Measurement
typedef struct volume_measurement_s {
uint8_t spare : 5;
uint8_t spare : 2;
uint8_t dlnop : 1;
uint8_t ulnop : 1;
uint8_t tonop : 1;
uint8_t dlvol : 1;
uint8_t ulvol : 1;
uint8_t tovol : 1;
uint64_t total_volume;
uint64_t uplink_volume;
uint64_t downlink_volume;
uint64_t total_nop;
uint64_t uplink_nop;
uint64_t downlink_nop;
} volume_measurement_t;
//-------------------------------------
......@@ -1557,7 +1566,7 @@ typedef struct user_plane_ip_resource_information_s {
uint8_t teid_range;
struct in_addr ipv4_address;
struct in6_addr ipv6_address;
uint16_t network_instance;
std::string network_instance;
uint8_t source_interface;
} user_plane_ip_resource_information_t;
......
......@@ -32,6 +32,10 @@ typedef uint64_t supi64_t;
#define SUPI_DIGITS_MAX 15
const uint32_t SD_NO_VALUE = 0xFFFFFF;
const std::string SD_NO_VALUE_STR = "0xFFFFFF";
const uint8_t SST_MAX_STANDARDIZED_VALUE = 127;
typedef struct {
uint32_t length;
char data[SUPI_DIGITS_MAX + 1];
......@@ -58,15 +62,23 @@ static uint64_t smf_supi_to_u64(supi_t supi) {
typedef struct s_nssai // section 28.4, TS23.003
{
uint8_t sST;
// uint32_t sD:24;
std::string sD;
// s_nssai(const uint8_t& sst, const uint32_t sd) : sST(sst), sD(sd) {}
s_nssai(const uint8_t& sst, const std::string sd) : sST(sst), sD(sd) {}
s_nssai() : sST(), sD() {}
s_nssai(const s_nssai& p) : sST(p.sST), sD(p.sD) {}
uint8_t sst;
uint32_t sd;
s_nssai(const uint8_t& m_sst, const uint32_t m_sd) : sst(m_sst), sd(m_sd) {}
s_nssai(const uint8_t& m_sst, const std::string m_sd) : sst(m_sst) {
sd = 0xFFFFFF;
try {
sd = std::stoul(m_sd, nullptr, 10);
} catch (const std::exception& e) {
Logger::smf_app().warn(
"Error when converting from string to int for snssai.SD, error: %s",
e.what());
}
}
s_nssai() : sst(), sd() {}
s_nssai(const s_nssai& p) : sst(p.sst), sd(p.sd) {}
bool operator==(const struct s_nssai& s) const {
if ((s.sST == this->sST) && (s.sD.compare(this->sD) == 0)) {
if ((s.sst == this->sst) && (s.sd == this->sd)) {
return true;
} else {
return false;
......@@ -74,15 +86,15 @@ typedef struct s_nssai // section 28.4, TS23.003
}
s_nssai& operator=(const struct s_nssai& s) {
sST = s.sST;
sD = s.sD;
sst = s.sst;
sd = s.sd;
return *this;
}
std::string toString() const {
std::string s = {};
s.append("SST=").append(std::to_string(sST));
s.append(", SD=").append(sD);
s.append("SST=").append(std::to_string(sst));
s.append(", SD=").append(std::to_string(sd));
return s;
}
......@@ -174,8 +186,8 @@ enum class sm_context_status_e {
SM_CONTEXT_STATUS_RELEASED = 1
};
static const std::vector<std::string> sm_context_status_e2str = {"ACTIVE",
"RELEASED"};
static const std::vector<std::string> sm_context_status_e2str = {
"ACTIVE", "RELEASED"};
typedef struct qos_profile_gbr_s {
gfbr_t gfbr; // Guaranteed Flow Bit Rate
......
......@@ -32,6 +32,8 @@
#include <stdbool.h>
#include <ctype.h>
#include <inttypes.h>
#include <boost/algorithm/string.hpp>
#include "SmContextCreateData.h"
#include "SmContextUpdateData.h"
#include "SmContextReleaseData.h"
......@@ -558,8 +560,8 @@ void xgpp_conv::smf_event_exposure_notification_from_openapi(
void xgpp_conv::sm_context_request_from_nas(
const nas_message_t& nas_msg,
smf::pdu_session_create_sm_context_request& pcr) {
pdu_session_type_t pdu_session_type = {.pdu_session_type =
PDU_SESSION_TYPE_E_IPV4};
pdu_session_type_t pdu_session_type = {
.pdu_session_type = PDU_SESSION_TYPE_E_IPV4};
// Extended Protocol Discriminator
pcr.set_epd(nas_msg.header.extended_protocol_discriminator);
// Message Type
......@@ -634,3 +636,23 @@ void xgpp_conv::update_sm_context_response_from_ctx_request(
ct_response->res.set_snssai(ct_request->req.get_snssai());
ct_response->res.set_dnn(ct_request->req.get_dnn());
}
//------------------------------------------------------------------------------
void xgpp_conv::sd_string_to_int(const std::string& sd_str, uint32_t& sd) {
sd = SD_NO_VALUE;
if (sd_str.empty()) return;
uint8_t base = 10;
try {
if (sd_str.size() > 2) {
if (boost::iequals(sd_str.substr(0, 2), "0x")) {
base = 16;
}
}
sd = std::stoul(sd_str, nullptr, base);
} catch (const std::exception& e) {
Logger::smf_app().error(
"Error when converting from string to int for S-NSSAI SD, error: %s",
e.what());
sd = SD_NO_VALUE;
}
}
......@@ -169,6 +169,7 @@ void update_sm_context_response_from_ctx_request(
const std::shared_ptr<itti_n11_update_sm_context_request>& ct_request,
std::shared_ptr<itti_n11_update_sm_context_response>& ct_response);
void sd_string_to_int(const std::string& sd_str, uint32_t& sd);
} // namespace xgpp_conv
#endif /* FILE_3GPP_CONVERSIONS_HPP_SEEN */
......@@ -45,7 +45,8 @@ int encode_snssai(SNSSAI snssai, uint8_t iei, uint8_t* buffer, uint32_t len) {
ielen = snssai.len;
if (snssai.sd == 0) ielen = 1; // Don't include SD if it = 0
if (snssai.sd == 0xffffff)
ielen = SST_LENGTH; // TODO: Don't include SD if it = 0xffffff
*(buffer + encoded) = ielen;
encoded++;
......
......@@ -378,34 +378,34 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) {
// pfcp_measurement_method_ie(tlv); ie->load_from(is); return ie;
// }
// break;
// case PFCP_IE_USAGE_REPORT_TRIGGER: {
// pfcp_usage_report_trigger_ie *ie = new
// pfcp_usage_report_trigger_ie(tlv); ie->load_from(is); return
// ie;
// }
// break;
// case PFCP_IE_MEASUREMENT_PERIOD: {
// pfcp_measurement_period_ie *ie = new
// pfcp_measurement_period_ie(tlv); ie->load_from(is); return ie;
// }
// break;
case PFCP_IE_USAGE_REPORT_TRIGGER: {
pfcp_usage_report_trigger_ie* ie =
new pfcp_usage_report_trigger_ie(tlv);
ie->load_from(is);
return ie;
} break;
case PFCP_IE_MEASUREMENT_PERIOD: {
pfcp_measurement_period_ie* ie = new pfcp_measurement_period_ie(tlv);
ie->load_from(is);
return ie;
} break;
// case PFCP_IE_FQ_CSID: {
// pfcp_fq_csid_ie *ie = new pfcp_fq_csid_ie(tlv);
// ie->load_from(is);
// return ie;
// }
// break;
// case PFCP_IE_VOLUME_MEASUREMENT: {
// pfcp_volume_measurement_ie *ie = new
// pfcp_volume_measurement_ie(tlv); ie->load_from(is); return ie;
// }
// break;
// case PFCP_IE_DURATION_MEASUREMENT: {
// pfcp_duration_measurement_ie *ie = new
// pfcp_duration_measurement_ie(tlv); ie->load_from(is); return
// ie;
// }
// break;
case PFCP_IE_VOLUME_MEASUREMENT: {
pfcp_volume_measurement_ie* ie = new pfcp_volume_measurement_ie(tlv);
ie->load_from(is);
return ie;
} break;
case PFCP_IE_DURATION_MEASUREMENT: {
pfcp_duration_measurement_ie* ie =
new pfcp_duration_measurement_ie(tlv);
ie->load_from(is);
return ie;
} break;
// case PFCP_IE_APPLICATION_DETECTION_INFORMATION: {
// pfcp_application_detection_information_ie *ie = new
// pfcp_application_detection_information_ie(tlv);
......@@ -413,18 +413,17 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) {
// return ie;
// }
// break;
// case PFCP_IE_TIME_OF_FIRST_PACKET: {
// pfcp_time_of_first_packet_ie *ie = new
// pfcp_time_of_first_packet_ie(tlv); ie->load_from(is); return
// ie;
// }
// break;
// case PFCP_IE_TIME_OF_LAST_PACKET: {
// pfcp_time_of_last_packet_ie *ie = new
// pfcp_time_of_last_packet_ie(tlv); ie->load_from(is); return
// ie;
// }
// break;
case PFCP_IE_TIME_OF_FIRST_PACKET: {
pfcp_time_of_first_packet_ie* ie =
new pfcp_time_of_first_packet_ie(tlv);
ie->load_from(is);
return ie;
} break;
case PFCP_IE_TIME_OF_LAST_PACKET: {
pfcp_time_of_last_packet_ie* ie = new pfcp_time_of_last_packet_ie(tlv);
ie->load_from(is);
return ie;
} break;
// case PFCP_IE_QUOTA_HOLDING_TIME: {
// pfcp_quota_holding_time_ie *ie = new
// pfcp_quota_holding_time_ie(tlv); ie->load_from(is); return ie;
......@@ -448,18 +447,16 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) {
// return ie;
// }
// break;
// case PFCP_IE_START_TIME: {
// pfcp_start_time_ie *ie = new pfcp_start_time_ie(tlv);
// ie->load_from(is);
// return ie;
// }
// break;
// case PFCP_IE_END_TIME: {
// pfcp_end_time_ie *ie = new pfcp_end_time_ie(tlv);
// ie->load_from(is);
// return ie;
// }
// break;
case PFCP_IE_START_TIME: {
pfcp_start_time_ie* ie = new pfcp_start_time_ie(tlv);
ie->load_from(is);
return ie;
} break;
case PFCP_IE_END_TIME: {
pfcp_end_time_ie* ie = new pfcp_end_time_ie(tlv);
ie->load_from(is);
return ie;
} break;
// case PFCP_IE_QUERY_URR: {
// pfcp_query_urr_ie *ie = new pfcp_query_urr_ie(tlv);
// ie->load_from(is);
......@@ -482,13 +479,12 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) {
// return ie;
// }
// break;
// case PFCP_IE_USAGE_REPORT_WITHIN_SESSION_REPORT_REQUEST: {
// pfcp_usage_report_within_session_report_request_ie *ie = new
// pfcp_usage_report_within_session_report_request_ie(tlv);
// ie->load_from(is);
// return ie;
// }
// break;
case PFCP_IE_USAGE_REPORT_WITHIN_SESSION_REPORT_REQUEST: {
pfcp_usage_report_within_session_report_request_ie* ie =
new pfcp_usage_report_within_session_report_request_ie(tlv);
ie->load_from(is);
return ie;
} break;
case PFCP_IE_URR_ID: {
pfcp_urr_id_ie* ie = new pfcp_urr_id_ie(tlv);
ie->load_from(is);
......@@ -622,12 +618,11 @@ pfcp_ie* pfcp_ie::new_pfcp_ie_from_stream(std::istream& is) {
// pfcp_remote_gtp_u_peer_ie(tlv); ie->load_from(is); return ie;
// }
// break;
// case PFCP_IE_UR_SEQN: {
// pfcp_ur_seqn_ie *ie = new pfcp_ur_seqn_ie(tlv);
// ie->load_from(is);
// return ie;
// }
// break;
case PFCP_IE_UR_SEQN: {
pfcp_ur_seqn_ie* ie = new pfcp_ur_seqn_ie(tlv);
ie->load_from(is);
return ie;
} break;
// case PFCP_IE_UPDATE_DUPLICATING_PARAMETERS: {
// pfcp_update_duplicating_parameters_ie *ie = new
// pfcp_update_duplicating_parameters_ie(tlv); ie->load_from(is);
......@@ -1411,6 +1406,12 @@ pfcp_msg::pfcp_msg(const pfcp_session_report_request& pfcp_ies)
new pfcp_downlink_data_report_ie(pfcp_ies.downlink_data_report.second));
add_ie(sie);
}
if (pfcp_ies.usage_report.first) {
std::shared_ptr<pfcp_usage_report_within_session_report_request_ie> sie(
new pfcp_usage_report_within_session_report_request_ie(
pfcp_ies.usage_report.second));
add_ie(sie);
}
// TODO std::pair<bool, pfcp::usage_report_within_pfcp_session_report_request>
// usage_report;
// TODO std::pair<bool, pfcp::error_indication_report>
......
This diff is collapsed.
......@@ -5100,6 +5100,7 @@ class usage_report_within_pfcp_session_report_request
// std::pair<bool, pfcp::event_reporting> event_reporting;
std::pair<bool, pfcp::ethernet_traffic_information>
ethernet_traffic_information;
std::pair<bool, pfcp::enterprise_specific_t> enterprise_specific;
usage_report_within_pfcp_session_report_request()
: urr_id(),
......@@ -5117,7 +5118,8 @@ class usage_report_within_pfcp_session_report_request
usage_information(),
query_urr_reference(),
// event_reporting(),
ethernet_traffic_information() {}
ethernet_traffic_information(),
enterprise_specific() {}
usage_report_within_pfcp_session_report_request(
const usage_report_within_pfcp_session_report_request& u)
......@@ -5136,7 +5138,8 @@ class usage_report_within_pfcp_session_report_request
usage_information(u.usage_information),
query_urr_reference(u.query_urr_reference),
// event_reporting(u.event_reporting),
ethernet_traffic_information(u.ethernet_traffic_information) {}
ethernet_traffic_information(u.ethernet_traffic_information),
enterprise_specific(u.enterprise_specific) {}
// virtual ~usage_report_within_pfcp_session_report_request() {};
void set(const pfcp::urr_id_t& v) {
......@@ -5201,6 +5204,10 @@ class usage_report_within_pfcp_session_report_request
ethernet_traffic_information.first = true;
ethernet_traffic_information.second = v;
}
void set(const pfcp::enterprise_specific_t& v) {
enterprise_specific.first = true;
enterprise_specific.second = v;
}
bool get(pfcp::urr_id_t& v) const {
if (urr_id.first) {
......@@ -5300,6 +5307,13 @@ class usage_report_within_pfcp_session_report_request
}
return false;
}
bool get(pfcp::enterprise_specific_t& v) const {
if (enterprise_specific.first) {
v = enterprise_specific.second;
return true;
}
return false;
}
// bool get(pfcp::event_reporting& v) const {if (event_reporting.first) {v =
// event_reporting.second;return true;}return false;}
bool get(pfcp::ethernet_traffic_information& v) const {
......@@ -7244,15 +7258,16 @@ class pfcp_session_report_request : public pfcp_ies_container {
overload_control_information(),
additional_usage_reports_information() {}
pfcp_session_report_request(const pfcp_session_report_request& i)
: report_type(i.report_type),
downlink_data_report(i.downlink_data_report),
usage_report(i.usage_report),
error_indication_report(i.error_indication_report),
load_control_information(i.load_control_information),
overload_control_information(i.overload_control_information),
additional_usage_reports_information(
i.additional_usage_reports_information) {}
pfcp_session_report_request(const pfcp_session_report_request& i) {
report_type = i.report_type;
downlink_data_report = i.downlink_data_report;
usage_report = i.usage_report;
error_indication_report = i.error_indication_report;
load_control_information = i.load_control_information;
overload_control_information = i.overload_control_information;
additional_usage_reports_information =
i.additional_usage_reports_information;
}
const char* get_msg_name() const { return "PFCP_SESSION_REPORT_REQUEST"; };
......
......@@ -785,8 +785,8 @@ void smf_app::handle_pdu_session_create_sm_context_request(
std::string n1_sm_message, n1_sm_message_hex;
nas_message_t decoded_nas_msg = {};
cause_value_5gsm_e cause_n1 = {cause_value_5gsm_e::CAUSE_0_UNKNOWN};
pdu_session_type_t pdu_session_type = {.pdu_session_type =
PDU_SESSION_TYPE_E_IPV4};
pdu_session_type_t pdu_session_type = {
.pdu_session_type = PDU_SESSION_TYPE_E_IPV4};
// Step 1. Decode NAS and get the necessary information
int decoder_rc = smf_n1::get_instance().decode_n1_sm_container(
......@@ -853,8 +853,8 @@ void smf_app::handle_pdu_session_create_sm_context_request(
snssai_t snssai = smreq->req.get_snssai();
Logger::smf_app().info(
"Handle a PDU Session Create SM Context Request message from AMF, "
"SUPI " SUPI_64_FMT ", SNSSAI SST %d, SD %s",
supi64, snssai.sST, snssai.sD.c_str());
"SUPI " SUPI_64_FMT ", SNSSAI SST %d, SD %ld (0x%x)",
supi64, snssai.sst, snssai.sd, snssai.sd);
// Step 2. Verify Procedure transaction id, pdu session id, message type,
// request type, etc.
......@@ -1878,8 +1878,8 @@ bool smf_app::get_session_management_subscription_data(
std::make_shared<dnn_configuration_t>();
for (auto sub : smf_cfg.session_management_subscriptions) {
if ((0 == dnn.compare(sub.dnn)) and (snssai.sST == sub.single_nssai.sST) and
(0 == snssai.sD.compare(sub.single_nssai.sD))) {
if ((0 == dnn.compare(sub.dnn)) and (snssai.sst == sub.single_nssai.sst) and
(snssai.sd == sub.single_nssai.sd)) {
// PDU Session Type
pdu_session_type_t pdu_session_type(
pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4);
......@@ -2278,14 +2278,14 @@ void smf_app::generate_smf_profile() {
for (auto sms : smf_cfg.session_management_subscriptions) {
// SNSSAIS
snssai_t snssai = {};
snssai.sD = sms.single_nssai.sD;
snssai.sST = sms.single_nssai.sST;
snssai.sd = sms.single_nssai.sd;
snssai.sst = sms.single_nssai.sst;
// Verify if this SNSSAI exist
std::vector<snssai_t> ss = {};
nf_instance_profile.get_nf_snssais(ss);
bool found = false;
for (auto it : ss) {
if ((it.sD == snssai.sD) and (it.sST == snssai.sST)) {
if ((it.sd == snssai.sd) and (it.sst == snssai.sst)) {
found = true;
break;
}
......@@ -2296,8 +2296,8 @@ void smf_app::generate_smf_profile() {
dnn_smf_info_item_t dnn_item = {.dnn = sms.dnn};
snssai_smf_info_item_t smf_info_item = {};
smf_info_item.dnn_smf_info_list.push_back(dnn_item);
smf_info_item.snssai.sD = sms.single_nssai.sD;
smf_info_item.snssai.sST = sms.single_nssai.sST;
smf_info_item.snssai.sd = sms.single_nssai.sd;
smf_info_item.snssai.sst = sms.single_nssai.sst;
nf_instance_profile.add_smf_info_item(smf_info_item);
}
......
......@@ -193,6 +193,26 @@ class smf_app {
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id);
/*
* process_pco_p_cscf_request
* @param [protocol_configuration_options_t &] pco_resp
* @param [pco_protocol_or_container_id_t *const] proc_id
* @return
*/
int process_pco_p_cscf_request(
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id);
/*
* process_pco_p_cscf_v6_request
* @param [protocol_configuration_options_t &] pco_resp
* @param [pco_protocol_or_container_id_t *const] proc_id
* @return
*/
int process_pco_p_cscf_v6_request(
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id);
public:
explicit smf_app(const std::string& config_file);
smf_app(smf_app const&) = delete;
......
......@@ -50,6 +50,7 @@
#include "logger.hpp"
#include "fqdn.hpp"
#include "smf_app.hpp"
#include "3gpp_conversions.hpp"
using namespace std;
using namespace libconfig;
......@@ -442,6 +443,26 @@ int smf_config::load(const string& config_file) {
util::trim(astring).c_str(), default_dns_secv4,
"BAD IPv4 ADDRESS FORMAT FOR DEFAULT DNS !");
// Default CSCF
smf_cfg.lookupValue(SMF_CONFIG_STRING_DEFAULT_CSCF_IPV4_ADDRESS, astring);
IPV4_STR_ADDR_TO_INADDR(
util::trim(astring).c_str(), default_cscfv4,
"BAD IPv4 ADDRESS FORMAT FOR DEFAULT CSCF !");
smf_cfg.lookupValue(SMF_CONFIG_STRING_DEFAULT_CSCF_IPV6_ADDRESS, astring);
if (inet_pton(AF_INET6, util::trim(astring).c_str(), buf_in6_addr) == 1) {
memcpy(&default_cscfv6, buf_in6_addr, sizeof(struct in6_addr));
} else {
Logger::smf_app().error(
"CONFIG : BAD ADDRESS in " SMF_CONFIG_STRING_DEFAULT_CSCF_IPV6_ADDRESS
" %s",
astring.c_str());
throw(
"CONFIG : BAD ADDRESS in " SMF_CONFIG_STRING_DEFAULT_CSCF_IPV6_ADDRESS
" %s",
astring.c_str());
}
smf_cfg.lookupValue(SMF_CONFIG_STRING_DEFAULT_DNS_IPV6_ADDRESS, astring);
if (inet_pton(AF_INET6, util::trim(astring).c_str(), buf_in6_addr) == 1) {
memcpy(&default_dnsv6, buf_in6_addr, sizeof(struct in6_addr));
......@@ -530,6 +551,14 @@ int smf_config::load(const string& config_file) {
use_nwi = false;
}
support_features.lookupValue(
SMF_CONFIG_STRING_SUPPORT_FEATURES_ENABLE_USAGE_REPORTING, opt);
if (boost::iequals(opt, "yes")) {
enable_ur = true;
} else {
enable_ur = false;
}
} catch (const SettingNotFoundException& nfex) {
Logger::smf_app().error(
"%s : %s, using defaults", nfex.what(), nfex.getPath());
......@@ -774,7 +803,7 @@ int smf_config::load(const string& config_file) {
session_management_subscription_t sub_item = {};
unsigned int nssai_sst = 0;
string nssai_sd = {};
string nssai_sd = SD_NO_VALUE_STR;
string dnn = {};
string default_session_type = {};
unsigned int default_ssc_mode = 0;
......@@ -814,9 +843,9 @@ int smf_config::load(const string& config_file) {
SMF_CONFIG_STRING_SESSION_AMBR_UL, session_ambr_ul);
session_management_subscription_cfg.lookupValue(
SMF_CONFIG_STRING_SESSION_AMBR_DL, session_ambr_dl);
sub_item.single_nssai.sST = nssai_sst;
sub_item.single_nssai.sD = nssai_sd;
sub_item.single_nssai.sst = nssai_sst;
sub_item.single_nssai.sd = SD_NO_VALUE;
xgpp_conv::sd_string_to_int(nssai_sd, sub_item.single_nssai.sd);
sub_item.session_type = default_session_type;
sub_item.dnn = dnn;
sub_item.ssc_mode = default_ssc_mode;
......@@ -868,7 +897,6 @@ void smf_config::display() {
n4.thread_rd_sched_params.sched_policy); Logger::smf_app().info( "
Scheduling prio .....: %d", n4.thread_rd_sched_params.sched_priority);
Logger::smf_app().info("- ITTI Timer Task Threading:");
Logger::smf_app().info(
" CPU id ..............: %d", itti.itti_timer_sched_params.cpu_id);
Logger::smf_app().info(
......@@ -966,6 +994,12 @@ void smf_config::display() {
Logger::smf_app().info(" Secondary DNS v6 ....: %s", str_addr6);
}
Logger::smf_app().info(
" CSCF .........: %s", inet_ntoa(*((struct in_addr*) &default_cscfv4)));
if (inet_ntop(AF_INET6, &default_cscfv6, str_addr6, sizeof(str_addr6))) {
Logger::smf_app().info(" CSCF v6 ......: %s", str_addr6);
}
Logger::smf_app().info("- Default UE MTU: %d", ue_mtu);
Logger::smf_app().info("- Supported Features:");
Logger::smf_app().info(
......@@ -1024,37 +1058,42 @@ void smf_config::display() {
for (auto sub : session_management_subscriptions) {
Logger::smf_app().info(
" Session Management Subscription Data %d:", index);
if (sub.single_nssai.sd != SD_NO_VALUE) {
Logger::smf_app().info(
" SST, SD: %d, %ld (0x%x)", sub.single_nssai.sst,
sub.single_nssai.sd, sub.single_nssai.sd);
} else {
Logger::smf_app().info(" SST: %d", sub.single_nssai.sst);
}
Logger::smf_app().info(
" " SMF_CONFIG_STRING_NSSAI_SST
": %d, " SMF_CONFIG_STRING_NSSAI_SD " %s",
sub.single_nssai.sST, sub.single_nssai.sD.c_str());
Logger::smf_app().info(
" " SMF_CONFIG_STRING_DNN ": %s", sub.dnn.c_str());
" " SMF_CONFIG_STRING_DNN ": %s", sub.dnn.c_str());
Logger::smf_app().info(
" " SMF_CONFIG_STRING_DEFAULT_SESSION_TYPE ": %s",
" " SMF_CONFIG_STRING_DEFAULT_SESSION_TYPE ": %s",
sub.session_type.c_str());
Logger::smf_app().info(
" " SMF_CONFIG_STRING_DEFAULT_SSC_MODE ": %d", sub.ssc_mode);
" " SMF_CONFIG_STRING_DEFAULT_SSC_MODE ": %d", sub.ssc_mode);
Logger::smf_app().info(
" " SMF_CONFIG_STRING_QOS_PROFILE_5QI ": %d",
" " SMF_CONFIG_STRING_QOS_PROFILE_5QI ": %d",
sub.default_qos._5qi);
Logger::smf_app().info(
" " SMF_CONFIG_STRING_QOS_PROFILE_PRIORITY_LEVEL ": %d",
" " SMF_CONFIG_STRING_QOS_PROFILE_PRIORITY_LEVEL ": %d",
sub.default_qos.priority_level);
Logger::smf_app().info(
" " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PRIORITY_LEVEL ": %d",
" " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PRIORITY_LEVEL ": %d",
sub.default_qos.arp.priority_level);
Logger::smf_app().info(
" " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTCAP ": %s",
" " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTCAP ": %s",
sub.default_qos.arp.preempt_cap.c_str());
Logger::smf_app().info(
" " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTVULN ": %s",
" " SMF_CONFIG_STRING_QOS_PROFILE_ARP_PREEMPTVULN ": %s",
sub.default_qos.arp.preempt_vuln.c_str());
Logger::smf_app().info(
" " SMF_CONFIG_STRING_SESSION_AMBR_UL ": %s",
" " SMF_CONFIG_STRING_SESSION_AMBR_UL ": %s",
sub.session_ambr.uplink.c_str());
Logger::smf_app().info(
" " SMF_CONFIG_STRING_SESSION_AMBR_DL ": %s",
" " SMF_CONFIG_STRING_SESSION_AMBR_DL ": %s",
sub.session_ambr.downlink.c_str());
index++;
}
......
......@@ -67,6 +67,9 @@
#define SMF_CONFIG_STRING_IPV4_ADDRESS_RANGE_DELIMITER "-"
#define SMF_CONFIG_STRING_IPV6_ADDRESS_PREFIX_DELIMITER "/"
#define SMF_CONFIG_STRING_DEFAULT_DNS_IPV4_ADDRESS "DEFAULT_DNS_IPV4_ADDRESS"
#define SMF_CONFIG_STRING_DEFAULT_CSCF_IPV4_ADDRESS "DEFAULT_CSCF_IPV4_ADDRESS"
#define SMF_CONFIG_STRING_DEFAULT_CSCF_IPV6_ADDRESS "DEFAULT_CSCF_IPV6_ADDRESS"
#define SMF_CONFIG_STRING_DEFAULT_DNS_SEC_IPV4_ADDRESS \
"DEFAULT_DNS_SEC_IPV4_ADDRESS"
#define SMF_CONFIG_STRING_DEFAULT_DNS_IPV6_ADDRESS "DEFAULT_DNS_IPV6_ADDRESS"
......@@ -149,6 +152,8 @@
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_SBI_HTTP_VERSION "HTTP_VERSION"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_USE_NETWORK_INSTANCE \
"USE_NETWORK_INSTANCE"
#define SMF_CONFIG_STRING_SUPPORT_FEATURES_ENABLE_USAGE_REPORTING \
"ENABLE_USAGE_REPORTING"
#define SMF_MAX_ALLOCATED_PDN_ADDRESSES 1024
......@@ -217,10 +222,11 @@ class smf_config {
struct in_addr default_dnsv4;
struct in_addr default_dns_secv4;
struct in_addr default_cscfv4;
struct in6_addr default_dnsv6;
struct in6_addr default_dns_secv6;
std::map<std::string, dnn_t> dnns;
struct in6_addr default_cscfv6;
bool force_push_pco;
uint ue_mtu;
......@@ -231,6 +237,7 @@ class smf_config {
bool use_fqdn_dns;
unsigned int http_version;
bool use_nwi;
bool enable_ur;
struct {
struct in_addr ipv4_addr;
......
This diff is collapsed.
......@@ -448,6 +448,20 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
*/
pdu_session_type_t get_pdu_session_type() const;
/*
* Get URR_ID associated with this PDU Session
* @param void
* @return uint32_t: urrId
*/
uint32_t get_urr_id() const;
/*
* Set URR_ID associated with this PDU Session
* @param [const uint32_t&] urrId: URR_ID
* @return void
*/
void set_urr_id(const uint32_t& urrId);
/*
* Get NWI associated with this PDU Session
* @param void
......@@ -548,6 +562,9 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
std::string dnn; // associated DNN
snssai_t snssai; // associated SNSSAI
uint32_t
urr_Id; // We maintain URR ID to reuse for DL PDR (session modification)
std::string nwi_access; // associated nwi_access
std::string nwi_core; // associated nwi_core
......@@ -1065,6 +1082,14 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
const snssai_t& snssai,
std::shared_ptr<session_management_subscription>& ss);
/*
* Get a unique key from SNSSAI
* @param [const snssai_t&] snssai
* @param [uint32_t&] key: generated key
* @return void
*/
void get_snssai_key(const snssai_t& snssai, uint32_t& key);
/*
* Convert all members of this class to string for logging
* @return std::string
......@@ -1333,8 +1358,8 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
private:
std::vector<std::shared_ptr<smf_procedure>> pending_procedures;
// snssai-sst <-> session management subscription
std::map<uint8_t, std::shared_ptr<session_management_subscription>>
// snssai <-> session management subscription
std::map<uint32_t, std::shared_ptr<session_management_subscription>>
dnn_subscriptions;
std::map<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>
pdu_sessions; // Store all PDU Sessions associated with this UE
......
......@@ -201,24 +201,20 @@ bool smf_n1::create_n1_pdu_session_establishment_accept(
// sm_msg->pdu_session_establishment_accept.gprstimer.timeValue = 0;
// SNSSAI
sm_msg->pdu_session_establishment_accept.snssai.len = SST_AND_SD_LENGTH;
sm_msg->pdu_session_establishment_accept.snssai.sst =
sm_context_res.get_snssai().sST;
try {
sm_msg->pdu_session_establishment_accept.snssai.sd =
std::stoul(sm_context_res.get_snssai().sD, nullptr, 10);
} catch (const std::exception& e) {
Logger::smf_n1().warn(
"Error when converting from string to int for snssai.SD, error: %s",
e.what());
//"no SD value associated with the SST"
sm_msg->pdu_session_establishment_accept.snssai.sd = 0xFFFFFF;
if (sm_context_res.get_snssai().sd == SD_NO_VALUE) {
sm_msg->pdu_session_establishment_accept.snssai.len = SST_LENGTH;
} else {
sm_msg->pdu_session_establishment_accept.snssai.len = SST_AND_SD_LENGTH;
}
sm_msg->pdu_session_establishment_accept.snssai.sst =
sm_context_res.get_snssai().sst;
sm_msg->pdu_session_establishment_accept.snssai.sd =
sm_context_res.get_snssai().sd;
Logger::smf_n1().debug(
"SNSSAI SST %d, SD %#0x",
"SNSSAI SST %d, SD %ld (0x%x)",
sm_msg->pdu_session_establishment_accept.snssai.sst,
sm_msg->pdu_session_establishment_accept.snssai.sd,
sm_msg->pdu_session_establishment_accept.snssai.sd);
// TODO: AlwaysonPDUSessionIndication
......
......@@ -691,11 +691,11 @@ void smf_n4::handle_receive_session_deletion_response(
//------------------------------------------------------------------------------
void smf_n4::handle_receive_session_report_request(
pfcp::pfcp_msg& msg, const endpoint& remote_endpoint) {
Logger::smf_n4().info("Received N4 SESSION REPORT REQUEST from an UPF");
bool error = true;
uint64_t trxn_id = 0;
pfcp_session_report_request msg_ies_container = {};
msg.to_core_type(msg_ies_container);
handle_receive_message_cb(msg, remote_endpoint, TASK_SMF_N4, error, trxn_id);
if (!error) {
std::shared_ptr<itti_n4_session_report_request> itti_msg =
......@@ -705,7 +705,8 @@ void smf_n4::handle_receive_session_report_request(
itti_msg->r_endpoint = remote_endpoint;
itti_msg->trxn_id = trxn_id;
itti_msg->seid = msg.get_seid();
int ret = itti_inst->send_msg(itti_msg);
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_n4().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
......
......@@ -335,6 +335,57 @@ int smf_app::process_pco_link_mtu_request(
return pco_push_protocol_or_container_id(pco_resp, &poc_id_resp);
}
//------------------------------------------------------------------------------
int smf_app::process_pco_p_cscf_request(
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id) {
in_addr_t cscf_ipv4_addr = smf_cfg.default_cscfv4.s_addr;
pco_protocol_or_container_id_t poc_id_resp = {0};
uint8_t cscf_array[4];
Logger::smf_app().debug("PCO: Protocol identifier P CSCF Request");
poc_id_resp.protocol_id = PCO_CONTAINER_IDENTIFIER_P_CSCF_IPV4_ADDRESS;
poc_id_resp.length_of_protocol_id_contents = 4;
cscf_array[0] = (uint8_t)(cscf_ipv4_addr & 0x000000FF);
cscf_array[1] = (uint8_t)((cscf_ipv4_addr >> 8) & 0x000000FF);
cscf_array[2] = (uint8_t)((cscf_ipv4_addr >> 16) & 0x000000FF);
cscf_array[3] = (uint8_t)((cscf_ipv4_addr >> 24) & 0x000000FF);
std::string tmp_s((const char*) &cscf_array[0], sizeof(cscf_array));
poc_id_resp.protocol_id_contents = tmp_s;
return pco_push_protocol_or_container_id(pco_resp, &poc_id_resp);
}
//------------------------------------------------------------------------------
int smf_app::process_pco_p_cscf_v6_request(
protocol_configuration_options_t& pco_resp,
const pco_protocol_or_container_id_t* const poc_id) {
in6_addr cscf_ipv6_addr = smf_cfg.default_cscfv6;
pco_protocol_or_container_id_t poc_id_resp = {0};
uint8_t cscfv6_array[16];
Logger::smf_app().debug("PCO: Protocol identifier P CSCF v6 Request");
poc_id_resp.protocol_id = PCO_CONTAINER_IDENTIFIER_P_CSCF_IPV6_ADDRESS;
poc_id_resp.length_of_protocol_id_contents = 16;
char str_addr6[INET6_ADDRSTRLEN];
if (inet_ntop(AF_INET6, &cscf_ipv6_addr, str_addr6, sizeof(str_addr6))) {
std::string ipv6_addr_str((char*) str_addr6, INET6_ADDRSTRLEN);
Logger::smf_app().info(" CSCF Ipv6 address....: %s", ipv6_addr_str.c_str());
unsigned char buf_in6_addr[sizeof(struct in6_addr)];
if (inet_pton(AF_INET6, util::trim(ipv6_addr_str).c_str(), buf_in6_addr) ==
1) {
for (int i = 0; i <= 15; i++)
cscfv6_array[i] = (uint8_t)(buf_in6_addr[i]);
}
}
std::string tmp_s((const char*) &cscfv6_array[0], sizeof(cscfv6_array));
poc_id_resp.protocol_id_contents = tmp_s;
return pco_push_protocol_or_container_id(pco_resp, &poc_id_resp);
}
//------------------------------------------------------------------------------
int smf_app::process_pco_request(
const protocol_configuration_options_t& pco_req,
......@@ -384,6 +435,17 @@ int smf_app::process_pco_request(
pco_ids.ci_ipv4_link_mtu_request = true;
break;
case PCO_CONTAINER_IDENTIFIER_P_CSCF_IPV6_ADDRESS_REQUEST:
process_pco_p_cscf_v6_request(
pco_resp, &pco_req.protocol_or_container_ids[id]);
pco_ids.ci_ipv6_p_cscf_request = true;
break;
case PCO_CONTAINER_IDENTIFIER_P_CSCF_IPV4_ADDRESS_REQUEST:
process_pco_p_cscf_request(
pco_resp, &pco_req.protocol_or_container_ids[id]);
pco_ids.ci_ipv4_p_cscf_request = true;
break;
default:
Logger::smf_app().warn(
"PCO: Protocol/container identifier 0x%04X not supported now",
......
......@@ -48,6 +48,8 @@ typedef struct protocol_configuration_options_ids_s {
uint8_t ci_ipv4_address_allocation_via_dhcpv4 : 1;
uint8_t ci_ipv4_link_mtu_request : 1;
uint8_t ci_dns_server_ipv6_address_request : 1;
uint8_t ci_ipv6_p_cscf_request : 1;
uint8_t ci_ipv4_p_cscf_request : 1;
} protocol_configuration_options_ids_t;
#endif
......@@ -467,15 +467,19 @@ bool pfcp_associations::select_up_node(
Logger::smf_app().debug("UPF info: %s", upf_info.to_string().c_str());
for (auto ui : upf_info.snssai_upf_info_list) {
if (ui.snssai == snssai) {
for (auto d : ui.dnn_upf_info_list) {
if (d.dnn.compare(dnn) == 0) {
node_id = it->second->node_id;
Logger::smf_app().info(
"Select the UPF for the corresponding DNN %s, NSSSAI (SD: %s, "
"SST: %d) ",
d.dnn.c_str(), snssai.sD.c_str(), snssai.sST);
return true;
if (ui.snssai.sst == snssai.sst) {
if ((ui.snssai.sst <= SST_MAX_STANDARDIZED_VALUE) or
(snssai.sd == ui.snssai.sd)) {
for (auto d : ui.dnn_upf_info_list) {
if (d.dnn.compare(dnn) == 0) {
node_id = it->second->node_id;
Logger::smf_app().info(
"Select the UPF for the corresponding DNN %s, NSSSAI (SST: "
"%d, "
"SD: %ld (0x%x)) ",
d.dnn.c_str(), snssai.sst, snssai.sd, snssai.sd);
return true;
}
}
}
}
......
......@@ -308,6 +308,28 @@ int session_create_sm_context_procedure::run(
create_pdr.set(far_id);
// TODO: list of Usage reporting Rule IDs
//-------------------
// IE create_urr ( Usage Reporting Rules)
//-------------------
if (smf_cfg.enable_ur) {
pfcp::urr_id_t urr_id = {};
sps->generate_urr_id(urr_id);
create_pdr.set(urr_id);
sps.get()->set_urr_id(urr_id.urr_id);
pfcp::create_urr create_urr = {};
pfcp::measurement_method_t measurement_method = {};
pfcp::measurement_period_t measurement_Period = {};
pfcp::reporting_triggers_t reporting_triggers = {};
// Hardcoded values for the moment
measurement_method.volum = 1; // Volume based usage report
measurement_Period.measurement_period = 10; // Every 10 Sec
reporting_triggers.perio = 1; // Periodic usage report
create_urr.set(urr_id);
create_urr.set(measurement_method);
create_urr.set(measurement_Period);
create_urr.set(reporting_triggers);
n4_triggered->pfcp_ies.set(create_urr);
}
// TODO: list of QoS Enforcement Rule IDs
//-------------------
......@@ -499,6 +521,9 @@ void session_create_sm_context_procedure::handle_itti_msg(
Logger::smf_app().debug(
"N1N2MessageTransfer will be sent to AMF with URL: %s", url.c_str());
// HTTP version
n11_triggered_pending->http_version = smf_cfg.http_version;
// Fill the json part
nlohmann::json json_data = {};
// N1SM
......@@ -517,9 +542,9 @@ void session_create_sm_context_procedure::handle_itti_msg(
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]
["contentId"] = N2_SM_CONTENT_ID; // NGAP part
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] =
n11_triggered_pending->res.get_snssai().sST;
n11_triggered_pending->res.get_snssai().sst;
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
n11_triggered_pending->res.get_snssai().sD;
std::to_string(n11_triggered_pending->res.get_snssai().sd);
json_data["n2InfoContainer"]["ranInfo"] = "SM";
// N1N2MsgTxfrFailureNotification
......@@ -821,6 +846,12 @@ int session_update_sm_context_procedure::run(
// pdi.set(local_fteid);
pdi.set(ue_ip_address);
if (smf_cfg.enable_ur) {
pfcp::urr_id_t urr_Id = {};
urr_Id.urr_id = sps.get()->get_urr_id();
create_pdr.set(urr_Id);
}
create_pdr.set(pdr_id);
create_pdr.set(precedence);
create_pdr.set(pdi);
......@@ -888,6 +919,12 @@ int session_update_sm_context_procedure::run(
pdi.set(source_interface);
pdi.set(ue_ip_address);
if (smf_cfg.enable_ur) {
pfcp::urr_id_t urr_Id = {};
urr_Id.urr_id = sps.get()->get_urr_id();
update_pdr.set(urr_Id);
}
update_pdr.set(flow.pdr_id_dl);
update_pdr.set(precedence);
update_pdr.set(pdi);
......
......@@ -203,7 +203,7 @@ void nf_profile::display() const {
Logger::smf_app().debug("\tSNSSAI:");
}
for (auto s : snssais) {
Logger::smf_app().debug("\t\t SST %d, SD %s", s.sST, s.sD.c_str());
Logger::smf_app().debug("\t\t SST %d, SD %ld (0x%x)", s.sst, s.sd, s.sd);
}
if (!fqdn.empty()) {
Logger::smf_app().debug("\tFQDN: %s", fqdn.c_str());
......@@ -235,8 +235,8 @@ void nf_profile::to_json(nlohmann::json& data) const {
data["sNssais"] = nlohmann::json::array();
for (auto s : snssais) {
nlohmann::json tmp = {};
tmp["sst"] = s.sST;
tmp["sd"] = s.sD;
tmp["sst"] = s.sst;
tmp["sd"] = std::to_string(s.sd);
data["sNssais"].push_back(tmp);
}
if (!fqdn.empty()) {
......@@ -282,8 +282,17 @@ void nf_profile::from_json(const nlohmann::json& data) {
if (data.find("sNssais") != data.end()) {
for (auto it : data["sNssais"]) {
snssai_t s = {};
s.sST = it["sst"].get<int>();
s.sD = it["sd"].get<std::string>();
s.sst = it["sst"].get<int>();
s.sd = 0xFFFFFF;
try {
s.sd = std::stoul(it["sd"].get<std::string>(), nullptr, 10);
} catch (const std::exception& e) {
Logger::smf_app().warn(
"Error when converting from string to int for snssai.SD, error: %s",
e.what());
}
// s.sD = it["sd"].get<std::string>();
snssais.push_back(s);
}
}
......@@ -384,7 +393,8 @@ void smf_profile::display() const {
for (auto s : smf_info.snssai_smf_info_list) {
Logger::smf_app().debug("\t\tParameters supported by the SMF:");
Logger::smf_app().debug(
"\t\t\tSNSSAI (SST %d, SD %s)", s.snssai.sST, s.snssai.sD.c_str());
"\t\t\tSNSSAI (SST %d, SD %ld (0x%x))", s.snssai.sst, s.snssai.sd,
s.snssai.sd);
for (auto d : s.dnn_smf_info_list) {
Logger::smf_app().debug("\t\t\tDNN %s", d.dnn.c_str());
}
......@@ -430,8 +440,8 @@ void smf_profile::to_json(nlohmann::json& data) const {
data["smfInfo"]["sNssaiSmfInfoList"] = nlohmann::json::array();
for (auto s : smf_info.snssai_smf_info_list) {
nlohmann::json tmp = {};
tmp["sNssai"]["sst"] = s.snssai.sST;
tmp["sNssai"]["sd"] = s.snssai.sD;
tmp["sNssai"]["sst"] = s.snssai.sst;
tmp["sNssai"]["sd"] = std::to_string(s.snssai.sd);
tmp["dnnSmfInfoList"] = nlohmann::json::array();
for (auto d : s.dnn_smf_info_list) {
nlohmann::json dnn_json = {};
......@@ -464,9 +474,19 @@ void smf_profile::from_json(const nlohmann::json& data) {
snssai_smf_info_item_t smf_info_item = {};
if (it.find("sNssai") != it.end()) {
if (it["sNssai"].find("sst") != it["sNssai"].end())
smf_info_item.snssai.sST = it["sNssai"]["sst"].get<int>();
if (it["sNssai"].find("sd") != it["sNssai"].end())
smf_info_item.snssai.sD = it["sNssai"]["sd"].get<std::string>();
smf_info_item.snssai.sst = it["sNssai"]["sst"].get<int>();
if (it["sNssai"].find("sd") != it["sNssai"].end()) {
smf_info_item.snssai.sd = 0xFFFFFF;
try {
smf_info_item.snssai.sd = std::stoul(
it["sNssai"]["sd"].get<std::string>(), nullptr, 10);
} catch (const std::exception& e) {
Logger::smf_app().warn(
"Error when converting from string to int for snssai.SD, "
"error: %s",
e.what());
}
}
}
if (it.find("dnnSmfInfoList") != it.end()) {
for (auto d : it["dnnSmfInfoList"]) {
......@@ -514,7 +534,8 @@ void upf_profile::display() const {
for (auto s : upf_info.snssai_upf_info_list) {
Logger::smf_app().debug("\t\tParameters supported by the UPF:");
Logger::smf_app().debug(
"\t\t\tSNSSAI (SST %d, SD %s)", s.snssai.sST, s.snssai.sD.c_str());
"\t\t\tSNSSAI (SST %d, SD %ld (0x%x))", s.snssai.sst, s.snssai.sd,
s.snssai.sd);
for (auto d : s.dnn_upf_info_list) {
Logger::smf_app().debug("\t\t\tDNN %s", d.dnn.c_str());
}
......@@ -550,8 +571,8 @@ void upf_profile::to_json(nlohmann::json& data) const {
data["upfInfo"]["sNssaiUpfInfoList"] = nlohmann::json::array();
for (auto s : upf_info.snssai_upf_info_list) {
nlohmann::json tmp = {};
tmp["sNssai"]["sst"] = s.snssai.sST;
tmp["sNssai"]["sd"] = s.snssai.sD;
tmp["sNssai"]["sst"] = s.snssai.sst;
tmp["sNssai"]["sd"] = std::to_string(s.snssai.sd);
tmp["dnnSmfInfoList"] = nlohmann::json::array();
for (auto d : s.dnn_upf_info_list) {
nlohmann::json dnn_json = {};
......@@ -598,9 +619,19 @@ void upf_profile::from_json(const nlohmann::json& data) {
snssai_upf_info_item_t upf_info_item = {};
if (it.find("sNssai") != it.end()) {
if (it["sNssai"].find("sst") != it["sNssai"].end())
upf_info_item.snssai.sST = it["sNssai"]["sst"].get<int>();
if (it["sNssai"].find("sd") != it["sNssai"].end())
upf_info_item.snssai.sD = it["sNssai"]["sd"].get<std::string>();
upf_info_item.snssai.sst = it["sNssai"]["sst"].get<int>();
if (it["sNssai"].find("sd") != it["sNssai"].end()) {
upf_info_item.snssai.sd = 0xFFFFFF;
try {
upf_info_item.snssai.sd = std::stoul(
it["sNssai"]["sd"].get<std::string>(), nullptr, 10);
} catch (const std::exception& e) {
Logger::smf_app().warn(
"Error when converting from string to int for snssai.SD, "
"error: %s",
e.what());
}
}
}
if (it.find("dnnUpfInfoList") != it.end()) {
for (auto d : it["dnnUpfInfoList"]) {
......
......@@ -43,6 +43,7 @@
#include "itti.hpp"
#include "logger.hpp"
#include "mime_parser.hpp"
#include "3gpp_conversions.hpp"
#include "smf.h"
#include "smf_app.hpp"
#include "smf_config.hpp"
......@@ -844,8 +845,8 @@ bool smf_sbi::get_sm_data(
std::string mnc = {};
conv::plmnToMccMnc(plmn, mcc, mnc);
query_str = "?single-nssai={\"sst\":" + std::to_string(snssai.sST) +
",\"sd\":\"" + snssai.sD + "\"}&dnn=" + dnn +
query_str = "?single-nssai={\"sst\":" + std::to_string(snssai.sst) +
",\"sd\":\"" + std::to_string(snssai.sd) + "\"}&dnn=" + dnn +
"&plmn-id={\"mcc\":\"" + mcc + "\",\"mnc\":\"" + mnc + "\"}";
std::string url =
std::string(inet_ntoa(*((struct in_addr*) &smf_cfg.udm_addr.ipv4_addr))) +
......@@ -906,13 +907,16 @@ bool smf_sbi::get_sm_data(
if (jsonData.find("singleNssai") == jsonData.end()) return false;
if (jsonData["singleNssai"].find("sst") != jsonData["singleNssai"].end()) {
uint8_t sst = jsonData["singleNssai"]["sst"].get<uint8_t>();
if (sst != snssai.sST) {
if (sst != snssai.sst) {
return false;
}
}
if (jsonData["singleNssai"].find("sd") != jsonData["singleNssai"].end()) {
std::string sd = jsonData["singleNssai"]["sd"];
if (sd.compare(snssai.sD) != 0) {
std::string sd_str = jsonData["singleNssai"]["sd"];
uint32_t sd = 0xFFFFFF;
xgpp_conv::sd_string_to_int(
jsonData["singleNssai"]["sd"].get<std::string>(), sd);
if (sd != snssai.sd) {
return false;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment