Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-SMF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-SMF
Commits
06729cf0
Commit
06729cf0
authored
Nov 28, 2022
by
Tien Thinh NGUYEN
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fix_develop_ue_rel16' into ue_triggered_pdu_session_release
parents
3d122038
89235dea
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
397 additions
and
145 deletions
+397
-145
src/api-server/api/NFStatusNotifyApi.cpp
src/api-server/api/NFStatusNotifyApi.cpp
+4
-0
src/common/3gpp_29.244.h
src/common/3gpp_29.244.h
+7
-0
src/common/smf.h
src/common/smf.h
+69
-17
src/common/utils/conversions.cpp
src/common/utils/conversions.cpp
+7
-3
src/common/utils/fqdn.cpp
src/common/utils/fqdn.cpp
+74
-2
src/common/utils/fqdn.hpp
src/common/utils/fqdn.hpp
+2
-0
src/smf_app/smf_app.cpp
src/smf_app/smf_app.cpp
+27
-9
src/smf_app/smf_context.cpp
src/smf_app/smf_context.cpp
+8
-2
src/smf_app/smf_pfcp_association.cpp
src/smf_app/smf_pfcp_association.cpp
+162
-77
src/smf_app/smf_pfcp_association.hpp
src/smf_app/smf_pfcp_association.hpp
+23
-2
src/smf_app/smf_profile.cpp
src/smf_app/smf_profile.cpp
+13
-32
src/smf_app/smf_sbi.cpp
src/smf_app/smf_sbi.cpp
+1
-1
No files found.
src/api-server/api/NFStatusNotifyApi.cpp
View file @
06729cf0
...
...
@@ -21,6 +21,7 @@
#include "NFStatusNotifyApi.h"
#include "Helpers.h"
#include "logger.hpp"
#include "smf_config.hpp"
extern
smf
::
smf_config
smf_cfg
;
...
...
@@ -56,6 +57,9 @@ void NFStatusNotifyApi::setupRoutes() {
void
NFStatusNotifyApi
::
notify_nf_status_handler
(
const
Pistache
::
Rest
::
Request
&
request
,
Pistache
::
Http
::
ResponseWriter
response
)
{
Logger
::
smf_api_server
().
info
(
"Received a NFStatusNotify message"
);
Logger
::
smf_api_server
().
debug
(
"Message body: %s
\n
"
,
request
.
body
().
c_str
());
// Getting the body param
NotificationData
notificationData
;
...
...
src/common/3gpp_29.244.h
View file @
06729cf0
...
...
@@ -1026,6 +1026,13 @@ struct node_id_s {
struct
in6_addr
ipv6_address
;
}
u1
;
std
::
string
fqdn
;
// should be in union but problem with virtual ~
node_id_s
()
{
node_id_type
=
node_id_type_value_e
::
NODE_ID_TYPE_UNKNOWN
;
u1
.
ipv4_address
.
s_addr
=
INADDR_ANY
;
u1
.
ipv6_address
=
in6addr_any
;
fqdn
=
{};
}
bool
operator
==
(
const
struct
node_id_s
&
i
)
const
{
if
(
i
.
node_id_type
!=
this
->
node_id_type
)
return
false
;
switch
(
i
.
node_id_type
)
{
...
...
src/common/smf.h
View file @
06729cf0
...
...
@@ -22,14 +22,15 @@
#ifndef FILE_SMF_SEEN
#define FILE_SMF_SEEN
#include "3gpp_29.274.h"
#include "3gpp_29.571.h"
#include "3gpp_24.501.h"
#include <nlohmann/json.hpp>
#include <boost/algorithm/string.hpp>
#include <map>
#include <
vector
>
#include <
nlohmann/json.hpp
>
#include <unordered_set>
#include <vector>
#include "3gpp_24.501.h"
#include "3gpp_29.274.h"
#include "3gpp_29.571.h"
typedef
uint64_t
supi64_t
;
#define SUPI_64_FMT "%" SCNu64
...
...
@@ -85,13 +86,21 @@ typedef struct s_nssai // section 28.4, TS23.003
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
;
sd
=
SD_NO_VALUE
;
if
(
m_sd
.
empty
())
return
;
uint8_t
base
=
10
;
try
{
sd
=
std
::
stoul
(
m_sd
,
nullptr
,
10
);
if
(
m_sd
.
size
()
>
2
)
{
if
(
boost
::
iequals
(
m_sd
.
substr
(
0
,
2
),
"0x"
))
{
base
=
16
;
}
}
sd
=
std
::
stoul
(
m_sd
,
nullptr
,
base
);
}
catch
(
const
std
::
exception
&
e
)
{
Logger
::
smf_app
().
warn
(
"Error when converting from string to int for
snssai.
SD, error: %s"
,
Logger
::
smf_app
().
error
(
"Error when converting from string to int for
S-NSSAI
SD, error: %s"
,
e
.
what
());
sd
=
SD_NO_VALUE
;
}
}
s_nssai
()
:
sst
(),
sd
()
{}
...
...
@@ -212,8 +221,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
...
...
@@ -346,7 +355,7 @@ typedef struct nf_service_s {
s
.
append
(
service_instance_id
);
s
.
append
(
", Service name: "
);
s
.
append
(
service_name
);
for
(
auto
v
:
versions
)
{
for
(
const
auto
&
v
:
versions
)
{
s
.
append
(
v
.
to_string
());
}
s
.
append
(
", Scheme: "
);
...
...
@@ -381,11 +390,38 @@ typedef struct dnn_upf_info_item_s {
return
std
::
hash
<
std
::
string
>
()(
dnn
);
}
}
dnn_upf_info_item_t
;
std
::
string
to_string
()
const
{
std
::
string
s
=
{};
s
.
append
(
"DNN = "
).
append
(
dnn
).
append
(
", "
);
if
(
dnai_list
.
size
()
>
0
)
{
s
.
append
(
"DNAI list: {"
);
for
(
const
auto
&
dnai
:
dnai_list
)
{
s
.
append
(
"DNAI = "
).
append
(
dnai
).
append
(
", "
);
}
s
.
append
(
"}, "
);
}
if
(
dnai_nw_instance_list
.
size
()
>
0
)
{
s
.
append
(
"DNAI NW Instance list: {"
);
for
(
const
auto
&
dnai_nw
:
dnai_nw_instance_list
)
{
s
.
append
(
"("
).
append
(
dnai_nw
.
first
).
append
(
", "
).
append
(
dnai_nw
.
second
).
append
(
"),"
);
}
s
.
append
(
"}, "
);
}
return
s
;
}
}
dnn_upf_info_item_t
;
typedef
struct
snssai_upf_info_item_s
{
snssai_t
snssai
;
std
::
unordered_set
<
dnn_upf_info_item_t
,
dnn_upf_info_item_t
>
mutable
snssai_t
snssai
;
mutable
std
::
unordered_set
<
dnn_upf_info_item_t
,
dnn_upf_info_item_t
>
dnn_upf_info_list
;
snssai_upf_info_item_s
&
operator
=
(
const
snssai_upf_info_item_s
&
s
)
{
...
...
@@ -395,13 +431,29 @@ typedef struct snssai_upf_info_item_s {
}
bool
operator
==
(
const
snssai_upf_info_item_s
&
s
)
const
{
return
snssai
==
s
.
snssai
;
return
(
snssai
==
s
.
snssai
)
and
(
dnn_upf_info_list
==
s
.
dnn_upf_info_list
)
;
}
size_t
operator
()(
const
snssai_upf_info_item_s
&
)
const
{
return
snssai
.
operator
()(
snssai
);
}
std
::
string
to_string
()
const
{
std
::
string
s
=
{};
s
.
append
(
"SNSSAI Info: "
+
snssai
.
toString
()
+
", "
);
if
(
dnn_upf_info_list
.
size
()
>
0
)
{
s
.
append
(
"DNN UPF Info list: {"
);
for
(
auto
dnn_upf
:
dnn_upf_info_list
)
{
s
.
append
(
dnn_upf
.
to_string
());
}
s
.
append
(
"}, "
);
}
return
s
;
}
}
snssai_upf_info_item_t
;
typedef
struct
interface_upf_info_item_s
{
...
...
src/common/utils/conversions.cpp
View file @
06729cf0
...
...
@@ -181,10 +181,14 @@ void conv::plmnToMccMnc(
//------------------------------------------------------------------------------
struct
in_addr
conv
::
fromString
(
const
std
::
string
addr4
)
{
unsigned
char
buf
[
sizeof
(
struct
in6_addr
)]
=
{};
int
s
=
inet_pton
(
AF_INET
,
addr4
.
c_str
(),
buf
);
struct
in_addr
*
ia
=
(
struct
in_addr
*
)
buf
;
return
*
ia
;
struct
in_addr
ipv4_addr
;
ipv4_addr
.
s_addr
=
INADDR_ANY
;
if
(
inet_pton
(
AF_INET
,
addr4
.
c_str
(),
buf
)
==
1
)
{
memcpy
(
&
ipv4_addr
,
buf
,
sizeof
(
struct
in_addr
));
}
return
ipv4_addr
;
}
//------------------------------------------------------------------------------
std
::
string
conv
::
toString
(
const
struct
in_addr
&
inaddr
)
{
std
::
string
s
=
{};
...
...
src/common/utils/fqdn.cpp
View file @
06729cf0
...
...
@@ -21,6 +21,7 @@
#include "fqdn.hpp"
#include "logger.hpp"
#include "string.hpp"
#include <boost/asio.hpp>
#include <iostream>
#include <chrono>
...
...
@@ -37,7 +38,7 @@ bool fqdn::resolve(
while
(
tries
<
MAX_NB_RESOLVE_TRIES
)
{
try
{
boost
::
asio
::
io_context
io_context
=
{};
Logger
::
smf_app
().
debug
(
"Resolving DNS Try #%u"
,
tries
);
Logger
::
smf_app
().
debug
(
"Resolving DNS Try #%u"
,
tries
+
1
);
boost
::
asio
::
ip
::
tcp
::
resolver
resolver
{
io_context
};
boost
::
asio
::
ip
::
tcp
::
resolver
::
results_type
endpoints
=
...
...
@@ -73,6 +74,77 @@ bool fqdn::resolve(
return
false
;
}
bool
fqdn
::
resolve
(
pfcp
::
node_id_t
&
node_id
)
{
Logger
::
smf_app
().
debug
(
"Resolving an FQDN/IP Addr for an UPF node"
);
// Resolve IP addr from FQDN
if
(
node_id
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_FQDN
)
{
// Don't need to do if IP addr already available
if
(
node_id
.
u1
.
ipv4_address
.
s_addr
!=
INADDR_ANY
)
return
true
;
// Resolve if FQDN available
if
(
!
node_id
.
fqdn
.
empty
())
{
Logger
::
smf_app
().
debug
(
"FQDN %s"
,
node_id
.
fqdn
.
c_str
());
std
::
string
ip_addr_str
=
{};
uint32_t
port
=
{
0
};
uint8_t
addr_type
=
{
0
};
struct
in_addr
ipv4_addr
=
{};
if
(
!
fqdn
::
resolve
(
node_id
.
fqdn
,
ip_addr_str
,
port
,
addr_type
))
{
Logger
::
smf_app
().
warn
(
"Resolve FQDN %s: cannot resolve the hostname!"
,
node_id
.
fqdn
.
c_str
());
return
false
;
}
switch
(
addr_type
)
{
case
0
:
{
node_id
.
u1
.
ipv4_address
.
s_addr
=
conv
::
fromString
(
ip_addr_str
).
s_addr
;
Logger
::
smf_app
().
debug
(
"Resolve FQDN %s, IP Addr %s"
,
node_id
.
fqdn
.
c_str
(),
ip_addr_str
.
c_str
());
}
break
;
case
1
:
{
// TODO
Logger
::
smf_app
().
warn
(
"Resolve FQDN: %s. IPv6 Addr, this mode has not been "
"supported yet!"
,
node_id
.
fqdn
.
c_str
());
return
false
;
}
break
;
default:
Logger
::
smf_app
().
warn
(
"Unknown Address type"
);
return
false
;
}
}
else
{
return
false
;
// No FQDN available
}
// Resolve hostname from an IP Addr
}
else
if
(
node_id
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
)
{
// Don't need to do reserve_resolve if FQDN is already available
if
(
!
node_id
.
fqdn
.
empty
())
{
return
true
;
}
else
{
std
::
string
hostname
=
{};
std
::
string
ip_str
=
conv
::
toString
(
node_id
.
u1
.
ipv4_address
);
if
(
!
fqdn
::
reverse_resolve
(
ip_str
,
hostname
))
{
Logger
::
smf_app
().
warn
(
"Could not resolve hostname for IP address %s"
,
ip_str
.
c_str
());
return
false
;
}
else
{
node_id
.
fqdn
=
hostname
;
Logger
::
smf_app
().
debug
(
"Resolve IP Addr %s, FQDN %s"
,
ip_str
.
c_str
(),
node_id
.
fqdn
.
c_str
());
}
return
true
;
}
}
else
{
// Don't support IPv6 for the moment
return
false
;
}
return
true
;
}
bool
fqdn
::
reverse_resolve
(
const
std
::
string
&
ip_addr
,
std
::
string
&
host_name
)
{
Logger
::
smf_app
().
debug
(
"Resolving an IP address (name %s)"
,
ip_addr
.
c_str
());
int
tries
=
0
;
...
...
@@ -107,4 +179,4 @@ bool fqdn::reverse_resolve(const std::string& ip_addr, std::string& host_name) {
}
}
return
false
;
}
\ No newline at end of file
}
src/common/utils/fqdn.hpp
View file @
06729cf0
...
...
@@ -28,6 +28,7 @@
#ifndef FILE_FQDN_HPP_SEEN
#define FILE_FQDN_HPP_SEEN
#include <string>
#include "3gpp_29.244.h"
class
fqdn
{
public:
/*
...
...
@@ -41,6 +42,7 @@ class fqdn {
const
std
::
string
&
host_name
,
std
::
string
&
address
,
uint32_t
&
port
,
uint8_t
&
addr_type
,
const
std
::
string
&
protocol
=
"http"
);
static
bool
resolve
(
pfcp
::
node_id_t
&
node_id
);
/**
* @brief Resolves an IP address to get the hostname
* @param ip_address to resolve
...
...
src/smf_app/smf_app.cpp
View file @
06729cf0
...
...
@@ -399,10 +399,13 @@ void smf_app::start_nf_registration_discovery() {
//------------------------------------------------------------------------------
void
smf_app
::
start_upf_association
(
const
pfcp
::
node_id_t
&
node_id
)
{
Logger
::
smf_app
().
debug
(
"Start a PFCP Association procedure with an UPF"
);
std
::
time_t
time_epoch
=
std
::
time
(
nullptr
);
uint64_t
tv_ntp
=
time_epoch
+
SECONDS_SINCE_FIRST_EPOCH
;
pfcp_associations
::
get_instance
().
add_peer_candidate_node
(
node_id
);
pfcp
::
node_id_t
node_id_tmp
=
node_id
;
fqdn
::
resolve
(
node_id_tmp
);
// Resolve FQDN/IP addr if necessary
pfcp_associations
::
get_instance
().
add_peer_candidate_node
(
node_id_tmp
);
std
::
shared_ptr
<
itti_n4_association_setup_request
>
n4_asc
=
std
::
shared_ptr
<
itti_n4_association_setup_request
>
(
new
itti_n4_association_setup_request
(
TASK_SMF_APP
,
TASK_SMF_N4
));
...
...
@@ -438,9 +441,12 @@ void smf_app::start_upf_association(const pfcp::node_id_t& node_id) {
//------------------------------------------------------------------------------
void
smf_app
::
start_upf_association
(
const
pfcp
::
node_id_t
&
node_id
,
const
upf_profile
&
profile
)
{
Logger
::
smf_app
().
debug
(
"Start a PFCP Association procedure with an UPF"
);
std
::
time_t
time_epoch
=
std
::
time
(
nullptr
);
uint64_t
tv_ntp
=
time_epoch
+
SECONDS_SINCE_FIRST_EPOCH
;
pfcp
::
node_id_t
node_id_tmp
=
node_id
;
fqdn
::
resolve
(
node_id_tmp
);
// Resolve FQDN/IP addr if necessary
pfcp_associations
::
get_instance
().
add_peer_candidate_node
(
node_id
,
profile
);
std
::
shared_ptr
<
itti_n4_association_setup_request
>
n4_asc
=
std
::
shared_ptr
<
itti_n4_association_setup_request
>
(
...
...
@@ -690,6 +696,11 @@ void smf_app::handle_itti_msg(
graph
->
start_asynch_dfs_procedure
(
true
,
empty_flow
);
graph
->
dfs_next_upf
(
dl_edges
,
ul_edges
,
current_upf
);
if
(
!
current_upf
)
{
Logger
::
smf_app
().
warn
(
"Could not select UPF in graph!"
);
return
;
}
up_node_id
=
current_upf
->
node_id
;
std
::
shared_ptr
<
itti_n4_session_failure_indication
>
...
...
@@ -1450,15 +1461,21 @@ bool smf_app::handle_nf_status_notification(
// Add a new UPF node
Logger
::
smf_app
().
debug
(
"Add a new UPF node, Ipv4 Addr %s"
,
inet_ntoa
(
ipv4_addrs
[
0
]));
// pfcp::node_id_t n = {};
if
(
n
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_UNKNOWN
)
n
.
node_id_type
=
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
;
n
.
u1
.
ipv4_address
.
s_addr
=
ipv4_addrs
[
0
].
s_addr
;
/*smf_cfg.upfs.push_back(n);
upf_profile* upf_node_profile =
dynamic_cast<upf_profile*>(profile.get());
start_upf_association(n, std::ref(*upf_node_profile));
*/
// Do reserve_resolve to find FQDN if not available
if
(
n
.
fqdn
.
empty
())
{
std
::
string
hostname
=
{};
std
::
string
ip_str
=
conv
::
toString
(
n
.
u1
.
ipv4_address
);
if
(
!
fqdn
::
reverse_resolve
(
ip_str
,
hostname
))
{
Logger
::
smf_app
().
debug
(
"Could not resolve hostname for IP address %s"
,
ip_str
.
c_str
());
}
else
{
n
.
fqdn
=
hostname
;
}
}
}
else
{
Logger
::
smf_app
().
debug
(
"UPF node already exist (%s)"
,
inet_ntoa
(
ipv4_addrs
[
0
]));
...
...
@@ -1473,7 +1490,7 @@ bool smf_app::handle_nf_status_notification(
// Trigger N4 association request with retry if needed
std
::
shared_ptr
<
itti_n4_association_retry
>
itti_msg
=
std
::
make_shared
<
itti_n4_association_retry
>
(
TASK_SMF_
N4
,
TASK_SMF_APP
);
TASK_SMF_
APP
,
TASK_SMF_APP
);
itti_msg
->
node_id
=
n
;
itti_msg
->
profile
=
std
::
ref
(
*
upf_node_profile
);
int
ret
=
itti_inst
->
send_msg
(
itti_msg
);
...
...
@@ -1483,7 +1500,8 @@ bool smf_app::handle_nf_status_notification(
itti_msg
->
get_msg_name
());
}
}
else
{
Logger
::
smf_app
().
debug
(
"No IP Addr/FQDN found"
);
Logger
::
smf_app
().
debug
(
"No IP Addr/FQDN found or UPF node already exist"
);
return
false
;
}
}
...
...
src/smf_app/smf_context.cpp
View file @
06729cf0
...
...
@@ -400,6 +400,9 @@ std::string smf_pdu_session::toString() const {
if
(
!
is_released
)
{
s
.
append
(
"
\t
SEID:
\t\t\t
"
).
append
(
std
::
to_string
(
seid
)).
append
(
"
\n
"
);
}
/*
// TODO as FTEID is not updated here, it is confusing to have null output
We need a complete QoS handling refactor
if (default_qfi.qfi) {
s.append("\tDefault ");
for (auto it : qos_flows) {
...
...
@@ -407,7 +410,9 @@ std::string smf_pdu_session::toString() const {
s.append(it.second.toString());
}
}
}
*/
if
(
policy_ptr
)
{
s
.
append
(
"
\t
Policy Decision:"
).
append
(
"
\n
"
);
...
...
@@ -3782,8 +3787,9 @@ bool smf_context::find_dnn_subscription(
Logger
::
smf_app
().
info
(
"Find a DNN Subscription with key: %ld (SST %d, SD %ld (0x%x)), map size "
"%d"
,
(
uint8_t
)
snssai
.
sst
,
snssai
.
sd
,
snssai
.
sd
,
dnn_subscriptions
.
size
());
"%ld"
,
key
,
(
uint8_t
)
snssai
.
sst
,
snssai
.
sd
,
snssai
.
sd
,
dnn_subscriptions
.
size
());
std
::
unique_lock
<
std
::
recursive_mutex
>
lock
(
m_context
);
if
(
dnn_subscriptions
.
count
(
key
)
>
0
)
{
...
...
src/smf_app/smf_pfcp_association.cpp
View file @
06729cf0
...
...
@@ -44,21 +44,50 @@ extern itti_mw* itti_inst;
extern
smf_n4
*
smf_n4_inst
;
extern
smf_config
smf_cfg
;
//---------------------------------------------------------------------------------------------
edge
edge
::
from_upf_info
(
const
upf_info_t
&
upf_info
)
{
edge
e
;
snssai_upf_info_item_s
snssai_item
;
edge
e
=
{}
;
snssai_upf_info_item_s
snssai_item
=
{}
;
for
(
const
auto
&
snssai
:
upf_info
.
snssai_upf_info_list
)
{
Logger
::
smf_app
().
debug
(
"Edge from UPF info, UPF info %s"
,
upf_info
.
to_string
().
c_str
());
for
(
auto
&
snssai
:
upf_info
.
snssai_upf_info_list
)
{
snssai_item
.
snssai
=
snssai
.
snssai
;
snssai_item
.
dnn_upf_info_list
=
snssai
.
dnn_upf_info_list
;
e
.
snssai_dnns
.
insert
(
snssai
);
bool
found
=
false
;
for
(
auto
&
item
:
e
.
snssai_dnns
)
{
if
(
item
.
snssai
==
snssai
.
snssai
)
{
// Update item if exist
found
=
true
;
snssai_item
.
dnn_upf_info_list
.
insert
(
item
.
dnn_upf_info_list
.
begin
(),
item
.
dnn_upf_info_list
.
end
());
item
.
dnn_upf_info_list
=
snssai_item
.
dnn_upf_info_list
;
Logger
::
smf_app
().
debug
(
"Updated item info: %s"
,
snssai_item
.
to_string
().
c_str
());
break
;
}
}
// Insert a new item otherwise
if
(
!
found
)
e
.
snssai_dnns
.
insert
(
snssai_item
);
}
if
(
!
e
.
snssai_dnns
.
empty
())
{
Logger
::
smf_app
().
debug
(
"Edge from UPF info"
);
for
(
const
auto
s
:
e
.
snssai_dnns
)
{
Logger
::
smf_app
().
debug
(
"info: %s"
,
s
.
to_string
().
c_str
());
}
}
else
{
Logger
::
smf_app
().
debug
(
"Edge from UPF info, empty"
);
}
return
e
;
}
//---------------------------------------------------------------------------------------------
edge
edge
::
from_upf_info
(
const
upf_info_t
&
upf_info
,
const
interface_upf_info_item_t
&
interface
)
{
edge
e
;
// TODO: Bring updates from the previous funtion to this one
edge
e
=
{};
e
.
type
=
pfcp_association
::
iface_type_from_string
(
interface
.
interface_type
);
e
.
nw_instance
=
interface
.
network_instance
;
...
...
@@ -93,46 +122,63 @@ edge edge::from_upf_info(
return
e
;
}
//---------------------------------------------------------------------------------------------
bool
edge
::
serves_network
(
const
std
::
string
&
dnn
,
const
snssai_t
&
snssai
,
const
std
::
unordered_set
<
std
::
string
>&
dnais
,
std
::
string
&
matched_dnai
)
const
{
Logger
::
smf_app
().
debug
(
"Serves Network, DNN %s, S-NSSAI %s"
,
dnn
.
c_str
(),
snssai
.
toString
().
c_str
());
// just create a snssai_upf_info_item for fast lookup
snssai_upf_info_item_s
snssai_item
;
snssai_item
.
snssai
=
snssai
;
auto
snssai_it
=
snssai_dnns
.
find
(
snssai_item
);
if
(
snssai_it
!=
snssai_dnns
.
end
())
{
// create temp item for fast lookup
dnn_upf_info_item_s
dnn_item
;
dnn_item
.
dnn
=
dnn
;
auto
dnn_it
=
snssai_it
->
dnn_upf_info_list
.
find
(
dnn_item
);
if
(
dnn_it
!=
snssai_it
->
dnn_upf_info_list
.
end
())
{
if
(
!
dnais
.
empty
())
{
// should be only 1 DNAI
for
(
const
auto
&
dnai
:
dnn_it
->
dnai_list
)
{
// O(1)
auto
found_dnai
=
dnais
.
find
(
dnai
);
if
(
found_dnai
!=
dnais
.
end
())
{
matched_dnai
=
dnai
;
return
true
;
snssai_upf_info_item_s
snssai_item
=
{};
snssai_item
.
snssai
=
snssai
;
// For debugging purpose
if
(
!
snssai_dnns
.
empty
())
{
Logger
::
smf_app
().
debug
(
"S-NSSAI UPF info list"
);
for
(
const
auto
&
s
:
snssai_dnns
)
{
Logger
::
smf_app
().
debug
(
"S-NSSAI UPF info item %s"
,
s
.
to_string
().
c_str
());
}
}
for
(
const
auto
&
snssai_it
:
snssai_dnns
)
{
if
(
snssai_it
.
snssai
==
snssai_item
.
snssai
)
{
// create temp item for fast lookup
dnn_upf_info_item_s
dnn_item
=
{};
dnn_item
.
dnn
=
dnn
;
auto
dnn_it
=
snssai_it
.
dnn_upf_info_list
.
find
(
dnn_item
);
if
(
dnn_it
!=
snssai_it
.
dnn_upf_info_list
.
end
())
{
if
(
!
dnais
.
empty
())
{
// should be only 1 DNAI
for
(
const
auto
&
dnai
:
dnn_it
->
dnai_list
)
{
// O(1)
auto
found_dnai
=
dnais
.
find
(
dnai
);
if
(
found_dnai
!=
dnais
.
end
())
{
matched_dnai
=
dnai
;
return
true
;
}
}
}
else
{
return
true
;
}
}
else
{
return
true
;
}
}
}
Logger
::
smf_app
().
debug
(
"Could not serve network, return false"
);
return
false
;
}
//---------------------------------------------------------------------------------------------
bool
edge
::
serves_network
(
const
std
::
string
&
dnn
,
const
snssai_t
&
snssai
)
const
{
std
::
unordered_set
<
string
>
set
;
std
::
string
s
;
std
::
string
s
=
{}
;
return
serves_network
(
dnn
,
snssai
,
set
,
s
);
}
//---------------------------------------------------------------------------------------------
std
::
shared_ptr
<
smf_qos_flow
>
edge
::
get_qos_flow
(
const
pfcp
::
pdr_id_t
&
pdr_id
)
{
// it may happen that 2 qos flows have the same PDR ID e.g. in an
// UL CL scenario, but then they will also have the same FTEID
...
...
@@ -144,6 +190,7 @@ std::shared_ptr<smf_qos_flow> edge::get_qos_flow(const pfcp::pdr_id_t& pdr_id) {
return
{};
}
//---------------------------------------------------------------------------------------------
std
::
shared_ptr
<
smf_qos_flow
>
edge
::
get_qos_flow
(
const
pfcp
::
qfi_t
&
qfi
)
{
for
(
auto
&
flow_it
:
qos_flows
)
{
if
(
flow_it
->
qfi
==
qfi
)
{
...
...
@@ -153,6 +200,7 @@ std::shared_ptr<smf_qos_flow> edge::get_qos_flow(const pfcp::qfi_t& qfi) {
return
{};
}
//---------------------------------------------------------------------------------------------
std
::
shared_ptr
<
smf_qos_flow
>
edge
::
get_qos_flow
(
const
pfcp
::
far_id_t
&
far_id
)
{
for
(
auto
&
flow_it
:
qos_flows
)
{
if
(
flow_it
->
far_id_ul
.
second
==
far_id
||
...
...
@@ -214,7 +262,7 @@ void smf_qos_flow::deallocate_ressources() {
//------------------------------------------------------------------------------
iface_type
pfcp_association
::
iface_type_from_string
(
const
std
::
string
&
input
)
{
iface_type
type_tmp
;
iface_type
type_tmp
=
{}
;
if
(
input
==
"N3"
)
{
type_tmp
=
iface_type
::
N3
;
}
else
if
(
input
==
"N6"
)
{
...
...
@@ -229,7 +277,7 @@ iface_type pfcp_association::iface_type_from_string(const std::string& input) {
}
//------------------------------------------------------------------------------
std
::
string
pfcp_association
::
string_from_iface_type
(
const
iface_type
&
type
)
{
std
::
string
output
;
std
::
string
output
=
{}
;
switch
(
type
)
{
case
iface_type
:
:
N3
:
return
"N3"
;
...
...
@@ -282,12 +330,13 @@ void pfcp_association::restore_n4_sessions() {
}
}
//---------------------------------------------------------------------------------------------
bool
pfcp_association
::
find_interface_edge
(
const
iface_type
&
type_match
,
std
::
vector
<
edge
>&
edges
)
{
if
(
!
is_upf_profile_set
())
{
return
false
;
}
upf_info_t
upf_info
;
upf_info_t
upf_info
=
{}
;
upf_node_profile
.
get_upf_info
(
upf_info
);
for
(
const
auto
&
iface
:
upf_info
.
interface_upf_info_list
)
{
...
...
@@ -310,10 +359,12 @@ bool pfcp_association::find_interface_edge(
return
!
edges
.
empty
();
}
//---------------------------------------------------------------------------------------------
bool
pfcp_association
::
find_n3_edge
(
std
::
vector
<
edge
>&
edges
)
{
return
find_interface_edge
(
iface_type
::
N3
,
edges
);
}
//---------------------------------------------------------------------------------------------
bool
pfcp_association
::
find_n6_edge
(
std
::
vector
<
edge
>&
edges
)
{
bool
success
=
find_interface_edge
(
iface_type
::
N6
,
edges
);
if
(
success
)
{
...
...
@@ -375,6 +426,16 @@ std::string pfcp_association::get_printable_name() {
}
}
//------------------------------------------------------------------------------
void
pfcp_association
::
display
()
{
Logger
::
smf_app
().
debug
(
"
\t
UPF Node Id: %s"
,
node_id
.
toString
().
c_str
());
if
(
upf_profile_is_set
)
{
Logger
::
smf_app
().
debug
(
"
\t
UPF Node profile:"
);
upf_node_profile
.
display
();
}
}
/******************************************************************************/
/***************************** PFCP ASSOCIATIONS ******************************/
/******************************************************************************/
...
...
@@ -383,7 +444,7 @@ std::shared_ptr<pfcp_association> pfcp_associations::check_association_on_add(
pfcp
::
node_id_t
&
node_id
,
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
bool
&
restore_n4_sessions
,
const
bool
use_function_features
,
pfcp
::
up_function_features_s
&
function_features
)
{
std
::
shared_ptr
<
pfcp_association
>
sa
;
std
::
shared_ptr
<
pfcp_association
>
sa
=
{}
;
if
(
get_association
(
node_id
,
sa
))
{
itti_inst
->
timer_remove
(
sa
->
timer_heartbeat
);
if
(
sa
->
recovery_time_stamp
==
recovery_time_stamp
)
{
...
...
@@ -405,6 +466,7 @@ std::shared_ptr<pfcp_association> pfcp_associations::check_association_on_add(
return
{};
// empty ptr
}
//---------------------------------------------------------------------------------------------
bool
pfcp_associations
::
resolve_upf_hostname
(
pfcp
::
node_id_t
&
node_id
)
{
// TODO why is this even here? We can see in the logs that UPF IP is requested
// before, at least for NRF scenario
...
...
@@ -412,9 +474,9 @@ bool pfcp_associations::resolve_upf_hostname(pfcp::node_id_t& node_id) {
if
(
node_id
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_FQDN
)
{
Logger
::
smf_app
().
info
(
"Node ID Type FQDN: %s"
,
node_id
.
fqdn
.
c_str
());
std
::
string
ip_addr
;
uint32_t
port
;
uint8_t
addr_type
;
std
::
string
ip_addr
=
{}
;
uint32_t
port
=
{
0
}
;
uint8_t
addr_type
=
{
0
}
;
if
(
!
fqdn
::
resolve
(
node_id
.
fqdn
,
ip_addr
,
port
,
addr_type
))
{
Logger
::
smf_app
().
warn
(
...
...
@@ -441,6 +503,7 @@ bool pfcp_associations::resolve_upf_hostname(pfcp::node_id_t& node_id) {
return
true
;
// no FQDN so we just continue
}
//---------------------------------------------------------------------------------------------
void
pfcp_associations
::
associate_with_upf_profile
(
std
::
shared_ptr
<
pfcp_association
>&
sa
,
const
pfcp
::
node_id_t
&
node_id
)
{
// TODO wouldn't it be better to use a shared lock? because here we have only
...
...
@@ -460,7 +523,7 @@ void pfcp_associations::associate_with_upf_profile(
bool
pfcp_associations
::
add_association
(
pfcp
::
node_id_t
&
node_id
,
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
bool
&
restore_n4_sessions
)
{
pfcp
::
up_function_features_s
tmp
;
pfcp
::
up_function_features_s
tmp
=
{}
;
std
::
shared_ptr
<
pfcp_association
>
sa
=
check_association_on_add
(
node_id
,
recovery_time_stamp
,
restore_n4_sessions
,
false
,
tmp
);
if
(
sa
)
return
true
;
...
...
@@ -515,6 +578,7 @@ bool pfcp_associations::add_association(
}
return
true
;
}
//------------------------------------------------------------------------------
bool
pfcp_associations
::
add_association
(
pfcp
::
node_id_t
&
node_id
,
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
,
...
...
@@ -566,40 +630,42 @@ bool pfcp_associations::update_association(
//------------------------------------------------------------------------------
bool
pfcp_associations
::
get_association
(
const
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
{
std
::
size_t
hash_node_id
=
std
::
hash
<
pfcp
::
node_id_t
>
{}(
node_id
);
auto
association
=
associations_graph
.
get_association
(
hash_node_id
);
if
(
!
association
)
{
// We didn't find association, may be because hash map is made with
// node_id_type FQDN
if
(
node_id
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
)
{
std
::
string
hostname
;
std
::
string
ip_str
=
conv
::
toString
(
node_id
.
u1
.
ipv4_address
);
if
(
!
fqdn
::
reverse_resolve
(
ip_str
,
hostname
))
{
Logger
::
smf_app
().
warn
(
"Could not resolve hostname for IP address %s"
,
ip_str
.
c_str
());
return
false
;
}
pfcp
::
node_id_t
node_id_tmp
=
{};
node_id_tmp
.
node_id_type
=
pfcp
::
NODE_ID_TYPE_FQDN
;
node_id_tmp
.
fqdn
=
hostname
;
Logger
::
smf_app
().
debug
(
"Hash lookup for association retry: Associated Hostname -> %s"
,
hostname
.
c_str
());
if
(
get_association
(
node_id_tmp
,
sa
))
return
true
;
const
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
{
std
::
shared_ptr
<
pfcp_association
>
association
=
{};
std
::
size_t
hash_node_id
=
{};
pfcp
::
node_id_t
node_id_tmp
=
node_id
;
// Resolve FQDN/IP Addr if necessary
fqdn
::
resolve
(
node_id_tmp
);
// We suppose that by default hash map is made with node_id_type FQDN
if
(
node_id_tmp
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_FQDN
)
{
hash_node_id
=
std
::
hash
<
pfcp
::
node_id_t
>
{}(
node_id_tmp
);
association
=
associations_graph
.
get_association
(
hash_node_id
);
if
(
association
)
{
sa
=
association
;
return
true
;
}
// We didn't found association, may be because hash map is made with
// node_id_type IP ADDR
// ToDo (Might stuck in recursive loop here)
return
false
;
}
else
{
node_id_tmp
.
node_id_type
=
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
;
}
else
if
(
node_id_tmp
.
node_id_type
==
pfcp
::
NODE_ID_TYPE_IPV4_ADDRESS
)
{
hash_node_id
=
std
::
hash
<
pfcp
::
node_id_t
>
{}(
node_id_tmp
);
association
=
associations_graph
.
get_association
(
hash_node_id
);
if
(
association
)
{
sa
=
association
;
return
true
;
}
node_id_tmp
.
node_id_type
=
pfcp
::
NODE_ID_TYPE_FQDN
;
}
// We didn't found association, may be because hash map is made with different
// node type
hash_node_id
=
std
::
hash
<
pfcp
::
node_id_t
>
{}(
node_id_tmp
);
association
=
associations_graph
.
get_association
(
hash_node_id
);
if
(
association
)
{
sa
=
association
;
return
true
;
}
return
false
;
}
//------------------------------------------------------------------------------
...
...
@@ -781,6 +847,8 @@ bool pfcp_associations::add_peer_candidate_node(
std
::
make_shared
<
pfcp_association
>
(
node_id
);
s
->
set_upf_node_profile
(
profile
);
pending_associations
.
push_back
(
s
);
Logger
::
smf_app
().
info
(
"Added a pending association candidate"
);
s
->
display
();
return
true
;
}
...
...
@@ -811,10 +879,10 @@ void upf_graph::insert_into_graph(const std::shared_ptr<pfcp_association>& sa) {
"just add the node"
);
Logger
::
smf_app
().
info
(
"Assume that the UPF has a N3 and a N6 interface."
);
edge
n3_edge
;
edge
n3_edge
=
{}
;
n3_edge
.
type
=
iface_type
::
N3
;
n3_edge
.
uplink
=
false
;
edge
n6_edge
;
edge
n6_edge
=
{}
;
n6_edge
.
type
=
iface_type
::
N6
;
n6_edge
.
uplink
=
true
;
...
...
@@ -951,13 +1019,16 @@ bool upf_graph::remove_association(
return
false
;
}
//---------------------------------------------------------------------------------------------
void
upf_graph
::
add_upf_graph_edge
(
const
std
::
shared_ptr
<
pfcp_association
>&
source
,
edge
&
edge_info_src_dst
)
{
add_upf_graph_node
(
source
);
std
::
unique_lock
lock_graph
(
graph_mutex
);
auto
it_src
=
adjacency_list
.
find
(
source
);
if
(
it_src
==
adjacency_list
.
end
())
{
return
;
}
bool
exists
=
false
;
for
(
const
auto
&
edge
:
it_src
->
second
)
{
if
(
edge
==
edge_info_src_dst
)
{
...
...
@@ -1173,6 +1244,7 @@ void upf_graph::start_asynch_dfs_procedure(
}
}
//---------------------------------------------------------------------------------------------
edge
upf_graph
::
get_access_edge
()
const
{
std
::
shared_lock
graph_lock
(
graph_mutex
);
edge
info
;
...
...
@@ -1188,6 +1260,7 @@ edge upf_graph::get_access_edge() const {
return
info
;
}
//---------------------------------------------------------------------------------------------
void
upf_graph
::
update_edge_info
(
const
std
::
shared_ptr
<
pfcp_association
>&
upf
,
const
edge
&
info
)
{
std
::
unique_lock
graph_lock
(
graph_mutex
);
...
...
@@ -1205,26 +1278,31 @@ void upf_graph::update_edge_info(
}
}
//---------------------------------------------------------------------------------------------
std
::
shared_ptr
<
upf_graph
>
upf_graph
::
select_upf_node
(
const
snssai_t
&
snssai
,
const
std
::
string
&
dnn
)
{
Logger
::
smf_app
().
info
(
"Select UPF Node"
);
std
::
shared_ptr
<
upf_graph
>
upf_graph_ptr
=
std
::
make_shared
<
upf_graph
>
();
std
::
shared_lock
graph_lock
(
graph_mutex
);
std
::
shared_ptr
<
pfcp_association
>
not_found
;
std
::
shared_ptr
<
pfcp_association
>
not_found
=
{}
;
if
(
adjacency_list
.
empty
())
{
Logger
::
smf_app
().
warn
(
"No UPF available"
);
}
// First, only consider UPFs with profile ID set
for
(
const
auto
&
it
:
adjacency_list
)
{
std
::
shared_ptr
<
pfcp_association
>
current_upf
=
it
.
first
;
Logger
::
smf_app
().
debug
(
"Current UPF info"
);
current_upf
->
display
();
if
(
current_upf
->
is_upf_profile_set
())
{
upf_info_t
upf_info
;
upf_info_t
upf_info
=
{}
;
std
::
vector
<
snssai_t
>
snssais
=
{};
current_upf
->
get_upf_node_profile
().
get_upf_info
(
upf_info
);
bool
has_access
=
false
;
bool
has_exit
=
false
;
edge
access_edge
;
edge
exit_edge
;
bool
has_access
=
false
;
bool
has_exit
=
false
;
edge
access_edge
=
{}
;
edge
exit_edge
=
{}
;
for
(
const
auto
&
edge
:
it
.
second
)
{
Logger
::
smf_app
().
debug
(
"Verify Slice/DNN support"
);
// verify that UPF belongs to the same slice and supports this dnn
if
(
edge
.
serves_network
(
dnn
,
snssai
))
{
if
(
edge
.
type
==
iface_type
::
N3
)
{
...
...
@@ -1268,11 +1346,12 @@ std::shared_ptr<upf_graph> upf_graph::select_upf_node(
return
upf_graph_ptr
;
}
//---------------------------------------------------------------------------------------------
std
::
shared_ptr
<
upf_graph
>
upf_graph
::
select_upf_node
(
const
int
node_selection_criteria
)
{
std
::
shared_lock
graph_lock
(
graph_mutex
);
std
::
shared_ptr
<
pfcp_association
>
association
;
std
::
shared_ptr
<
upf_graph
>
upf_graph_ptr
=
std
::
make_shared
<
upf_graph
>
();
std
::
shared_ptr
<
pfcp_association
>
association
=
{}
;
std
::
shared_ptr
<
upf_graph
>
upf_graph_ptr
=
std
::
make_shared
<
upf_graph
>
();
Logger
::
smf_app
().
error
(
"Called non-implemented UPF selection function"
);
...
...
@@ -1302,6 +1381,7 @@ std::shared_ptr<upf_graph> upf_graph::select_upf_node(
}
return
upf_graph_ptr
;
}
return
upf_graph_ptr
;
}
//------------------------------------------------------------------------------
...
...
@@ -1327,7 +1407,7 @@ std::shared_ptr<upf_graph> upf_graph::select_upf_nodes(
// std::shared_ptr<upf_graph> correct_sub_graph_ptr;
std
::
unordered_set
<
std
::
string
>
dnais_from_all_rules
;
std
::
shared_ptr
<
upf_graph
>
sub_graph_ptr
;
std
::
shared_ptr
<
upf_graph
>
sub_graph_ptr
=
{}
;
// run DFS for each PCC rule, get different graphs and merge them
...
...
@@ -1443,6 +1523,7 @@ std::shared_ptr<upf_graph> upf_graph::select_upf_nodes(
return
sub_graph_ptr
;
}
//---------------------------------------------------------------------------------------------
bool
upf_graph
::
verify
()
{
int
access_count
=
0
;
bool
has_exit
=
false
;
...
...
@@ -1511,8 +1592,9 @@ bool upf_graph::verify() {
return
false
;
}
//---------------------------------------------------------------------------------------------
std
::
string
upf_graph
::
get_dnai_list
(
const
std
::
unordered_set
<
string
>&
dnais
)
{
std
::
string
out
;
std
::
string
out
=
{}
;
for
(
const
auto
&
dnai
:
dnais
)
{
out
.
append
(
dnai
).
append
(
", "
);
...
...
@@ -1523,6 +1605,7 @@ std::string upf_graph::get_dnai_list(const std::unordered_set<string>& dnais) {
return
out
;
}
//---------------------------------------------------------------------------------------------
void
upf_graph
::
set_dfs_selection_criteria
(
const
std
::
unordered_set
<
std
::
string
>&
all_dnais
,
const
std
::
string
&
flow_description
,
uint32_t
precedence
,
...
...
@@ -1534,6 +1617,7 @@ void upf_graph::set_dfs_selection_criteria(
dfs_dnn
=
dnn
;
}
//---------------------------------------------------------------------------------------------
void
upf_graph
::
create_subgraph_dfs
(
std
::
shared_ptr
<
upf_graph
>&
sub_graph
,
const
std
::
shared_ptr
<
pfcp_association
>&
start_node
,
...
...
@@ -1622,6 +1706,7 @@ void upf_graph::create_subgraph_dfs(
}
}
//---------------------------------------------------------------------------------------------
bool
upf_graph
::
full
()
const
{
std
::
shared_lock
graph_lock
(
graph_mutex
);
...
...
src/smf_app/smf_pfcp_association.hpp
View file @
06729cf0
...
...
@@ -92,6 +92,7 @@ class pfcp_association {
timer_association
=
ITTI_INVALID_TIMER_ID
;
timer_graceful_release
=
ITTI_INVALID_TIMER_ID
;
}
pfcp_association
(
const
pfcp
::
node_id_t
&
node_id
,
pfcp
::
recovery_time_stamp_t
&
recovery_time_stamp
)
...
...
@@ -129,6 +130,7 @@ class pfcp_association {
timer_association
=
ITTI_INVALID_TIMER_ID
;
timer_graceful_release
=
ITTI_INVALID_TIMER_ID
;
}
pfcp_association
(
pfcp_association
const
&
p
)
:
node_id
(
p
.
node_id
),
hash_node_id
(
p
.
hash_node_id
),
...
...
@@ -190,8 +192,21 @@ class pfcp_association {
bool
find_upf_edge
(
const
std
::
shared_ptr
<
pfcp_association
>&
other_upf
,
edge
&
out_edge
);
/**
* @brief Get the readble name of the UPF associated with this association
* @param void
* @return string representing the name of the UPF associated with this
* association
*/
std
::
string
get_printable_name
();
/*
* Print related-information for this association
* @param void
* @return void:
*/
void
display
();
private:
bool
find_interface_edge
(
const
iface_type
&
type_match
,
std
::
vector
<
edge
>&
edges
);
...
...
@@ -313,6 +328,13 @@ struct edge {
if
(
association
&&
nw_instance
.
empty
())
{
output
.
append
(
"("
).
append
(
association
->
get_printable_name
()).
append
(
")"
);
}
if
(
!
snssai_dnns
.
empty
())
{
output
.
append
(
"S-NSSAI UPF info list: { "
);
for
(
const
auto
&
s
:
snssai_dnns
)
{
output
.
append
(
" "
).
append
(
s
.
to_string
()).
append
(
", "
);
}
output
.
append
(
"}"
);
}
return
output
;
}
};
...
...
@@ -615,8 +637,7 @@ class pfcp_associations {
pfcp
::
node_id_t
&
node_id
,
pfcp
::
up_function_features_s
&
function_features
);
bool
get_association
(
const
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
;
const
pfcp
::
node_id_t
&
node_id
,
std
::
shared_ptr
<
pfcp_association
>&
sa
);
bool
get_association
(
const
pfcp
::
fseid_t
&
cp_fseid
,
std
::
shared_ptr
<
pfcp_association
>&
sa
)
const
;
...
...
src/smf_app/smf_profile.cpp
View file @
06729cf0
...
...
@@ -27,11 +27,12 @@
\email: Tien-Thinh.Nguyen@eurecom.fr
*/
#include "smf_profile.hpp"
#include "3gpp_conversions.hpp"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include "logger.hpp"
#include "smf_profile.hpp"
#include "string.hpp"
using
namespace
std
;
...
...
@@ -282,17 +283,11 @@ 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
=
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
=
SD_NO_VALUE
;
if
(
it
.
find
(
"sst"
)
!=
it
.
end
())
s
.
sst
=
it
[
"sst"
].
get
<
int
>
();
if
(
it
.
find
(
"sd"
)
!=
it
.
end
())
{
xgpp_conv
::
sd_string_to_int
(
it
[
"sd"
].
get
<
std
::
string
>
(),
s
.
sd
);
}
// s.sD = it["sd"].get<std::string>();
snssais
.
push_back
(
s
);
}
}
...
...
@@ -472,20 +467,13 @@ void smf_profile::from_json(const nlohmann::json& data) {
for
(
auto
it
:
snssai_smf_info_list
)
{
snssai_smf_info_item_t
smf_info_item
=
{};
smf_info_item
.
snssai
.
sd
=
SD_NO_VALUE
;
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
=
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
());
}
xgpp_conv
::
sd_string_to_int
(
it
[
"sNssai"
][
"sd"
].
get
<
std
::
string
>
(),
smf_info_item
.
snssai
.
sd
);
}
}
if
(
it
.
find
(
"dnnSmfInfoList"
)
!=
it
.
end
())
{
...
...
@@ -629,20 +617,13 @@ void upf_profile::from_json(const nlohmann::json& data) {
for
(
auto
it
:
snssai_upf_info_list
)
{
snssai_upf_info_item_t
upf_info_item
=
{};
upf_info_item
.
snssai
.
sd
=
SD_NO_VALUE
;
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
=
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
());
}
xgpp_conv
::
sd_string_to_int
(
it
[
"sNssai"
][
"sd"
].
get
<
std
::
string
>
(),
upf_info_item
.
snssai
.
sd
);
}
}
if
(
it
.
find
(
"dnnUpfInfoList"
)
!=
it
.
end
())
{
...
...
src/smf_app/smf_sbi.cpp
View file @
06729cf0
...
...
@@ -927,7 +927,7 @@ bool smf_sbi::get_sm_data(
}
if
(
jsonData
[
"singleNssai"
].
find
(
"sd"
)
!=
jsonData
[
"singleNssai"
].
end
())
{
std
::
string
sd_str
=
jsonData
[
"singleNssai"
][
"sd"
];
uint32_t
sd
=
0xFFFFFF
;
uint32_t
sd
=
SD_NO_VALUE
;
xgpp_conv
::
sd_string_to_int
(
jsonData
[
"singleNssai"
][
"sd"
].
get
<
std
::
string
>
(),
sd
);
if
(
sd
!=
snssai
.
sd
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment