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
98e4efa5
Commit
98e4efa5
authored
Aug 17, 2022
by
Tien-Thinh Nguyen
Committed by
sagar arora
Aug 24, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix nake ptr
parent
67253515
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
374 additions
and
301 deletions
+374
-301
src/amf-app/amf_app.cpp
src/amf-app/amf_app.cpp
+44
-39
src/amf-app/amf_n1.cpp
src/amf-app/amf_n1.cpp
+38
-14
src/amf-app/amf_n1.hpp
src/amf-app/amf_n1.hpp
+13
-12
src/amf-app/amf_n2.cpp
src/amf-app/amf_n2.cpp
+19
-17
src/amf-app/amf_profile.hpp
src/amf-app/amf_profile.hpp
+1
-0
src/amf-app/amf_sbi.cpp
src/amf-app/amf_sbi.cpp
+8
-4
src/amf-app/amf_statistics.hpp
src/amf-app/amf_statistics.hpp
+1
-1
src/amf-app/mysql_db.cpp
src/amf-app/mysql_db.cpp
+39
-46
src/common/amf.hpp
src/common/amf.hpp
+2
-0
src/contexts/nas_context.hpp
src/contexts/nas_context.hpp
+1
-1
src/nas/common/3gpp_ts24501.hpp
src/nas/common/3gpp_ts24501.hpp
+2
-0
src/ngap/ngap_app/ngap_message_callback.hpp
src/ngap/ngap_app/ngap_message_callback.hpp
+193
-163
src/sbi/amf_server/impl/AMFConfigurationApiImpl.cpp
src/sbi/amf_server/impl/AMFConfigurationApiImpl.cpp
+5
-2
src/sbi/amf_server/impl/N1N2IndividualSubscriptionDocumentApiImpl.cpp
...server/impl/N1N2IndividualSubscriptionDocumentApiImpl.cpp
+4
-1
src/sbi/amf_server/impl/N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl.cpp
...tionsCollectionForIndividualUEContextsDocumentApiImpl.cpp
+4
-1
No files found.
src/amf-app/amf_app.cpp
View file @
98e4efa5
...
...
@@ -27,6 +27,7 @@
#include <iostream>
#include <stdexcept>
#include "3gpp_29.500.h"
#include "DLNASTransport.hpp"
#include "GlobalRanNodeId.h"
#include "RegistrationContextContainer.h"
...
...
@@ -322,7 +323,7 @@ void amf_app::handle_itti_message(
}
else
{
Logger
::
amf_app
().
info
(
"Handle ITTI N1N2 Message Transfer Request"
);
// Encode DL NAS TRANSPORT message(NAS message)
DLNASTransport
*
dl
=
new
DLNASTransport
();
auto
dl
=
std
::
make_unique
<
DLNASTransport
>
();
dl
->
setHeader
(
PLAIN_5GS_MSG
);
dl
->
setPayload_Container_Type
(
N1_SM_INFORMATION
);
dl
->
setPayload_Container
(
...
...
@@ -334,8 +335,9 @@ void amf_app::handle_itti_message(
comUt
::
print_buffer
(
"amf_app"
,
"n1n2 transfer"
,
nas
,
encoded_size
);
bstring
dl_nas
=
blk2bstr
(
nas
,
encoded_size
);
itti_downlink_nas_transfer
*
dl_msg
=
new
itti_downlink_nas_transfer
(
TASK_AMF_APP
,
TASK_AMF_N1
);
std
::
shared_ptr
<
itti_downlink_nas_transfer
>
dl_msg
=
std
::
make_shared
<
itti_downlink_nas_transfer
>
(
TASK_AMF_APP
,
TASK_AMF_N1
);
dl_msg
->
dl_nas
=
dl_nas
;
if
(
!
itti_msg
.
is_n2sm_set
)
{
dl_msg
->
is_n2sm_set
=
false
;
...
...
@@ -347,13 +349,12 @@ void amf_app::handle_itti_message(
}
amf_n1_inst
->
supi_2_amf_id
(
itti_msg
.
supi
,
dl_msg
->
amf_ue_ngap_id
);
amf_n1_inst
->
supi_2_ran_id
(
itti_msg
.
supi
,
dl_msg
->
ran_ue_ngap_id
);
std
::
shared_ptr
<
itti_downlink_nas_transfer
>
i
=
std
::
shared_ptr
<
itti_downlink_nas_transfer
>
(
dl_msg
);
int
ret
=
itti_inst
->
send_msg
(
i
);
int
ret
=
itti_inst
->
send_msg
(
dl_msg
);
if
(
0
!=
ret
)
{
Logger
::
amf_app
().
error
(
"Could not send ITTI message %s to task TASK_AMF_N1"
,
i
->
get_msg_name
());
dl_msg
->
get_msg_name
());
}
}
}
...
...
@@ -361,15 +362,11 @@ void amf_app::handle_itti_message(
//------------------------------------------------------------------------------
void
amf_app
::
handle_itti_message
(
itti_nas_signalling_establishment_request
&
itti_msg
)
{
// 1. Generate amf_ue_ngap_id
// 2. Create UE Context and store related information information
// 3. Send nas-pdu to task_amf_n1
long
amf_ue_ngap_id
=
0
;
std
::
shared_ptr
<
ue_context
>
uc
;
long
amf_ue_ngap_id
=
0
;
std
::
shared_ptr
<
ue_context
>
uc
=
{};
//
Check UE Context with 5g-s-tmsi
if
((
amf_ue_ngap_id
=
itti_msg
.
amf_ue_ngap_id
)
==
-
1
)
{
//
Generate amf_ue_ngap_id
if
((
amf_ue_ngap_id
=
itti_msg
.
amf_ue_ngap_id
)
==
INVALID_AMF_UE_NGAP_ID
)
{
amf_ue_ngap_id
=
generate_amf_ue_ngap_id
();
}
...
...
@@ -396,6 +393,7 @@ void amf_app::handle_itti_message(
amf_n2_inst
->
set_amf_ue_ngap_id_2_ue_ngap_context
(
amf_ue_ngap_id
,
unc
);
}
// Create UE Context and store related information information
if
(
uc
.
get
()
==
nullptr
)
{
Logger
::
amf_app
().
error
(
"Failed to create ue_context with ran_amf_id %s"
,
...
...
@@ -422,8 +420,10 @@ void amf_app::handle_itti_message(
Logger
::
amf_app
().
debug
(
"Receiving GUTI %s"
,
guti
.
c_str
());
}
itti_uplink_nas_data_ind
*
itti_n1_msg
=
new
itti_uplink_nas_data_ind
(
TASK_AMF_APP
,
TASK_AMF_N1
);
// Send NAS PDU to task_amf_n1 for further processing
std
::
shared_ptr
<
itti_uplink_nas_data_ind
>
itti_n1_msg
=
std
::
make_shared
<
itti_uplink_nas_data_ind
>
(
TASK_AMF_APP
,
TASK_AMF_N1
);
itti_n1_msg
->
amf_ue_ngap_id
=
amf_ue_ngap_id
;
itti_n1_msg
->
ran_ue_ngap_id
=
itti_msg
.
ran_ue_ngap_id
;
itti_n1_msg
->
is_nas_signalling_estab_req
=
true
;
...
...
@@ -434,13 +434,12 @@ void amf_app::handle_itti_message(
if
(
is_guti_valid
)
{
itti_n1_msg
->
guti
=
guti
;
}
std
::
shared_ptr
<
itti_uplink_nas_data_ind
>
i
=
std
::
shared_ptr
<
itti_uplink_nas_data_ind
>
(
itti_n1_msg
);
int
ret
=
itti_inst
->
send_msg
(
i
);
int
ret
=
itti_inst
->
send_msg
(
itti_n1_msg
);
if
(
0
!=
ret
)
{
Logger
::
amf_app
().
error
(
"Could not send ITTI message %s to task TASK_AMF_N1"
,
i
->
get_msg_name
());
i
tti_n1_msg
->
get_msg_name
());
}
}
}
...
...
@@ -536,12 +535,12 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
}
*/
long
amf_ue_ngap_id
=
-
1
;
long
amf_ue_ngap_id
=
INVALID_AMF_UE_NGAP_ID
;
// Generate AMF UE NGAP ID if necessary
if
(
!
uc
.
get
())
{
// No UE context existed
amf_ue_ngap_id
=
generate_amf_ue_ngap_id
();
}
else
{
if
((
amf_ue_ngap_id
=
uc
->
amf_ue_ngap_id
)
==
-
1
)
{
if
((
amf_ue_ngap_id
=
uc
->
amf_ue_ngap_id
)
==
INVALID_AMF_UE_NGAP_ID
)
{
amf_ue_ngap_id
=
generate_amf_ue_ngap_id
();
}
}
...
...
@@ -620,8 +619,9 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
// Step 5. Trigger the procedure following RegistrationRequest
itti_uplink_nas_data_ind
*
itti_n1_msg
=
new
itti_uplink_nas_data_ind
(
TASK_AMF_APP
,
TASK_AMF_N1
);
std
::
shared_ptr
<
itti_uplink_nas_data_ind
>
itti_n1_msg
=
std
::
make_shared
<
itti_uplink_nas_data_ind
>
(
TASK_AMF_APP
,
TASK_AMF_N1
);
itti_n1_msg
->
amf_ue_ngap_id
=
amf_ue_ngap_id
;
itti_n1_msg
->
ran_ue_ngap_id
=
ran_ue_ngap_id
;
itti_n1_msg
->
is_nas_signalling_estab_req
=
true
;
...
...
@@ -630,13 +630,11 @@ void amf_app::handle_itti_message(itti_sbi_n1_message_notification& itti_msg) {
itti_n1_msg
->
mnc
=
ran_node_id
.
getPlmnId
().
getMnc
();
itti_n1_msg
->
is_guti_valid
=
false
;
std
::
shared_ptr
<
itti_uplink_nas_data_ind
>
i
=
std
::
shared_ptr
<
itti_uplink_nas_data_ind
>
(
itti_n1_msg
);
int
ret
=
itti_inst
->
send_msg
(
i
);
int
ret
=
itti_inst
->
send_msg
(
itti_n1_msg
);
if
(
0
!=
ret
)
{
Logger
::
amf_app
().
error
(
"Could not send ITTI message %s to task TASK_AMF_N1"
,
i
->
get_msg_name
());
i
tti_n1_msg
->
get_msg_name
());
}
return
;
...
...
@@ -672,8 +670,9 @@ void amf_app::handle_itti_message(itti_sbi_n1n2_message_subscribe& itti_msg) {
nlohmann
::
json
response_data
=
{};
response_data
[
"createdData"
]
=
created_data
;
response_data
[
"httpResponseCode"
]
=
201
;
// TODO:
response_data
[
"location"
]
=
location
;
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_201_CREATED
);
response_data
[
"location"
]
=
location
;
// Notify to the result
if
(
itti_msg
.
promise_id
>
0
)
{
...
...
@@ -693,9 +692,11 @@ void amf_app::handle_itti_message(itti_sbi_n1n2_message_unsubscribe& itti_msg) {
nlohmann
::
json
response_data
=
{};
if
(
remove_n1n2_message_subscription
(
itti_msg
.
ue_cxt_id
,
itti_msg
.
subscription_id
))
{
response_data
[
"httpResponseCode"
]
=
204
;
// TODO:
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_204_NO_CONTENT
);
}
else
{
response_data
[
"httpResponseCode"
]
=
400
;
// TODO:
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_BAD_REQUEST
);
oai
::
amf
::
model
::
ProblemDetails
problem_details
=
{};
// TODO set problem_details
to_json
(
response_data
[
"ProblemDetails"
],
problem_details
);
...
...
@@ -721,9 +722,11 @@ void amf_app::handle_itti_message(itti_sbi_amf_configuration& itti_msg) {
if
(
read_amf_configuration
(
response_data
[
"content"
]))
{
Logger
::
amf_app
().
debug
(
"AMF configuration:
\n
%s"
,
response_data
[
"content"
].
dump
().
c_str
());
response_data
[
"httpResponseCode"
]
=
200
;
// TODO:
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
);
}
else
{
response_data
[
"httpResponseCode"
]
=
400
;
// TODO:
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_BAD_REQUEST
);
oai
::
amf
::
model
::
ProblemDetails
problem_details
=
{};
// TODO set problem_details
to_json
(
response_data
[
"ProblemDetails"
],
problem_details
);
...
...
@@ -750,7 +753,8 @@ void amf_app::handle_itti_message(itti_sbi_update_amf_configuration& itti_msg) {
if
(
update_amf_configuration
(
response_data
[
"content"
]))
{
Logger
::
amf_app
().
debug
(
"AMF configuration:
\n
%s"
,
response_data
[
"content"
].
dump
().
c_str
());
response_data
[
"httpResponseCode"
]
=
200
;
// TODO:
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
);
// Update AMF profile
generate_amf_profile
();
...
...
@@ -762,7 +766,8 @@ void amf_app::handle_itti_message(itti_sbi_update_amf_configuration& itti_msg) {
register_to_nrf
();
}
else
{
response_data
[
"httpResponseCode"
]
=
400
;
// TODO:
response_data
[
"httpResponseCode"
]
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_BAD_REQUEST
);
oai
::
amf
::
model
::
ProblemDetails
problem_details
=
{};
// TODO set problem_details
to_json
(
response_data
[
"ProblemDetails"
],
problem_details
);
...
...
@@ -925,8 +930,8 @@ bool amf_app::handle_nf_status_notification(
"Handle a NF status notification from NRF (HTTP version "
"%d)"
,
msg
->
http_version
);
// TODO
http_code
=
204
;
// HTTP_STATUS_CODE_204_NO_CONTENT
;
http_code
=
static_cast
<
uint32_t
>
(
http_response_codes_e
::
HTTP_RESPONSE_CODE_204_NO_CONTENT
)
;
return
true
;
}
...
...
src/amf-app/amf_n1.cpp
View file @
98e4efa5
...
...
@@ -138,12 +138,20 @@ void amf_n1_task(void*) {
}
//------------------------------------------------------------------------------
amf_n1
::
amf_n1
()
{
amf_n1
::
amf_n1
()
:
m_amfueid2nas_context
(),
m_nas_context
(),
m_guti2nas_context
()
{
if
(
itti_inst
->
create_task
(
TASK_AMF_N1
,
amf_n1_task
,
nullptr
))
{
Logger
::
amf_n1
().
error
(
"Cannot create task TASK_AMF_N1"
);
throw
std
::
runtime_error
(
"Cannot create task TASK_AMF_N1"
);
}
Logger
::
amf_n1
().
startup
(
"amf_n1 started"
);
amfueid2nas_context
=
{};
imsi2nas_context
=
{};
supi2amfId
=
{};
supi2ranId
=
{};
guti2nas_context
=
{};
random_state
=
{};
db_desc
=
{};
db_desc
.
db_conn
=
nullptr
;
// EventExposure: subscribe to UE Location Report
ee_ue_location_report_connection
=
event_sub
.
subscribe_ue_location_report
(
...
...
@@ -173,6 +181,8 @@ amf_n1::amf_n1() {
ee_ue_communication_failure_connection
=
event_sub
.
subscribe_ue_communication_failure
(
boost
::
bind
(
&
amf_n1
::
handle_ue_communication_failure_change
,
this
,
_1
,
_2
,
_3
));
Logger
::
amf_n1
().
startup
(
"amf_n1 started"
);
}
//------------------------------------------------------------------------------
...
...
@@ -774,9 +784,16 @@ void amf_n1::identity_response_handle(
stacs
.
update_ue_info
(
ueItem
);
set_5gmm_state
(
nc
,
_5GMM_COMMON_PROCEDURE_INITIATED
);
// stacs.display();
nc
.
get
()
->
is_stacs_available
=
true
;
}
set_5gmm_state
(
nc
,
_5GMM_COMMON_PROCEDURE_INITIATED
);
string
supi
=
"imsi-"
+
nc
.
get
()
->
imsi
;
Logger
::
amf_n1
().
debug
(
"Signal the UE Registration State Event notification for SUPI %s"
,
supi
.
c_str
());
event_sub
.
ue_registration_state
(
supi
,
_5GMM_COMMON_PROCEDURE_INITIATED
,
1
);
// TODO: Trigger UE Location Report
run_registration_procedure
(
nc
);
...
...
@@ -820,7 +837,7 @@ void amf_n1::service_request_handle(
}
set_amf_ue_ngap_id_2_nas_context
(
amf_ue_ngap_id
,
nc
);
nas_secu_ctx
*
secu
=
nc
.
get
()
->
security_ctx
;
nas_secu_ctx
*
secu
=
nc
.
get
()
->
security_ctx
;
// TODO: remove naked ptr
if
(
!
secu
)
{
Logger
::
amf_n1
().
error
(
"No Security Context found"
);
return
;
...
...
@@ -872,7 +889,12 @@ void amf_n1::service_request_handle(
// Get PDU Session Status from NAS Message Container if available
bstring
plain_msg
;
if
(
service_request
->
getNasMessageContainer
(
plain_msg
))
{
uint8_t
*
buf_nas
=
(
uint8_t
*
)
bdata
(
plain_msg
);
if
(
blength
(
plain_msg
)
<
NAS_MESSAGE_MIN_LENGTH
)
{
Logger
::
amf_n1
().
debug
(
"NAS message too short!"
);
return
;
}
uint8_t
*
buf_nas
=
(
uint8_t
*
)
bdata
(
plain_msg
);
// TODO
uint8_t
message_type
=
*
(
buf_nas
+
2
);
Logger
::
amf_n1
().
debug
(
"NAS message type 0x%x"
,
message_type
);
...
...
@@ -1161,7 +1183,7 @@ void amf_n1::registration_request_handle(
nc
.
get
()
->
serving_network
=
snn
;
nc
.
get
()
->
is_5g_guti_present
=
true
;
nc
.
get
()
->
to_be_register_by_new_suci
=
true
;
nc
.
get
()
->
ngKsi
=
100
&
0xf
;
nc
.
get
()
->
ngKsi
=
100
&
0xf
;
// TODO: remove hardcoded value
// nc.get()->imsi =
// set_supi_2_amf_id("imsi-" + nc.get()->imsi, amf_ue_ngap_id);
// set_supi_2_ran_id("imsi-" + nc.get()->imsi, ran_ue_ngap_id);
...
...
@@ -1728,14 +1750,12 @@ void amf_n1::run_registration_procedure(std::shared_ptr<nas_context>& nc) {
}
//------------------------------------------------------------------------------
// Get authentication vectors either from AUSF(UDM) or from AMF (generate
// locally)
bool
amf_n1
::
auth_vectors_generator
(
std
::
shared_ptr
<
nas_context
>&
nc
)
{
Logger
::
amf_n1
().
debug
(
"Start to generate Authentication Vectors"
);
if
(
amf_cfg
.
support_features
.
enable_external_ausf
)
{
// get authentication vectors from AUSF
if
(
!
get_authentication_vectors_from_ausf
(
nc
))
return
false
;
}
else
{
}
else
{
// Generate locally
authentication_vectors_generator_in_udm
(
nc
);
authentication_vectors_generator_in_ausf
(
nc
);
Logger
::
amf_n1
().
debug
(
"Deriving kamf"
);
...
...
@@ -1752,14 +1772,15 @@ bool amf_n1::auth_vectors_generator(std::shared_ptr<nas_context>& nc) {
bool
amf_n1
::
get_authentication_vectors_from_ausf
(
std
::
shared_ptr
<
nas_context
>&
nc
)
{
Logger
::
amf_n1
().
debug
(
"Get Authentication Vectors from AUSF"
);
// TODO: remove naked ptr
UEAuthenticationCtx
ueauthenticationctx
=
{};
AuthenticationInfo
authenticationinfo
=
{};
authenticationinfo
.
setSupiOrSuci
(
nc
.
get
()
->
imsi
);
authenticationinfo
.
setServingNetworkName
(
nc
.
get
()
->
serving_network
);
ResynchronizationInfo
resynchronizationInfo
=
{};
uint8_t
auts_len
=
blength
(
nc
.
get
()
->
auts
);
uint8_t
*
auts_value
=
(
uint8_t
*
)
bdata
(
nc
.
get
()
->
auts
);
uint8_t
auts_len
=
blength
(
nc
.
get
()
->
auts
);
// TODO
uint8_t
*
auts_value
=
(
uint8_t
*
)
bdata
(
nc
.
get
()
->
auts
);
// TODO
std
::
string
authenticationinfo_auts
=
{};
std
::
string
authenticationinfo_rand
=
{};
if
(
auts_value
)
{
...
...
@@ -1840,6 +1861,7 @@ bool amf_n1::get_authentication_vectors_from_ausf(
bool
amf_n1
::
_5g_aka_confirmation_from_ausf
(
std
::
shared_ptr
<
nas_context
>&
nc
,
bstring
resStar
)
{
Logger
::
amf_n1
().
debug
(
"5G AKA Confirmation from AUSF"
);
// TODO: remove naked ptr
std
::
string
remoteUri
=
nc
.
get
()
->
Href
;
std
::
string
msgBody
=
{};
...
...
@@ -1905,9 +1927,9 @@ bool amf_n1::_5g_aka_confirmation_from_ausf(
//------------------------------------------------------------------------------
bool
amf_n1
::
authentication_vectors_generator_in_ausf
(
std
::
shared_ptr
<
nas_context
>&
nc
)
{
// A.5, 3gpp ts33.501
// TODO: remove naked ptr
Logger
::
amf_n1
().
debug
(
"Generate Authentication Vectors in AUSF"
);
// Actually, done locally in
// AMF
"Generate Authentication Vectors in AUSF (locally in AMF)"
);
uint8_t
inputString
[
MAX_5GS_AUTH_VECTORS
][
40
];
uint8_t
*
xresStar
[
MAX_5GS_AUTH_VECTORS
];
uint8_t
*
rand
[
MAX_5GS_AUTH_VECTORS
];
...
...
@@ -1933,7 +1955,9 @@ bool amf_n1::authentication_vectors_generator_in_ausf(
//------------------------------------------------------------------------------
bool
amf_n1
::
authentication_vectors_generator_in_udm
(
std
::
shared_ptr
<
nas_context
>&
nc
)
{
Logger
::
amf_n1
().
debug
(
"Generate Authentication Vectors"
);
// TODO: remove naked ptr
Logger
::
amf_n1
().
debug
(
"Generate Authentication Vectors in UDM (locally in AMF)"
);
uint8_t
*
sqn
=
nullptr
;
uint8_t
*
auts
=
(
uint8_t
*
)
bdata
(
nc
.
get
()
->
auts
);
_5G_HE_AV_t
*
vector
=
nc
.
get
()
->
_5g_he_av
;
...
...
src/amf-app/amf_n1.hpp
View file @
98e4efa5
...
...
@@ -277,7 +277,8 @@ class amf_n1 {
std
::
shared_ptr
<
nas_context
>&
nc
,
bstring
&
nas_msg
);
/*
* Generate the Authentication Vectors
* Generate the Authentication Vectors (either from AUSF(UDM) or generate
* locally in AMF)
* @param [std::shared_ptr<nas_context>&] nc: Pointer to the UE NAS Context
* @return true if generated successfully, otherwise return false
*/
...
...
@@ -832,16 +833,6 @@ class amf_n1 {
std
::
string
supi
,
oai
::
amf
::
model
::
CommunicationFailure
,
uint8_t
http_version
);
// for Event Handling
amf_event
event_sub
;
bs2
::
connection
ee_ue_location_report_connection
;
bs2
::
connection
ee_ue_reachability_status_connection
;
bs2
::
connection
ee_ue_registration_state_connection
;
bs2
::
connection
ee_ue_connectivity_state_connection
;
bs2
::
connection
ee_ue_loss_of_connectivity_connection
;
bs2
::
connection
ee_ue_communication_failure_connection
;
private:
/*
* Handle UE-initiated Deregistration Request message
* @param [const uint32_t] ran_ue_ngap_id: RAN UE NGAP ID
...
...
@@ -986,6 +977,16 @@ class amf_n1 {
const
uint8_t
cause_value
,
const
uint32_t
ran_ue_ngap_id
,
const
long
amf_ue_ngap_id
);
// for Event Handling
amf_event
event_sub
;
bs2
::
connection
ee_ue_location_report_connection
;
bs2
::
connection
ee_ue_reachability_status_connection
;
bs2
::
connection
ee_ue_registration_state_connection
;
bs2
::
connection
ee_ue_connectivity_state_connection
;
bs2
::
connection
ee_ue_loss_of_connectivity_connection
;
bs2
::
connection
ee_ue_communication_failure_connection
;
private:
std
::
map
<
long
,
std
::
shared_ptr
<
nas_context
>>
amfueid2nas_context
;
// amf ue ngap id
mutable
std
::
shared_mutex
m_amfueid2nas_context
;
...
...
@@ -1001,7 +1002,7 @@ class amf_n1 {
static
std
::
map
<
std
::
string
,
std
::
string
>
rand_record
;
static
uint8_t
no_random_delta
;
random_state_t
random_state
;
database_t
*
db_desc
;
database_t
db_desc
;
};
}
// namespace amf_application
...
...
src/amf-app/amf_n2.cpp
View file @
98e4efa5
...
...
@@ -227,11 +227,13 @@ void amf_n2_task(void* args_p) {
//------------------------------------------------------------------------------
amf_n2
::
amf_n2
(
const
std
::
string
&
address
,
const
uint16_t
port_num
)
:
ngap_app
(
address
,
port_num
)
{
:
ngap_app
(
address
,
port_num
)
,
m_ranid2uecontext
(),
m_amfueid2uecontext
()
{
if
(
itti_inst
->
create_task
(
TASK_AMF_N2
,
amf_n2_task
,
nullptr
))
{
Logger
::
amf_n2
().
error
(
"Cannot create task TASK_AMF_N2"
);
throw
std
::
runtime_error
(
"Cannot create task TASK_AMF_N2"
);
}
ranid2uecontext
=
{};
amfueid2uecontext
=
{};
Logger
::
amf_n2
().
startup
(
"amf_n2 started"
);
}
...
...
@@ -411,17 +413,17 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
Logger
::
amf_n2
().
debug
(
"Encoding NG_SETUP_RESPONSE ..."
);
// encode NG SETUP RESPONSE message with information stored in configuration
// file and send_msg
uint8_t
*
buffer
=
(
uint8_t
*
)
calloc
(
1
,
BUFFER_SIZE_1024
);
NGSetupResponseMsg
ngSetupResp
;
uint8_t
*
buffer
=
(
uint8_t
*
)
calloc
(
1
,
BUFFER_SIZE_1024
);
NGSetupResponseMsg
ngSetupResp
=
{}
;
ngSetupResp
.
setAMFName
(
amf_cfg
.
amf_name
);
std
::
vector
<
struct
GuamiItem_s
>
guami_list
;
std
::
vector
<
GuamiItem_t
>
guami_list
;
for
(
int
i
=
0
;
i
<
amf_cfg
.
guami_list
.
size
();
i
++
)
{
struct
GuamiItem_s
tmp
;
tmp
.
mcc
=
amf_cfg
.
guami_list
[
i
].
mcc
;
tmp
.
mnc
=
amf_cfg
.
guami_list
[
i
].
mnc
;
tmp
.
regionID
=
amf_cfg
.
guami_list
[
i
].
regionID
;
tmp
.
AmfSetID
=
amf_cfg
.
guami_list
[
i
].
AmfSetID
;
tmp
.
AmfPointer
=
amf_cfg
.
guami_list
[
i
].
AmfPointer
;
GuamiItem_t
tmp
=
{}
;
tmp
.
mcc
=
amf_cfg
.
guami_list
[
i
].
mcc
;
tmp
.
mnc
=
amf_cfg
.
guami_list
[
i
].
mnc
;
tmp
.
regionID
=
amf_cfg
.
guami_list
[
i
].
regionID
;
tmp
.
AmfSetID
=
amf_cfg
.
guami_list
[
i
].
AmfSetID
;
tmp
.
AmfPointer
=
amf_cfg
.
guami_list
[
i
].
AmfPointer
;
guami_list
.
push_back
(
tmp
);
}
ngSetupResp
.
setGUAMIList
(
guami_list
);
...
...
@@ -429,13 +431,13 @@ void amf_n2::handle_itti_message(itti_ng_setup_request& itti_msg) {
ngSetupResp
.
setRelativeAmfCapacity
(
amf_cfg
.
relative_amf_capacity
);
std
::
vector
<
PlmnSliceSupport_t
>
plmn_list
;
for
(
int
i
=
0
;
i
<
amf_cfg
.
plmn_list
.
size
();
i
++
)
{
PlmnSliceSupport_t
tmp
;
tmp
.
mcc
=
amf_cfg
.
plmn_list
[
i
].
mcc
;
tmp
.
mnc
=
amf_cfg
.
plmn_list
[
i
].
mnc
;
PlmnSliceSupport_t
tmp
=
{}
;
tmp
.
mcc
=
amf_cfg
.
plmn_list
[
i
].
mcc
;
tmp
.
mnc
=
amf_cfg
.
plmn_list
[
i
].
mnc
;
for
(
int
j
=
0
;
j
<
amf_cfg
.
plmn_list
[
i
].
slice_list
.
size
();
j
++
)
{
S_Nssai
s_tmp
;
s_tmp
.
sst
=
std
::
to_string
(
amf_cfg
.
plmn_list
[
i
].
slice_list
[
j
].
sst
);
s_tmp
.
sd
=
std
::
to_string
(
amf_cfg
.
plmn_list
[
i
].
slice_list
[
j
].
sd
);
S_Nssai
s_tmp
=
{}
;
s_tmp
.
sst
=
std
::
to_string
(
amf_cfg
.
plmn_list
[
i
].
slice_list
[
j
].
sst
);
s_tmp
.
sd
=
std
::
to_string
(
amf_cfg
.
plmn_list
[
i
].
slice_list
[
j
].
sd
);
tmp
.
slice_list
.
push_back
(
s_tmp
);
}
plmn_list
.
push_back
(
tmp
);
...
...
@@ -717,7 +719,7 @@ void amf_n2::handle_itti_message(itti_initial_ue_message& init_ue_msg) {
}
itti_msg
->
ran_ue_ngap_id
=
ran_ue_ngap_id
;
itti_msg
->
amf_ue_ngap_id
=
-
1
;
itti_msg
->
amf_ue_ngap_id
=
INVALID_AMF_UE_NGAP_ID
;
int
ret
=
itti_inst
->
send_msg
(
itti_msg
);
if
(
0
!=
ret
)
{
...
...
src/amf-app/amf_profile.hpp
View file @
98e4efa5
...
...
@@ -77,6 +77,7 @@ class nf_profile : public std::enable_shared_from_this<nf_profile> {
return
*
this
;
}
// nf_profile(nf_profile &b) = delete;
virtual
~
nf_profile
()
{}
/*
* Set NF instance ID
...
...
src/amf-app/amf_sbi.cpp
View file @
98e4efa5
...
...
@@ -857,7 +857,8 @@ bool amf_sbi::discover_smf(
"NFDiscovery, response from NRF, json data:
\n
%s"
,
response_data
.
dump
().
c_str
());
if
(
response_code
!=
200
)
{
if
(
static_cast
<
http_response_codes_e
>
(
response_code
)
!=
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
)
{
Logger
::
amf_sbi
().
warn
(
"NFDiscovery, could not get response from NRF"
);
result
=
false
;
}
else
{
...
...
@@ -1001,8 +1002,10 @@ bool amf_sbi::send_ue_authentication_request(
Logger
::
amf_sbi
().
debug
(
"UE Authentication, response from AUSF, HTTP Code: %d"
,
response_code
);
if
((
response_code
==
200
)
or
(
response_code
==
201
))
{
// TODO: remove hardcoded value
if
((
static_cast
<
http_response_codes_e
>
(
response_code
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
)
or
(
static_cast
<
http_response_codes_e
>
(
response_code
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_201_CREATED
))
{
Logger
::
amf_sbi
().
debug
(
"UE Authentication, response from AUSF
\n
, %s "
,
response_data
.
dump
().
c_str
());
...
...
@@ -1652,7 +1655,8 @@ bool amf_sbi::get_nrf_uri(
"NS Selection, response from NSSF, json data:
\n
%s"
,
response_data
.
dump
().
c_str
());
if
(
response_code
!=
200
)
{
if
(
static_cast
<
http_response_codes_e
>
(
response_code
)
!=
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
)
{
Logger
::
amf_sbi
().
warn
(
"NS Selection, could not get response from NSSF"
);
result
=
false
;
}
else
{
...
...
src/amf-app/amf_statistics.hpp
View file @
98e4efa5
...
...
@@ -124,7 +124,7 @@ class statistics {
*/
uint32_t
get_number_connected_gnbs
()
const
;
p
ublic
:
p
rivate
:
uint32_t
gNB_connected
;
uint32_t
UE_connected
;
uint32_t
UE_registred
;
...
...
src/amf-app/mysql_db.cpp
View file @
98e4efa5
...
...
@@ -37,22 +37,22 @@ bool amf_n1::get_mysql_auth_info(
MYSQL_ROW
row
;
std
::
string
query
;
if
(
!
db_desc
->
db_conn
)
{
if
(
!
db_desc
.
db_conn
)
{
Logger
::
amf_n1
().
error
(
"Cannot connect to MySQL DB"
);
return
false
;
}
query
=
"SELECT `key`,`sqn`,`rand`,`OPc` FROM `users` WHERE `users`.`imsi`='"
+
imsi
+
"' "
;
pthread_mutex_lock
(
&
db_desc
->
db_cs_mutex
);
if
(
mysql_query
(
db_desc
->
db_conn
,
query
.
c_str
()))
{
pthread_mutex_unlock
(
&
db_desc
->
db_cs_mutex
);
pthread_mutex_lock
(
&
db_desc
.
db_cs_mutex
);
if
(
mysql_query
(
db_desc
.
db_conn
,
query
.
c_str
()))
{
pthread_mutex_unlock
(
&
db_desc
.
db_cs_mutex
);
Logger
::
amf_n1
().
error
(
"Query execution failed: %s
\n
"
,
mysql_error
(
db_desc
->
db_conn
));
"Query execution failed: %s
\n
"
,
mysql_error
(
db_desc
.
db_conn
));
return
false
;
}
res
=
mysql_store_result
(
db_desc
->
db_conn
);
pthread_mutex_unlock
(
&
db_desc
->
db_cs_mutex
);
res
=
mysql_store_result
(
db_desc
.
db_conn
);
pthread_mutex_unlock
(
&
db_desc
.
db_cs_mutex
);
if
(
!
res
)
{
Logger
::
amf_n1
().
error
(
"Data fetched from MySQL is not present"
);
return
false
;
...
...
@@ -81,29 +81,24 @@ bool amf_n1::get_mysql_auth_info(
//------------------------------------------------------------------------------
bool
amf_n1
::
connect_to_mysql
()
{
const
int
mysql_reconnect_val
=
1
;
db_desc
=
(
database_t
*
)
calloc
(
1
,
sizeof
(
database_t
));
if
(
!
db_desc
)
{
Logger
::
amf_n1
().
error
(
"An error occurs when allocating memory for DB_DESC"
);
return
false
;
}
pthread_mutex_init
(
&
db_desc
->
db_cs_mutex
,
NULL
);
db_desc
->
server
=
amf_cfg
.
auth_para
.
mysql_server
;
db_desc
->
user
=
amf_cfg
.
auth_para
.
mysql_user
;
db_desc
->
password
=
amf_cfg
.
auth_para
.
mysql_pass
;
db_desc
->
database
=
amf_cfg
.
auth_para
.
mysql_db
;
db_desc
->
db_conn
=
mysql_init
(
NULL
);
mysql_options
(
db_desc
->
db_conn
,
MYSQL_OPT_RECONNECT
,
&
mysql_reconnect_val
);
pthread_mutex_init
(
&
db_desc
.
db_cs_mutex
,
NULL
);
db_desc
.
server
=
amf_cfg
.
auth_para
.
mysql_server
;
db_desc
.
user
=
amf_cfg
.
auth_para
.
mysql_user
;
db_desc
.
password
=
amf_cfg
.
auth_para
.
mysql_pass
;
db_desc
.
database
=
amf_cfg
.
auth_para
.
mysql_db
;
db_desc
.
db_conn
=
mysql_init
(
NULL
);
mysql_options
(
db_desc
.
db_conn
,
MYSQL_OPT_RECONNECT
,
&
mysql_reconnect_val
);
if
(
!
mysql_real_connect
(
db_desc
->
db_conn
,
db_desc
->
server
.
c_str
(),
db_desc
->
user
.
c_str
(),
db_desc
->
password
.
c_str
(),
db_desc
->
database
.
c_str
(),
0
,
NULL
,
0
))
{
db_desc
.
db_conn
,
db_desc
.
server
.
c_str
(),
db_desc
.
user
.
c_str
(),
db_desc
.
password
.
c_str
(),
db_desc
.
database
.
c_str
(),
0
,
NULL
,
0
))
{
Logger
::
amf_n1
().
error
(
"An error occurred while connecting to db: %s"
,
mysql_error
(
db_desc
->
db_conn
));
mysql_error
(
db_desc
.
db_conn
));
mysql_thread_end
();
return
false
;
}
mysql_set_server_option
(
db_desc
->
db_conn
,
MYSQL_OPTION_MULTI_STATEMENTS_ON
);
mysql_set_server_option
(
db_desc
.
db_conn
,
MYSQL_OPTION_MULTI_STATEMENTS_ON
);
return
true
;
}
...
...
@@ -115,7 +110,7 @@ void amf_n1::mysql_push_rand_sqn(
char
query
[
1000
];
int
query_length
=
0
;
uint64_t
sqn_decimal
=
0
;
if
(
!
db_desc
->
db_conn
)
{
if
(
!
db_desc
.
db_conn
)
{
Logger
::
amf_n1
().
error
(
"Cannot connect to MySQL DB"
);
return
;
}
...
...
@@ -135,31 +130,30 @@ void amf_n1::mysql_push_rand_sqn(
sprintf
(
&
query
[
query_length
],
"'),`sqn`=%"
PRIu64
,
sqn_decimal
);
query_length
+=
sprintf
(
&
query
[
query_length
],
" WHERE `users`.`imsi`='%s'"
,
imsi
.
c_str
());
pthread_mutex_lock
(
&
db_desc
->
db_cs_mutex
);
if
(
mysql_query
(
db_desc
->
db_conn
,
query
))
{
pthread_mutex_unlock
(
&
db_desc
->
db_cs_mutex
);
pthread_mutex_lock
(
&
db_desc
.
db_cs_mutex
);
if
(
mysql_query
(
db_desc
.
db_conn
,
query
))
{
pthread_mutex_unlock
(
&
db_desc
.
db_cs_mutex
);
Logger
::
amf_n1
().
error
(
"Query execution failed: %s"
,
mysql_error
(
db_desc
->
db_conn
));
"Query execution failed: %s"
,
mysql_error
(
db_desc
.
db_conn
));
return
;
}
do
{
res
=
mysql_store_result
(
db_desc
->
db_conn
);
res
=
mysql_store_result
(
db_desc
.
db_conn
);
if
(
res
)
{
mysql_free_result
(
res
);
}
else
{
if
(
mysql_field_count
(
db_desc
->
db_conn
)
==
0
)
{
if
(
mysql_field_count
(
db_desc
.
db_conn
)
==
0
)
{
Logger
::
amf_n1
().
debug
(
"[MySQL] %lld rows affected"
,
mysql_affected_rows
(
db_desc
->
db_conn
));
"[MySQL] %lld rows affected"
,
mysql_affected_rows
(
db_desc
.
db_conn
));
}
else
{
/* some error occurred */
Logger
::
amf_n1
().
error
(
"Could not retrieve result set"
);
break
;
}
}
if
((
status
=
mysql_next_result
(
db_desc
->
db_conn
))
>
0
)
if
((
status
=
mysql_next_result
(
db_desc
.
db_conn
))
>
0
)
Logger
::
amf_n1
().
error
(
"Could not execute statement"
);
}
while
(
status
==
0
);
pthread_mutex_unlock
(
&
db_desc
->
db_cs_mutex
);
pthread_mutex_unlock
(
&
db_desc
.
db_cs_mutex
);
return
;
}
...
...
@@ -168,7 +162,7 @@ void amf_n1::mysql_increment_sqn(const std::string& imsi) {
int
status
;
MYSQL_RES
*
res
;
char
query
[
1000
];
if
(
db_desc
->
db_conn
==
NULL
)
{
if
(
db_desc
.
db_conn
==
NULL
)
{
Logger
::
amf_n1
().
error
(
"Cannot connect to MySQL DB"
);
return
;
}
...
...
@@ -176,31 +170,30 @@ void amf_n1::mysql_increment_sqn(const std::string& imsi) {
query
,
"UPDATE `users` SET `sqn` = `sqn` + 32 WHERE `users`.`imsi`='%s'"
,
imsi
.
c_str
());
pthread_mutex_lock
(
&
db_desc
->
db_cs_mutex
);
pthread_mutex_lock
(
&
db_desc
.
db_cs_mutex
);
if
(
mysql_query
(
db_desc
->
db_conn
,
query
))
{
pthread_mutex_unlock
(
&
db_desc
->
db_cs_mutex
);
if
(
mysql_query
(
db_desc
.
db_conn
,
query
))
{
pthread_mutex_unlock
(
&
db_desc
.
db_cs_mutex
);
Logger
::
amf_n1
().
error
(
"Query execution failed: %s"
,
mysql_error
(
db_desc
->
db_conn
));
"Query execution failed: %s"
,
mysql_error
(
db_desc
.
db_conn
));
return
;
}
do
{
res
=
mysql_store_result
(
db_desc
->
db_conn
);
res
=
mysql_store_result
(
db_desc
.
db_conn
);
if
(
res
)
{
mysql_free_result
(
res
);
}
else
{
if
(
mysql_field_count
(
db_desc
->
db_conn
)
==
0
)
{
if
(
mysql_field_count
(
db_desc
.
db_conn
)
==
0
)
{
Logger
::
amf_n1
().
debug
(
"[MySQL] %lld rows affected"
,
mysql_affected_rows
(
db_desc
->
db_conn
));
"[MySQL] %lld rows affected"
,
mysql_affected_rows
(
db_desc
.
db_conn
));
}
else
{
Logger
::
amf_n1
().
error
(
"Could not retrieve result set"
);
break
;
}
}
if
((
status
=
mysql_next_result
(
db_desc
->
db_conn
))
>
0
)
if
((
status
=
mysql_next_result
(
db_desc
.
db_conn
))
>
0
)
Logger
::
amf_n1
().
error
(
"Could not execute statement"
);
}
while
(
status
==
0
);
pthread_mutex_unlock
(
&
db_desc
->
db_cs_mutex
);
pthread_mutex_unlock
(
&
db_desc
.
db_cs_mutex
);
return
;
}
src/common/amf.hpp
View file @
98e4efa5
...
...
@@ -42,6 +42,8 @@ constexpr auto CURL_MIME_BOUNDARY = "----Boundary";
#define GNB_UE_NGAP_ID_FMT "%" PRIu32
#define AMF_UE_NGAP_ID_FMT "%" PRIu64
constexpr
long
INVALID_AMF_UE_NGAP_ID
=
-
1
;
// Event Subscription IDs)
typedef
uint32_t
evsub_id_t
;
#define EVSUB_ID_FMT "0x%" PRIx32
...
...
src/contexts/nas_context.hpp
View file @
98e4efa5
...
...
@@ -123,7 +123,7 @@ class nas_context {
uint8_t
kamf
[
MAX_5GS_AUTH_VECTORS
][
32
];
security_context_t
_security
;
nas_secu_ctx
*
security_ctx
;
nas_secu_ctx
*
security_ctx
;
// TODO: avoid using naked ptr
bool
is_current_security_available
;
...
...
src/nas/common/3gpp_ts24501.hpp
View file @
98e4efa5
...
...
@@ -183,4 +183,6 @@ static const std::vector<std::string> nas_ciphering_algorithm_list_e2str = {
#define DEREGISTRATION_TYPE_MASK 0b00001000
#define NAS_MESSAGE_MIN_LENGTH 3
#endif
src/ngap/ngap_app/ngap_message_callback.hpp
View file @
98e4efa5
This diff is collapsed.
Click to expand it.
src/sbi/amf_server/impl/AMFConfigurationApiImpl.cpp
View file @
98e4efa5
...
...
@@ -21,6 +21,7 @@
#include <AMFConfigurationApiImpl.h>
#include "3gpp_29.500.h"
#include "logger.hpp"
extern
itti_mw
*
itti_inst
;
...
...
@@ -81,7 +82,8 @@ void AMFConfigurationApiImpl::read_configuration(
http_response_code
=
result
[
"httpResponseCode"
].
get
<
int
>
();
}
if
(
http_response_code
==
200
)
{
if
(
static_cast
<
http_response_codes_e
>
(
http_response_code
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
)
{
if
(
result
.
find
(
"content"
)
!=
result
.
end
())
{
json_data
=
result
[
"content"
];
}
...
...
@@ -152,7 +154,8 @@ void AMFConfigurationApiImpl::update_configuration(
http_response_code
=
result
[
"httpResponseCode"
].
get
<
int
>
();
}
if
(
http_response_code
==
200
)
{
if
(
static_cast
<
http_response_codes_e
>
(
http_response_code
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_200_OK
)
{
if
(
result
.
find
(
"content"
)
!=
result
.
end
())
{
json_data
=
result
[
"content"
];
}
...
...
src/sbi/amf_server/impl/N1N2IndividualSubscriptionDocumentApiImpl.cpp
View file @
98e4efa5
...
...
@@ -13,6 +13,8 @@
#include "N1N2IndividualSubscriptionDocumentApiImpl.h"
#include "3gpp_29.500.h"
extern
itti_mw
*
itti_inst
;
namespace
oai
{
namespace
amf
{
...
...
@@ -77,7 +79,8 @@ void N1N2IndividualSubscriptionDocumentApiImpl::n1_n2_message_un_subscribe(
http_response_code
=
result
[
"httpResponseCode"
].
get
<
int
>
();
}
if
(
http_response_code
==
204
)
{
if
(
static_cast
<
http_response_codes_e
>
(
http_response_code
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_204_NO_CONTENT
)
{
response
.
send
(
Pistache
::
Http
::
Code
::
No_Content
);
}
else
{
// Problem//details
...
...
src/sbi/amf_server/impl/N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl.cpp
View file @
98e4efa5
...
...
@@ -12,6 +12,8 @@
*/
#include "N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl.h"
#include "3gpp_29.500.h"
#include "itti.hpp"
extern
itti_mw
*
itti_inst
;
...
...
@@ -93,7 +95,8 @@ void N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl::
json_data
=
result
[
"createdData"
];
}
if
(
http_response_code
==
201
)
{
// TODO:
if
(
static_cast
<
http_response_codes_e
>
(
http_response_code
)
==
http_response_codes_e
::
HTTP_RESPONSE_CODE_201_CREATED
)
{
response
.
headers
().
add
<
Pistache
::
Http
::
Header
::
Location
>
(
location
);
// Location header
response
.
headers
().
add
<
Pistache
::
Http
::
Header
::
ContentType
>
(
...
...
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