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
71b5eb69
Commit
71b5eb69
authored
Sep 24, 2021
by
Tien-Thinh Nguyen
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'static_ue_ip_addr' into 'develop'
Static ue ip addr See merge request oai/cn5g/oai-cn5g-smf!96
parents
52700d25
885f0f3e
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
353 additions
and
106 deletions
+353
-106
src/common/3gpp_24.501.h
src/common/3gpp_24.501.h
+13
-0
src/common/3gpp_29.274.h
src/common/3gpp_29.274.h
+0
-9
src/common/3gpp_29.503.h
src/common/3gpp_29.503.h
+142
-1
src/smf_app/smf_app.cpp
src/smf_app/smf_app.cpp
+6
-6
src/smf_app/smf_context.cpp
src/smf_app/smf_context.cpp
+54
-42
src/smf_app/smf_sbi.cpp
src/smf_app/smf_sbi.cpp
+136
-47
src/smf_app/smf_sbi.hpp
src/smf_app/smf_sbi.hpp
+2
-1
No files found.
src/common/3gpp_24.501.h
View file @
71b5eb69
...
...
@@ -318,6 +318,18 @@ typedef struct pdu_session_type_s {
pdu_session_type_s
(
const
uint8_t
&
p
)
:
pdu_session_type
(
p
)
{}
pdu_session_type_s
(
const
struct
pdu_session_type_s
&
p
)
:
pdu_session_type
(
p
.
pdu_session_type
)
{}
pdu_session_type_s
(
const
std
::
string
&
s
)
{
if
(
s
.
compare
(
"IPV4"
)
==
0
)
{
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4
;
}
else
if
(
s
.
compare
(
"IPV6"
)
==
0
)
{
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV6
;
}
else
if
(
s
.
compare
(
"IPV4V6"
)
==
0
)
{
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4V6
;
}
else
{
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4
;
// Default value
}
}
bool
operator
==
(
const
struct
pdu_session_type_s
&
p
)
const
{
return
(
p
.
pdu_session_type
==
pdu_session_type
);
}
...
...
@@ -329,6 +341,7 @@ typedef struct pdu_session_type_s {
const
std
::
string
&
toString
()
const
{
return
pdu_session_type_e2str
.
at
(
pdu_session_type
);
}
}
pdu_session_type_t
;
//-------------------------------------
...
...
src/common/3gpp_29.274.h
View file @
71b5eb69
...
...
@@ -142,15 +142,6 @@ struct imsi_s {
};
typedef
struct
imsi_s
imsi_t
;
//-------------------------------------
// 8.9 IP Address
typedef
struct
ip_address_s
{
bool
is_ipv4
;
// if not ipv4, then it is ipv6
union
{
struct
in_addr
ipv4_address
;
struct
in6_addr
ipv6_address
;
}
address
;
}
ip_address_t
;
//-------------------------------------
// 8.10 Mobile Equipment Identity (MEI)
// The ME Identity field contains either the IMEI or the IMEISV as defined in
...
...
src/common/3gpp_29.503.h
View file @
71b5eb69
...
...
@@ -38,6 +38,26 @@ typedef struct ssc_mode_s {
ssc_mode_s
()
:
ssc_mode
(
SSC_MODE_1
)
{}
ssc_mode_s
(
ssc_mode_e
mode
)
:
ssc_mode
(
mode
)
{}
ssc_mode_s
(
const
struct
ssc_mode_s
&
p
)
:
ssc_mode
(
p
.
ssc_mode
)
{}
ssc_mode_s
(
const
std
::
string
&
s
)
{
if
(
s
.
compare
(
"SSC_MODE_1"
)
==
0
)
{
ssc_mode
=
ssc_mode_e
::
SSC_MODE_1
;
}
else
if
(
s
.
compare
(
"SSC_MODE_2"
)
==
0
)
{
ssc_mode
=
ssc_mode_e
::
SSC_MODE_2
;
}
else
if
(
s
.
compare
(
"SSC_MODE_3"
)
==
0
)
{
ssc_mode
=
ssc_mode_e
::
SSC_MODE_3
;
}
else
{
ssc_mode
=
ssc_mode_e
::
SSC_MODE_1
;
// default mode
}
}
ssc_mode_s
&
operator
=
(
const
ssc_mode_s
&
s
)
{
ssc_mode
=
s
.
ssc_mode
;
return
*
this
;
}
virtual
~
ssc_mode_s
(){};
}
ssc_mode_t
;
typedef
struct
pdu_session_types_s
{
...
...
@@ -50,12 +70,133 @@ typedef struct ssc_modes_s {
std
::
vector
<
ssc_mode_t
>
allowed_ssc_modes
;
}
ssc_modes_t
;
enum
ip_address_type_value_e
{
IP_ADDRESS_TYPE_IPV4_ADDRESS
=
0
,
IP_ADDRESS_TYPE_IPV6_ADDRESS
=
1
,
IP_ADDRESS_TYPE_IPV6_PREFIX
=
2
};
typedef
struct
ipv6_prefix_s
{
struct
in6_addr
prefix
;
uint8_t
prefix_len
;
std
::
string
to_string
()
const
{
return
conv
::
toString
(
prefix
)
+
"/"
+
std
::
to_string
(
prefix_len
);
}
}
ipv6_prefix_t
;
typedef
struct
ip_address_s
{
uint8_t
ip_address_type
;
union
{
struct
in_addr
ipv4_address
;
struct
in6_addr
ipv6_address
;
ipv6_prefix_t
ipv6_prefix
;
}
u1
;
bool
operator
==
(
const
struct
ip_address_s
&
i
)
const
{
if
((
i
.
ip_address_type
==
this
->
ip_address_type
)
&&
(
i
.
u1
.
ipv4_address
.
s_addr
==
this
->
u1
.
ipv4_address
.
s_addr
)
&&
(
i
.
u1
.
ipv6_address
.
s6_addr32
[
0
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
0
])
&&
(
i
.
u1
.
ipv6_address
.
s6_addr32
[
1
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
1
])
&&
(
i
.
u1
.
ipv6_address
.
s6_addr32
[
2
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
2
])
&&
(
i
.
u1
.
ipv6_address
.
s6_addr32
[
3
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
3
])
&&
(
i
.
u1
.
ipv6_prefix
.
prefix_len
==
this
->
u1
.
ipv6_prefix
.
prefix_len
)
&&
(
i
.
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
0
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
0
])
&&
(
i
.
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
1
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
1
])
&&
(
i
.
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
2
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
2
])
&&
(
i
.
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
3
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
3
]))
{
return
true
;
}
else
{
return
false
;
}
};
bool
operator
==
(
const
struct
in_addr
&
a
)
const
{
if
((
IP_ADDRESS_TYPE_IPV4_ADDRESS
==
this
->
ip_address_type
)
&&
(
a
.
s_addr
==
u1
.
ipv4_address
.
s_addr
))
{
return
true
;
}
else
{
return
false
;
}
};
bool
operator
==
(
const
struct
in6_addr
&
i
)
const
{
if
((
IP_ADDRESS_TYPE_IPV6_ADDRESS
==
this
->
ip_address_type
)
&&
(
i
.
s6_addr32
[
0
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
0
])
&&
(
i
.
s6_addr32
[
1
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
1
])
&&
(
i
.
s6_addr32
[
2
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
2
])
&&
(
i
.
s6_addr32
[
3
]
==
this
->
u1
.
ipv6_address
.
s6_addr32
[
3
]))
{
return
true
;
}
else
{
return
false
;
}
};
bool
operator
==
(
const
ipv6_prefix_t
&
i
)
const
{
if
((
IP_ADDRESS_TYPE_IPV6_PREFIX
==
this
->
ip_address_type
)
&&
(
i
.
prefix_len
==
this
->
u1
.
ipv6_prefix
.
prefix_len
)
&&
(
i
.
prefix
.
s6_addr32
[
0
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
0
])
&&
(
i
.
prefix
.
s6_addr32
[
1
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
1
])
&&
(
i
.
prefix
.
s6_addr32
[
2
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
2
])
&&
(
i
.
prefix
.
s6_addr32
[
3
]
==
this
->
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
3
]))
{
return
true
;
}
else
{
return
false
;
}
};
ip_address_s
&
operator
=
(
const
struct
in_addr
&
a
)
{
ip_address_type
=
IP_ADDRESS_TYPE_IPV4_ADDRESS
;
u1
.
ipv4_address
.
s_addr
=
a
.
s_addr
;
return
*
this
;
}
ip_address_s
&
operator
=
(
const
struct
in6_addr
&
a
)
{
ip_address_type
=
IP_ADDRESS_TYPE_IPV6_ADDRESS
;
u1
.
ipv6_address
.
s6_addr32
[
0
]
=
a
.
s6_addr32
[
0
];
u1
.
ipv6_address
.
s6_addr32
[
1
]
=
a
.
s6_addr32
[
1
];
u1
.
ipv6_address
.
s6_addr32
[
2
]
=
a
.
s6_addr32
[
2
];
u1
.
ipv6_address
.
s6_addr32
[
3
]
=
a
.
s6_addr32
[
3
];
return
*
this
;
}
ip_address_s
&
operator
=
(
const
ipv6_prefix_t
&
a
)
{
ip_address_type
=
IP_ADDRESS_TYPE_IPV6_PREFIX
;
u1
.
ipv6_prefix
.
prefix_len
=
a
.
prefix_len
;
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
0
]
=
a
.
prefix
.
s6_addr32
[
0
];
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
1
]
=
a
.
prefix
.
s6_addr32
[
1
];
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
2
]
=
a
.
prefix
.
s6_addr32
[
2
];
u1
.
ipv6_prefix
.
prefix
.
s6_addr32
[
3
]
=
a
.
prefix
.
s6_addr32
[
3
];
return
*
this
;
}
virtual
~
ip_address_s
(){};
std
::
string
to_string
()
const
{
if
(
IP_ADDRESS_TYPE_IPV4_ADDRESS
==
this
->
ip_address_type
)
{
return
conv
::
toString
(
u1
.
ipv4_address
);
}
else
if
(
IP_ADDRESS_TYPE_IPV6_ADDRESS
==
this
->
ip_address_type
)
{
return
conv
::
toString
(
u1
.
ipv6_address
);
}
else
if
(
IP_ADDRESS_TYPE_IPV6_PREFIX
==
this
->
ip_address_type
)
{
return
u1
.
ipv6_prefix
.
to_string
();
}
return
std
::
string
(
"Unknown IP Address Type"
);
}
}
ip_address_t
;
typedef
struct
dnn_configuration_s
{
pdu_session_types_t
pdu_session_types
;
ssc_modes_t
ssc_modes
;
session_ambr_t
session_ambr
;
subscribed_default_qos_t
_5g_qos_profile
;
// staticIpAddresses
std
::
vector
<
ip_address_t
>
static_ip_addresses
;
}
dnn_configuration_t
;
#endif
src/smf_app/smf_app.cpp
View file @
71b5eb69
...
...
@@ -701,8 +701,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
(
...
...
@@ -907,6 +907,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
sc
.
get
()
->
set_supi
(
supi
);
sc
.
get
()
->
set_supi_prefix
(
supi_prefix
);
set_supi_2_smf_context
(
supi64
,
sc
);
sc
.
get
()
->
set_plmn
(
smreq
->
req
.
get_plmn
());
// PLMN
}
// Step 5. Create/update context with dnn information
...
...
@@ -954,7 +955,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
if
(
not
use_local_configuration_subscription_data
(
dnn_selection_mode
))
{
Logger
::
smf_app
().
debug
(
"Retrieve Session Management Subscription data from the UDM"
);
if
(
smf_sbi_inst
->
get_sm_data
(
supi64
,
dnn
,
snssai
,
subscription
))
{
plmn_t
plmn
=
{};
sc
.
get
()
->
get_plmn
(
plmn
);
if
(
smf_sbi_inst
->
get_sm_data
(
supi64
,
dnn
,
snssai
,
subscription
,
plmn
))
{
// Update dnn_context with subscription info
sc
.
get
()
->
insert_dnn_subscription
(
snssai
,
dnn
,
subscription
);
}
else
{
...
...
@@ -996,9 +999,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
}
}
// Store PLMN
sc
.
get
()
->
set_plmn
(
smreq
->
req
.
get_plmn
());
// Step 8. Generate a SMF context Id and store the corresponding information
// in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id))
scid_t
scid
=
generate_smf_context_ref
();
...
...
src/smf_app/smf_context.cpp
View file @
71b5eb69
...
...
@@ -1366,13 +1366,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
bool
set_paa
=
false
;
paa_t
paa
=
{};
Logger
::
smf_app
().
debug
(
"UE Address Allocation"
);
bool
paa_static_ip
=
false
;
switch
(
sp
->
pdu_session_type
.
pdu_session_type
)
{
case
PDU_SESSION_TYPE_E_IPV4V6
:
{
Logger
::
smf_app
().
debug
(
"PDU Session Type IPv4v6, select PDU Session Type IPv4"
);
bool
paa_res
=
false
;
// TODO: Verify if use default session type or requested session type
std
::
shared_ptr
<
session_management_subscription
>
ss
=
{};
std
::
shared_ptr
<
dnn_configuration_t
>
sdc
=
{};
find_dnn_subscription
(
snssai
,
ss
);
...
...
@@ -1381,12 +1376,53 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if
(
nullptr
!=
sdc
.
get
())
{
paa
.
pdu_session_type
.
pdu_session_type
=
sdc
.
get
()
->
pdu_session_types
.
default_session_type
.
pdu_session_type
;
->
pdu_session_types
.
default_session_type
.
pdu_session_type
;
// TODO: Verified if use default session
// type or requested session type
// Static IP address allocation
for
(
auto
addr
:
sdc
.
get
()
->
static_ip_addresses
)
{
if
((
sp
->
pdu_session_type
.
pdu_session_type
==
PDU_SESSION_TYPE_E_IPV4V6
)
or
(
sp
->
pdu_session_type
.
pdu_session_type
==
PDU_SESSION_TYPE_E_IPV4
))
{
if
(
addr
.
ip_address_type
==
IP_ADDRESS_TYPE_IPV4_ADDRESS
)
{
Logger
::
smf_app
().
debug
(
"Static IP Address with IPv4 %s"
,
inet_ntoa
(
*
((
struct
in_addr
*
)
&
addr
.
u1
.
ipv4_address
)));
paa
.
ipv4_address
.
s_addr
=
addr
.
u1
.
ipv4_address
.
s_addr
;
paa
.
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4
;
set_paa
=
true
;
paa_static_ip
=
true
;
}
}
else
if
(
sp
->
pdu_session_type
.
pdu_session_type
==
PDU_SESSION_TYPE_E_IPV6
)
{
paa
.
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV6
;
if
(
addr
.
ip_address_type
==
IP_ADDRESS_TYPE_IPV6_ADDRESS
)
{
paa
.
ipv6_address
=
addr
.
u1
.
ipv6_address
;
}
else
if
(
addr
.
ip_address_type
==
IP_ADDRESS_TYPE_IPV6_PREFIX
)
{
paa
.
ipv6_address
=
addr
.
u1
.
ipv6_prefix
.
prefix
;
// TODO: prefix length
}
char
str_addr6
[
INET6_ADDRSTRLEN
];
if
(
inet_ntop
(
AF_INET6
,
&
paa
.
ipv6_address
,
str_addr6
,
sizeof
(
str_addr6
)))
{
Logger
::
smf_app
().
debug
(
"Static IP Address with IPv6 %s"
,
str_addr6
);
}
set_paa
=
true
;
paa_static_ip
=
true
;
}
}
}
}
switch
(
sp
->
pdu_session_type
.
pdu_session_type
)
{
case
PDU_SESSION_TYPE_E_IPV4V6
:
{
Logger
::
smf_app
().
debug
(
"PDU Session Type IPv4v6, select PDU Session Type IPv4"
);
// TODO: use requested PDU Session Type?
// paa.pdu_session_type.pdu_session_type = PDU_SESSION_TYPE_E_IPV4V6;
if
((
not
paa_
res
)
||
(
not
paa
.
is_ip_assigned
()))
{
if
((
not
paa_
static_ip
)
||
(
not
paa
.
is_ip_assigned
()))
{
bool
success
=
paa_dynamic
::
get_instance
().
get_free_paa
(
sd
->
dnn_in_use
,
paa
);
if
(
success
)
{
...
...
@@ -1398,8 +1434,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp_pending
->
res
.
set_cause
(
static_cast
<
uint8_t
>
(
cause_value_5gsm_e
::
CAUSE_26_INSUFFICIENT_RESOURCES
));
}
// TODO: Static IP address allocation
}
else
if
((
paa_res
)
&&
(
paa
.
is_ip_assigned
()))
{
}
else
if
((
paa_static_ip
)
&&
(
paa
.
is_ip_assigned
()))
{
set_paa
=
true
;
}
Logger
::
smf_app
().
info
(
...
...
@@ -1417,30 +1452,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
Logger
::
smf_app
().
debug
(
"PDU Session Type IPv4"
);
if
(
!
pco_ids
.
ci_ipv4_address_allocation_via_dhcpv4
)
{
// use SM NAS signalling
// static or dynamic address allocation
bool
paa_res
=
false
;
// how to define static or dynamic
// depend of subscription information: staticIpAddress in DNN
// Configuration
// TODO: check static IP address is available in the subscription
// information (SessionManagementSubscription) or in DHCP/DN-AAA
std
::
shared_ptr
<
session_management_subscription
>
ss
=
{};
std
::
shared_ptr
<
dnn_configuration_t
>
sdc
=
{};
find_dnn_subscription
(
snssai
,
ss
);
if
(
nullptr
!=
ss
.
get
())
{
ss
.
get
()
->
find_dnn_configuration
(
sd
->
dnn_in_use
,
sdc
);
if
(
nullptr
!=
sdc
.
get
())
{
paa
.
pdu_session_type
.
pdu_session_type
=
sdc
.
get
()
->
pdu_session_types
.
default_session_type
.
pdu_session_type
;
// TODO: Verified if use default session
// type or requested session type
// TODO: static ip address
}
}
if
((
not
paa_res
)
||
(
not
paa
.
is_ip_assigned
()))
{
if
((
not
paa_static_ip
)
||
(
not
paa
.
is_ip_assigned
()))
{
bool
success
=
paa_dynamic
::
get_instance
().
get_free_paa
(
sd
->
dnn_in_use
,
paa
);
if
(
success
)
{
...
...
@@ -1452,8 +1464,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp_pending
->
res
.
set_cause
(
static_cast
<
uint8_t
>
(
cause_value_5gsm_e
::
CAUSE_26_INSUFFICIENT_RESOURCES
));
}
// Static IP address allocation
}
else
if
((
paa_
res
)
&&
(
paa
.
is_ip_assigned
()))
{
}
else
if
((
paa_
static_ip
)
&&
(
paa
.
is_ip_assigned
()))
{
set_paa
=
true
;
}
Logger
::
smf_app
().
info
(
...
...
src/smf_app/smf_sbi.cpp
View file @
71b5eb69
...
...
@@ -35,6 +35,9 @@
#include <pistache/http.h>
#include <pistache/mime.h>
#include <nlohmann/json.hpp>
#include <boost/algorithm/string/split.hpp>
//#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "common_defs.h"
#include "itti.hpp"
...
...
@@ -833,13 +836,23 @@ void smf_sbi::subscribe_upf_status_notify(
//------------------------------------------------------------------------------
bool
smf_sbi
::
get_sm_data
(
const
supi64_t
&
supi
,
const
std
::
string
&
dnn
,
const
snssai_t
&
snssai
,
std
::
shared_ptr
<
session_management_subscription
>
subscription
)
{
std
::
shared_ptr
<
session_management_subscription
>&
subscription
,
plmn_t
plmn
)
{
nlohmann
::
json
jsonData
=
{};
std
::
string
query_str
=
{};
std
::
string
mcc
=
{};
std
::
string
mnc
=
{};
conv
::
plmnToMccMnc
(
plmn
,
mcc
,
mnc
);
query_str
=
"?single-nssai={
\"
sst
\"
:"
+
std
::
to_string
(
snssai
.
sST
)
+
",
\"
sd
\"
:
\"
"
+
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
)))
+
":"
+
std
::
to_string
(
smf_cfg
.
udm_addr
.
port
)
+
NUDM_SDM_BASE
+
smf_cfg
.
udm_addr
.
api_version
+
fmt
::
format
(
NUDM_SDM_GET_SM_DATA_URL
,
std
::
to_string
(
supi
));
fmt
::
format
(
NUDM_SDM_GET_SM_DATA_URL
,
std
::
to_string
(
supi
))
+
query_str
;
Logger
::
smf_sbi
().
debug
(
"UDM's URL: %s "
,
url
.
c_str
());
std
::
string
response_data
=
{};
...
...
@@ -866,7 +879,9 @@ bool smf_sbi::get_sm_data(
Logger
::
smf_sbi
().
debug
(
"Got result for promise ID %d"
,
promise_id
);
Logger
::
smf_sbi
().
debug
(
"Response data %s"
,
response_data
.
c_str
());
Logger
::
smf_sbi
().
debug
(
"NF Instance Registration, response from NRF, HTTP Code: %u"
,
httpCode
);
"Session Management Subscription Data Retrieval, response from UDM, HTTP "
"Code: %u"
,
httpCode
);
if
(
static_cast
<
http_response_codes_e
>
(
httpCode
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_OK
)
{
...
...
@@ -887,50 +902,48 @@ bool smf_sbi::get_sm_data(
// Process the response
if
(
!
jsonData
.
empty
())
{
Logger
::
smf_sbi
().
debug
(
"Response from UDM %s"
,
jsonData
.
dump
().
c_str
());
// Verify SNSSAI
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
)
{
return
false
;
}
}
if
(
jsonData
[
"singleNssai"
].
find
(
"sd"
)
!=
jsonData
[
"singleNssai"
].
end
())
{
std
::
string
sd
=
jsonData
[
"singleNssai"
][
"sd"
];
if
(
sd
.
compare
(
snssai
.
sD
)
!=
0
)
{
return
false
;
}
}
// Retrieve SessionManagementSubscription and store in the context
for
(
nlohmann
::
json
::
iterator
it
=
jsonData
[
"dnnConfigurations"
].
begin
();
it
!=
jsonData
[
"dnnConfigurations"
].
end
();
++
it
)
{
Logger
::
smf_sbi
().
debug
(
"DNN %s"
,
it
.
key
().
c_str
());
if
(
it
.
key
().
compare
(
dnn
)
!=
0
)
break
;
try
{
std
::
shared_ptr
<
dnn_configuration_t
>
dnn_configuration
=
std
::
make_shared
<
dnn_configuration_t
>
();
pdu_session_type_t
pdu_session_type
(
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4
);
// PDU Session Type (Mandatory)
std
::
string
default_session_type
=
it
.
value
()[
"pduSessionTypes"
][
"defaultSessionType"
];
Logger
::
smf_sbi
().
debug
(
"Default session type %s"
,
default_session_type
.
c_str
());
if
(
default_session_type
.
compare
(
"IPV4"
)
==
0
)
{
pdu_session_type
.
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4
;
}
else
if
(
default_session_type
.
compare
(
"IPV6"
)
==
0
)
{
pdu_session_type
.
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV6
;
}
else
if
(
default_session_type
.
compare
(
"IPV4V6"
)
==
0
)
{
pdu_session_type
.
pdu_session_type
=
pdu_session_type_e
::
PDU_SESSION_TYPE_E_IPV4V6
;
}
pdu_session_type_t
pdu_session_type
(
default_session_type
);
dnn_configuration
->
pdu_session_types
.
default_session_type
=
pdu_session_type
;
// SSC_Mode
ssc_mode_t
ssc_mode
(
ssc_mode_e
::
SSC_MODE_1
);
// SSC_Mode (Mandatory)
std
::
string
default_ssc_mode
=
it
.
value
()[
"sscModes"
][
"defaultSscMode"
];
Logger
::
smf_sbi
().
debug
(
"Default SSC Mode %s"
,
default_ssc_mode
.
c_str
());
if
(
default_ssc_mode
.
compare
(
"SSC_MODE_1"
)
==
0
)
{
dnn_configuration
->
ssc_modes
.
default_ssc_mode
=
ssc_mode_t
(
ssc_mode_e
::
SSC_MODE_1
);
}
else
if
(
default_ssc_mode
.
compare
(
"SSC_MODE_2"
)
==
0
)
{
dnn_configuration
->
ssc_modes
.
default_ssc_mode
=
ssc_mode_t
(
ssc_mode_e
::
SSC_MODE_2
);
}
else
if
(
default_ssc_mode
.
compare
(
"SSC_MODE_3"
)
==
0
)
{
dnn_configuration
->
ssc_modes
.
default_ssc_mode
=
ssc_mode_t
(
ssc_mode_e
::
SSC_MODE_3
);
}
// 5gQosProfile
ssc_mode_t
ssc_mode
(
default_ssc_mode
);
dnn_configuration
->
ssc_modes
.
default_ssc_mode
=
ssc_mode
;
// 5gQosProfile (Optional)
if
(
it
.
value
().
find
(
"5gQosProfile"
)
!=
it
.
value
().
end
())
{
dnn_configuration
->
_5g_qos_profile
.
_5qi
=
it
.
value
()[
"5gQosProfile"
][
"5qi"
];
dnn_configuration
->
_5g_qos_profile
.
arp
.
priority_level
=
...
...
@@ -939,10 +952,16 @@ bool smf_sbi::get_sm_data(
it
.
value
()[
"5gQosProfile"
][
"arp"
][
"preemptCap"
];
dnn_configuration
->
_5g_qos_profile
.
arp
.
preempt_vuln
=
it
.
value
()[
"5gQosProfile"
][
"arp"
][
"preemptVuln"
];
// Optinal
if
(
it
.
value
()[
"5gQosProfile"
].
find
(
""
)
!=
it
.
value
()[
"5gQosProfile"
].
end
())
{
dnn_configuration
->
_5g_qos_profile
.
priority_level
=
1
;
// TODO: hardcoded
it
.
value
()[
"5gQosProfile"
][
"5QiPriorityLevel"
];
}
}
// session_ambr
// session_ambr (Optional)
if
(
it
.
value
().
find
(
"sessionAmbr"
)
!=
it
.
value
().
end
())
{
dnn_configuration
->
session_ambr
.
uplink
=
it
.
value
()[
"sessionAmbr"
][
"uplink"
];
dnn_configuration
->
session_ambr
.
downlink
=
...
...
@@ -951,12 +970,82 @@ bool smf_sbi::get_sm_data(
"Session AMBR Uplink %s, Downlink %s"
,
dnn_configuration
->
session_ambr
.
uplink
.
c_str
(),
dnn_configuration
->
session_ambr
.
downlink
.
c_str
());
}
// Static IP Addresses (Optional)
if
(
it
.
value
().
find
(
"staticIpAddress"
)
!=
it
.
value
().
end
())
{
for
(
const
auto
&
ip_addr
:
it
.
value
()[
"staticIpAddress"
])
{
if
(
ip_addr
.
find
(
"ipv4Addr"
)
!=
ip_addr
.
end
())
{
struct
in_addr
ue_ipv4_addr
=
{};
std
::
string
ue_ip_str
=
ip_addr
[
"ipv4Addr"
].
get
<
std
::
string
>
();
// ip_addr.at("ipv4Addr").get_to(ue_ip_str);
IPV4_STR_ADDR_TO_INADDR
(
util
::
trim
(
ue_ip_str
).
c_str
(),
ue_ipv4_addr
,
"BAD IPv4 ADDRESS FORMAT FOR UE IP ADDR !"
);
ip_address_t
ue_ip
=
{};
ue_ip
=
ue_ipv4_addr
;
dnn_configuration
->
static_ip_addresses
.
push_back
(
ue_ip
);
}
else
if
(
ip_addr
.
find
(
"ipv6Addr"
)
!=
ip_addr
.
end
())
{
unsigned
char
buf_in6_addr
[
sizeof
(
struct
in6_addr
)];
struct
in6_addr
ue_ipv6_addr
;
std
::
string
ue_ip_str
=
ip_addr
[
"ipv6Addr"
].
get
<
std
::
string
>
();
if
(
inet_pton
(
AF_INET6
,
util
::
trim
(
ue_ip_str
).
c_str
(),
buf_in6_addr
)
==
1
)
{
memcpy
(
&
ue_ipv6_addr
,
buf_in6_addr
,
sizeof
(
struct
in6_addr
));
}
else
{
Logger
::
smf_app
().
error
(
"Bad UE IPv6 Addr %s"
,
ue_ip_str
.
c_str
());
throw
(
"Bad UE IPv6 Addr %s"
,
ue_ip_str
.
c_str
());
}
ip_address_t
ue_ip
=
{};
ue_ip
=
ue_ipv6_addr
;
dnn_configuration
->
static_ip_addresses
.
push_back
(
ue_ip
);
}
else
if
(
ip_addr
.
find
(
"ipv6Prefix"
)
!=
ip_addr
.
end
())
{
unsigned
char
buf_in6_addr
[
sizeof
(
struct
in6_addr
)];
struct
in6_addr
ipv6_prefix
;
std
::
string
prefix_str
=
ip_addr
[
"ipv6Prefix"
].
get
<
std
::
string
>
();
std
::
vector
<
std
::
string
>
words
=
{};
boost
::
split
(
words
,
prefix_str
,
boost
::
is_any_of
(
"/"
),
boost
::
token_compress_on
);
if
(
words
.
size
()
!=
2
)
{
Logger
::
smf_app
().
error
(
"Bad value for UE IPv6 Prefix %s"
,
prefix_str
.
c_str
());
return
RETURNerror
;
}
if
(
inet_pton
(
AF_INET6
,
util
::
trim
(
words
.
at
(
0
)).
c_str
(),
buf_in6_addr
)
==
1
)
{
memcpy
(
&
ipv6_prefix
,
buf_in6_addr
,
sizeof
(
struct
in6_addr
));
}
else
{
Logger
::
smf_app
().
error
(
"Bad UE IPv6 Addr %s"
,
words
.
at
(
0
).
c_str
());
throw
(
"Bad UE IPv6 Addr %s"
,
words
.
at
(
0
).
c_str
());
}
ip_address_t
ue_ip
=
{};
ipv6_prefix_t
ue_ipv6_prefix
=
{};
ue_ipv6_prefix
.
prefix_len
=
std
::
stoi
(
util
::
trim
(
words
.
at
(
1
)));
ue_ipv6_prefix
.
prefix
=
ipv6_prefix
;
ue_ip
=
ue_ipv6_prefix
;
dnn_configuration
->
static_ip_addresses
.
push_back
(
ue_ip
);
}
}
}
subscription
->
insert_dnn_configuration
(
it
.
key
(),
dnn_configuration
);
return
true
;
}
catch
(
nlohmann
::
json
::
exception
&
e
)
{
Logger
::
smf_sbi
().
warn
(
"Exception message %s, exception id %d "
,
e
.
what
(),
e
.
id
);
return
false
;
}
catch
(
std
::
exception
&
e
)
{
Logger
::
smf_sbi
().
warn
(
"Exception message %s"
,
e
.
what
());
return
false
;
}
}
return
true
;
...
...
src/smf_app/smf_sbi.hpp
View file @
71b5eb69
...
...
@@ -157,7 +157,8 @@ class smf_sbi {
*/
bool
get_sm_data
(
const
supi64_t
&
supi
,
const
std
::
string
&
dnn
,
const
snssai_t
&
snssai
,
std
::
shared_ptr
<
session_management_subscription
>
subscription
);
std
::
shared_ptr
<
session_management_subscription
>&
subscription
,
plmn_t
plmn
=
{});
/*
* Subscribe to be notify from UDM
...
...
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