Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-AMF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
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-AMF
Commits
182acb4d
Commit
182acb4d
authored
Jan 27, 2022
by
Tien-Thinh Nguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First version for N1 Message Notify Procedure
parent
ef5b7fa4
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
228 additions
and
23 deletions
+228
-23
src/amf-app/amf_app.cpp
src/amf-app/amf_app.cpp
+22
-0
src/amf-app/amf_app.hpp
src/amf-app/amf_app.hpp
+9
-2
src/amf-app/amf_config.hpp
src/amf-app/amf_config.hpp
+35
-18
src/amf-app/amf_n1.cpp
src/amf-app/amf_n1.cpp
+61
-1
src/amf-app/amf_n1.hpp
src/amf-app/amf_n1.hpp
+4
-2
src/amf-app/amf_n11.cpp
src/amf-app/amf_n11.cpp
+94
-0
src/amf-app/amf_n11.hpp
src/amf-app/amf_n11.hpp
+2
-0
src/itti/msgs/itti_msg_n11.hpp
src/itti/msgs/itti_msg_n11.hpp
+1
-0
No files found.
src/amf-app/amf_app.cpp
View file @
182acb4d
...
...
@@ -874,6 +874,13 @@ void amf_app::add_promise(
curl_handle_responses_n2_sm
.
emplace
(
id
,
p
);
}
//---------------------------------------------------------------------------------------------
void
amf_app
::
add_promise
(
uint32_t
pid
,
boost
::
shared_ptr
<
boost
::
promise
<
nlohmann
::
json
>>&
p
)
{
std
::
unique_lock
lock
(
m_curl_handle_responses_n11
);
curl_handle_responses_n11
.
emplace
(
pid
,
p
);
}
//------------------------------------------------------------------------------
void
amf_app
::
trigger_process_response
(
uint32_t
pid
,
std
::
string
n2_sm
)
{
Logger
::
amf_app
().
debug
(
...
...
@@ -887,3 +894,18 @@ void amf_app::trigger_process_response(uint32_t pid, std::string n2_sm) {
curl_handle_responses_n2_sm
.
erase
(
pid
);
}
}
//------------------------------------------------------------------------------
void
amf_app
::
trigger_process_response
(
uint32_t
pid
,
nlohmann
::
json
&
json_data
)
{
Logger
::
amf_app
().
debug
(
"Trigger process response: Set promise with ID %u "
"to ready"
,
pid
);
std
::
unique_lock
lock
(
m_curl_handle_responses_n11
);
if
(
curl_handle_responses_n11
.
count
(
pid
)
>
0
)
{
curl_handle_responses_n11
[
pid
]
->
set_value
(
json_data
);
// Remove this promise from list
curl_handle_responses_n11
.
erase
(
pid
);
}
}
src/amf-app/amf_app.hpp
View file @
182acb4d
...
...
@@ -37,6 +37,7 @@
#include "amf_module_from_config.hpp"
#include "amf_profile.hpp"
#include "itti.hpp"
#include "itti_msg_n11.hpp"
#include "itti_msg_amf_app.hpp"
#include "ue_context.hpp"
#include "amf_subscription.hpp"
...
...
@@ -268,11 +269,13 @@ class amf_app {
return
util
::
uint_uid_generator
<
uint64_t
>::
get_instance
().
get_uid
();
}
void
trigger_process_response
(
uint32_t
pid
,
uint32_t
http_code
);
void
add_promise
(
uint32_t
pid
,
boost
::
shared_ptr
<
boost
::
promise
<
std
::
string
>>&
p
);
void
add_promise
(
uint32_t
pid
,
boost
::
shared_ptr
<
boost
::
promise
<
nlohmann
::
json
>>&
p
);
void
trigger_process_response
(
uint32_t
pid
,
uint32_t
http_code
);
void
trigger_process_response
(
uint32_t
pid
,
std
::
string
n2_sm
);
void
trigger_process_response
(
uint32_t
pid
,
nlohmann
::
json
&
json_data
);
private:
std
::
map
<
long
,
std
::
shared_ptr
<
ue_context
>>
amf_ue_ngap_id2ue_ctx
;
...
...
@@ -286,6 +289,10 @@ class amf_app {
mutable
std
::
shared_mutex
m_curl_handle_responses_n2_sm
;
std
::
map
<
uint32_t
,
boost
::
shared_ptr
<
boost
::
promise
<
std
::
string
>>>
curl_handle_responses_n2_sm
;
mutable
std
::
shared_mutex
m_curl_handle_responses_n11
;
std
::
map
<
uint32_t
,
boost
::
shared_ptr
<
boost
::
promise
<
nlohmann
::
json
>>>
curl_handle_responses_n11
;
};
}
// namespace amf_application
...
...
src/amf-app/amf_config.hpp
View file @
182acb4d
...
...
@@ -192,6 +192,12 @@ typedef struct {
std
::
string
fqdn
;
}
smf_inst_t
;
typedef
struct
nf_addr_s
{
struct
in_addr
ipv4_addr
;
unsigned
int
port
;
std
::
string
api_version
;
}
nf_addr_t
;
class
amf_config
{
public:
amf_config
();
...
...
@@ -228,24 +234,35 @@ class amf_config {
bool
use_fqdn_dns
;
bool
use_http2
;
}
support_features
;
struct
{
struct
in_addr
ipv4_addr
;
unsigned
int
port
;
std
::
string
api_version
;
}
nrf_addr
;
struct
{
struct
in_addr
ipv4_addr
;
unsigned
int
port
;
std
::
string
api_version
;
}
ausf_addr
;
struct
{
struct
in_addr
ipv4_addr
;
unsigned
int
port
;
std
::
string
api_version
;
}
nssf_addr
;
/*
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nrf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} ausf_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} udm_addr;
struct {
struct in_addr ipv4_addr;
unsigned int port;
std::string api_version;
} nssf_addr;
*/
nf_addr_t
nrf_addr
;
nf_addr_t
ausf_addr
;
nf_addr_t
udm_addr
;
nf_addr_t
nssf_addr
;
}
;
}
// namespace config
...
...
src/amf-app/amf_n1.cpp
View file @
182acb4d
...
...
@@ -3740,15 +3740,75 @@ bool amf_n1::check_requested_nssai(
//------------------------------------------------------------------------------
bool
amf_n1
::
get_slice_selection_subscription_data
(
const
std
::
shared_ptr
<
nas_context
>&
nc
,
nssai_t
&
nssai
)
const
{
const
std
::
shared_ptr
<
nas_context
>&
nc
,
nssai_t
&
nssai
)
{
// TODO: UDM selection (from NRF or configuration file)
if
(
amf_cfg
.
support_features
.
enable_external_udm
)
{
std
::
shared_ptr
<
ue_context
>
uc
=
{};
if
(
!
find_ue_context
(
nc
.
get
()
->
ran_ue_ngap_id
,
nc
.
get
()
->
amf_ue_ngap_id
,
uc
))
{
Logger
::
amf_n1
().
warn
(
"Cannot find the UE context"
);
return
false
;
}
std
::
shared_ptr
<
itti_n11_slice_selection_subscription_data
>
itti_msg
=
std
::
make_shared
<
itti_n11_slice_selection_subscription_data
>
(
TASK_AMF_N1
,
TASK_AMF_N11
);
// Generate a promise and associate this promise to the ITTI message
uint32_t
promise_id
=
amf_app_inst
->
generate_promise_id
();
Logger
::
amf_n1
().
debug
(
"Promise ID generated %d"
,
promise_id
);
boost
::
shared_ptr
<
boost
::
promise
<
nlohmann
::
json
>>
p
=
boost
::
make_shared
<
boost
::
promise
<
nlohmann
::
json
>>
();
boost
::
shared_future
<
nlohmann
::
json
>
f
=
p
->
get_future
();
amf_app_inst
->
add_promise
(
promise_id
,
p
);
itti_msg
->
http_version
=
1
;
itti_msg
->
supi
=
uc
.
get
()
->
supi
;
itti_msg
->
plmn
.
mcc
=
uc
.
get
()
->
cgi
.
mcc
;
itti_msg
->
plmn
.
mnc
=
uc
.
get
()
->
cgi
.
mnc
;
itti_msg
->
promise_id
=
promise_id
;
int
ret
=
itti_inst
->
send_msg
(
itti_msg
);
if
(
0
!=
ret
)
{
Logger
::
ngap
().
error
(
"Could not send ITTI message %s to task TASK_AMF_N2"
,
itti_msg
->
get_msg_name
());
}
bool
result
=
false
;
boost
::
future_status
status
;
// wait for timeout or ready
status
=
f
.
wait_for
(
boost
::
chrono
::
milliseconds
(
FUTURE_STATUS_TIMEOUT_MS
));
if
(
status
==
boost
::
future_status
::
ready
)
{
assert
(
f
.
is_ready
());
assert
(
f
.
has_value
());
assert
(
!
f
.
has_exception
());
// Wait for the result from APP and send reply to AMF
nlohmann
::
json
nssai
=
f
.
get
();
if
(
!
nssai
.
empty
())
{
Logger
::
ngap
().
debug
(
"Got NSSAI from UDM"
,
nssai
.
dump
().
c_str
());
}
else
{
return
false
;
}
}
else
{
return
false
;
}
}
else
{
// TODO: get from the conf file
return
get_slice_selection_subscription_data_from_conf_file
(
nc
,
nssai
);
}
return
true
;
}
//------------------------------------------------------------------------------
bool
amf_n1
::
get_slice_selection_subscription_data_from_conf_file
(
const
std
::
shared_ptr
<
nas_context
>&
nc
,
nssai_t
&
nssai
)
{
// TODO:
return
true
;
}
//------------------------------------------------------------------------------
bool
amf_n1
::
get_network_slice_selection
(
const
std
::
string
&
nf_instance_id
,
...
...
src/amf-app/amf_n1.hpp
View file @
182acb4d
...
...
@@ -221,12 +221,14 @@ class amf_n1 {
bool
reroute_registration_request
(
std
::
shared_ptr
<
nas_context
>&
nc
);
bool
get_slice_selection_subscription_data
(
const
std
::
shared_ptr
<
nas_context
>&
nc
,
nssai_t
&
nssai
)
const
;
const
std
::
shared_ptr
<
nas_context
>&
nc
,
nssai_t
&
nssai
);
bool
get_slice_selection_subscription_data_from_conf_file
(
const
std
::
shared_ptr
<
nas_context
>&
nc
,
nssai_t
&
nssai
);
bool
check_requested_nssai
(
const
std
::
shared_ptr
<
nas_context
>&
nc
,
const
nssai_t
&
nssai
)
const
;
bool
get_network_slice_selection
(
const
std
::
string
&
nf_instance_id
,
slice_info_fo_registration_t
&
slice_info
,
slice_info_fo
r
_registration_t
&
slice_info
,
authorized_network_slice_info_t
&
authorized_network_slice_info
)
const
;
void
send_n1_message_notity
(
const
std
::
shared_ptr
<
nas_context
>&
nc
,
...
...
src/amf-app/amf_n11.cpp
View file @
182acb4d
...
...
@@ -137,6 +137,15 @@ void amf_n11_task(void*) {
dynamic_cast
<
itti_sbi_notify_subscribed_event
*>
(
msg
);
amf_n11_inst
->
handle_itti_message
(
ref
(
*
m
));
}
break
;
case
N11_SLICE_SELECTION_SUBSCRIPTION_DATA
:
{
Logger
::
amf_n11
().
info
(
"Receive Slice Selection Subscription Data Retrieval Request, "
"handling ..."
);
itti_n11_slice_selection_subscription_data
*
m
=
dynamic_cast
<
itti_n11_slice_selection_subscription_data
*>
(
msg
);
amf_n11_inst
->
handle_itti_message
(
ref
(
*
m
));
}
break
;
case
TERMINATE
:
{
if
(
itti_msg_terminate
*
terminate
=
dynamic_cast
<
itti_msg_terminate
*>
(
msg
))
{
...
...
@@ -570,6 +579,91 @@ void amf_n11::handle_itti_message(itti_sbi_notify_subscribed_event& itti_msg) {
return
;
}
//------------------------------------------------------------------------------
void
amf_n11
::
handle_itti_message
(
itti_n11_slice_selection_subscription_data
&
itti_msg
)
{
Logger
::
amf_n11
().
debug
(
"Send Slice Selection Subscription Data Retrieval to UDM (HTTP version "
"%d)"
,
itti_msg
.
http_version
);
std
::
string
url
=
std
::
string
(
inet_ntoa
(
*
((
struct
in_addr
*
)
&
amf_cfg
.
udm_addr
.
ipv4_addr
)))
+
":"
+
std
::
to_string
(
amf_cfg
.
udm_addr
.
port
)
+
"/nudm-sdm/"
+
amf_cfg
.
udm_addr
.
api_version
+
"/"
+
itti_msg
.
supi
+
"/nssai"
;
nlohmann
::
json
json_data
=
{};
json_data
[
"plmn-id"
][
"mcc"
]
=
itti_msg
.
plmn
.
mcc
;
json_data
[
"plmn-id"
][
"mnc"
]
=
itti_msg
.
plmn
.
mnc
;
std
::
string
body
=
json_data
.
dump
();
Logger
::
amf_n11
().
debug
(
"Send Slice Selection Subscription Data Retrieval to UDM, URL %s"
,
url
.
c_str
());
Logger
::
amf_n11
().
debug
(
"MSG body:
\n
%s"
,
body
.
c_str
());
curl_global_init
(
CURL_GLOBAL_ALL
);
CURL
*
curl
=
curl
=
curl_easy_init
();
std
::
unique_ptr
<
std
::
string
>
httpData
(
new
std
::
string
());
nlohmann
::
json
response_data
=
{};
if
(
curl
)
{
CURLcode
res
=
{};
struct
curl_slist
*
headers
=
nullptr
;
headers
=
curl_slist_append
(
headers
,
"content-type: application/json"
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
headers
);
curl_easy_setopt
(
curl
,
CURLOPT_URL
,
url
.
c_str
());
curl_easy_setopt
(
curl
,
CURLOPT_HTTPGET
,
1
);
curl_easy_setopt
(
curl
,
CURLOPT_TIMEOUT_MS
,
CURL_TIMEOUT_MS
);
curl_easy_setopt
(
curl
,
CURLOPT_INTERFACE
,
amf_cfg
.
n11
.
if_name
.
c_str
());
if
(
itti_msg
.
http_version
==
2
)
{
curl_easy_setopt
(
curl
,
CURLOPT_VERBOSE
,
1L
);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt
(
curl
,
CURLOPT_SSL_VERIFYPEER
,
0L
);
curl_easy_setopt
(
curl
,
CURLOPT_SSL_VERIFYHOST
,
0L
);
curl_easy_setopt
(
curl
,
CURLOPT_HTTP_VERSION
,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE
);
}
// Response information
long
httpCode
=
{
0
};
std
::
unique_ptr
<
std
::
string
>
httpData
(
new
std
::
string
());
curl_easy_setopt
(
curl
,
CURLOPT_WRITEFUNCTION
,
&
callback
);
curl_easy_setopt
(
curl
,
CURLOPT_WRITEDATA
,
httpData
.
get
());
curl_easy_setopt
(
curl
,
CURLOPT_POSTFIELDSIZE
,
body
.
length
());
curl_easy_setopt
(
curl
,
CURLOPT_POSTFIELDS
,
body
.
c_str
());
res
=
curl_easy_perform
(
curl
);
curl_easy_getinfo
(
curl
,
CURLINFO_RESPONSE_CODE
,
&
httpCode
);
Logger
::
amf_n11
().
debug
(
"Response from UDM, HTTP Code: %d"
,
httpCode
);
if
(
static_cast
<
http_response_codes_e
>
(
httpCode
)
!=
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
)
{
try
{
response_data
=
nlohmann
::
json
::
parse
(
*
httpData
.
get
());
}
catch
(
nlohmann
::
json
::
exception
&
e
)
{
Logger
::
amf_n11
().
warn
(
"Could not parse JSON from the UDM response"
);
}
}
else
{
Logger
::
amf_n11
().
warn
(
"Could not get NSSAI from UDM"
);
}
curl_slist_free_all
(
headers
);
curl_easy_cleanup
(
curl
);
}
curl_global_cleanup
();
// Notify to the result
if
(
itti_msg
.
promise_id
>
0
)
{
amf_app_inst
->
trigger_process_response
(
itti_msg
.
promise_id
,
response_data
);
return
;
}
return
;
}
//------------------------------------------------------------------------------
bool
amf_n11
::
smf_selection_from_configuration
(
std
::
string
&
smf_addr
,
std
::
string
&
smf_api_version
)
{
...
...
src/amf-app/amf_n11.hpp
View file @
182acb4d
...
...
@@ -59,6 +59,8 @@ class amf_n11 {
void
handle_itti_message
(
itti_nsmf_pdusession_release_sm_context
&
itti_msg
);
void
handle_itti_message
(
itti_pdu_session_resource_setup_response
&
itti_msg
);
void
handle_itti_message
(
itti_sbi_notify_subscribed_event
&
itti_msg
);
void
handle_itti_message
(
itti_n11_slice_selection_subscription_data
&
itti_msg
);
void
send_pdu_session_update_sm_context_request
(
std
::
string
supi
,
std
::
shared_ptr
<
pdu_session_context
>
psc
,
...
...
src/itti/msgs/itti_msg_n11.hpp
View file @
182acb4d
...
...
@@ -205,6 +205,7 @@ class itti_n11_slice_selection_subscription_data : public itti_msg_n11 {
uint8_t
http_version
;
std
::
string
supi
;
plmn_t
plmn
;
uint32_t
promise_id
;
};
#endif
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