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
7b4bdc8c
Commit
7b4bdc8c
authored
Aug 17, 2022
by
Tien-Thinh Nguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix nake ptr
parent
ea5dbeaf
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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -137,12 +137,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
(
...
...
@@ -172,6 +180,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"
);
}
//------------------------------------------------------------------------------
...
...
@@ -773,9 +783,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
);
...
...
@@ -819,7 +836,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
;
...
...
@@ -871,7 +888,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
);
...
...
@@ -1160,7 +1182,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);
...
...
@@ -1727,14 +1749,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"
);
...
...
@@ -1751,14 +1771,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
)
{
...
...
@@ -1839,6 +1860,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
=
{};
...
...
@@ -1904,9 +1926,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
];
...
...
@@ -1932,7 +1954,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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
This diff is collapsed.
Click to expand it.
src/sbi/amf_server/impl/AMFConfigurationApiImpl.cpp
View file @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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 @
7b4bdc8c
...
...
@@ -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