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
0d1c5fd6
Commit
0d1c5fd6
authored
May 05, 2020
by
Tien-Thinh Nguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add Release SM Context procedure
parent
0590fb18
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
543 additions
and
153 deletions
+543
-153
src/api-server/api/IndividualSMContextApi.cpp
src/api-server/api/IndividualSMContextApi.cpp
+7
-74
src/api-server/api/IndividualSMContextApi.h
src/api-server/api/IndividualSMContextApi.h
+1
-1
src/api-server/impl/IndividualSMContextApiImpl.cpp
src/api-server/impl/IndividualSMContextApiImpl.cpp
+9
-24
src/api-server/impl/IndividualSMContextApiImpl.h
src/api-server/impl/IndividualSMContextApiImpl.h
+1
-1
src/common/msg/itti_msg_n11.hpp
src/common/msg/itti_msg_n11.hpp
+82
-0
src/itti/itti_msg.hpp
src/itti/itti_msg.hpp
+2
-0
src/smf_app/smf_app.cpp
src/smf_app/smf_app.cpp
+80
-1
src/smf_app/smf_app.hpp
src/smf_app/smf_app.hpp
+8
-0
src/smf_app/smf_context.cpp
src/smf_app/smf_context.cpp
+58
-0
src/smf_app/smf_context.hpp
src/smf_app/smf_context.hpp
+10
-3
src/smf_app/smf_msg.cpp
src/smf_app/smf_msg.cpp
+11
-0
src/smf_app/smf_msg.hpp
src/smf_app/smf_msg.hpp
+30
-0
src/smf_app/smf_n11.cpp
src/smf_app/smf_n11.cpp
+39
-0
src/smf_app/smf_n11.hpp
src/smf_app/smf_n11.hpp
+21
-0
src/smf_app/smf_procedure.cpp
src/smf_app/smf_procedure.cpp
+83
-0
src/smf_app/smf_procedure.hpp
src/smf_app/smf_procedure.hpp
+13
-15
src/test/amf_client/amf-client.cpp
src/test/amf_client/amf-client.cpp
+88
-34
No files found.
src/api-server/api/IndividualSMContextApi.cpp
View file @
0d1c5fd6
...
...
@@ -87,84 +87,16 @@ void IndividualSMContextApi::setupRoutes() {
void
IndividualSMContextApi
::
release_sm_context_handler
(
const
Pistache
::
Rest
::
Request
&
request
,
Pistache
::
Http
::
ResponseWriter
response
)
{
// Getting the path params
auto
smContextRef
=
request
.
param
(
":smContextRef"
).
as
<
std
::
string
>
();
//TODO: to be updated as update_sm_context_handler
Logger
::
smf_api_server
().
info
(
"Received a Nsmf_PDUSession_UpdateSMContext: PDU Session Release request from AMF"
);
Logger
::
smf_api_server
().
debug
(
"Request body: %s
\n
"
,
request
.
body
().
c_str
());
SmContextReleaseMessage
smContextReleaseMessage
=
{
};
//find boundary
std
::
size_t
found
=
request
.
body
().
find
(
"Content-Type"
);
std
::
string
boundary_str
=
request
.
body
().
substr
(
2
,
found
-
4
);
Logger
::
smf_api_server
().
debug
(
"Boundary: %s"
,
boundary_str
.
c_str
());
//step 1. use multipartparser to decode the request
multipartparser_callbacks_init
(
&
g_callbacks
);
g_callbacks
.
on_body_begin
=
&
on_body_begin
;
g_callbacks
.
on_part_begin
=
&
on_part_begin
;
g_callbacks
.
on_header_field
=
&
on_header_field
;
g_callbacks
.
on_header_value
=
&
on_header_value
;
g_callbacks
.
on_headers_complete
=
&
on_headers_complete
;
g_callbacks
.
on_data
=
&
on_data
;
g_callbacks
.
on_part_end
=
&
on_part_end
;
g_callbacks
.
on_body_end
=
&
on_body_end
;
multipartparser
parser
=
{
};
init_globals
();
multipartparser_init
(
&
parser
,
reinterpret_cast
<
const
char
*>
(
boundary_str
.
c_str
()));
unsigned
int
str_len
=
request
.
body
().
length
();
unsigned
char
*
data
=
(
unsigned
char
*
)
malloc
(
str_len
+
1
);
memset
(
data
,
0
,
str_len
+
1
);
memcpy
((
void
*
)
data
,
(
void
*
)
request
.
body
().
c_str
(),
str_len
);
//if ((multipartparser_execute(&parser, &g_callbacks, request.body().c_str(), strlen(request.body().c_str())) != strlen(request.body().c_str())) or (!g_body_begin_called)){
if
((
multipartparser_execute
(
&
parser
,
&
g_callbacks
,
reinterpret_cast
<
const
char
*>
(
data
),
str_len
)
!=
strlen
(
request
.
body
().
c_str
()))
or
(
!
g_body_begin_called
))
{
Logger
::
smf_api_server
().
warn
(
"The received message can not be parsed properly!"
);
//TODO: fix this issue
//response.send(Pistache::Http::Code::Bad_Request, "");
//return;
}
free_wrapper
((
void
**
)
&
data
);
uint8_t
size
=
g_parts
.
size
();
Logger
::
smf_api_server
().
debug
(
"Number of g_parts %d"
,
g_parts
.
size
());
part
p0
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 1: %s"
,
p0
.
body
.
c_str
());
part
p1
=
{
};
if
(
size
>
1
)
{
p1
=
g_parts
.
front
();
g_parts
.
pop_front
();
Logger
::
smf_api_server
().
debug
(
"Request body, part 2: %s (%d bytes)"
,
p1
.
body
.
c_str
(),
p1
.
body
.
length
());
//part p2 = g_parts.front(); g_parts.pop_front();
//Logger::smf_api_server().debug("Request body, part 3: \n %s",p2.body.c_str());
}
// Getting the body param
SmContextReleaseData
smContextReleaseData
=
{
};
try
{
nlohmann
::
json
::
parse
(
p0
.
body
.
c_str
()).
get_to
(
smContextReleaseData
);
smContextReleaseMessage
.
setJsonData
(
smContextReleaseData
);
if
(
size
>
1
)
{
if
(
smContextReleaseData
.
n2SmInfoIsSet
())
{
//N2 SM (for Session establishment, or for session modification)
Logger
::
smf_api_server
().
debug
(
"N2 SM information is set"
);
smContextReleaseMessage
.
setBinaryDataN2SmInformation
(
p1
.
body
);
}
}
// Getting the path params
auto
smContextRef
=
request
.
param
(
":smContextRef"
).
as
<
std
::
string
>
();
this
->
release_sm_context
(
smContextRef
,
smContextReleaseMessage
,
response
);
SmContextReleaseData
smContextReleaseData
;
try
{
nlohmann
::
json
::
parse
(
request
.
body
()).
get_to
(
smContextReleaseData
);
this
->
release_sm_context
(
smContextRef
,
smContextReleaseData
,
response
);
}
catch
(
nlohmann
::
detail
::
exception
&
e
)
{
//send a 400 error
response
.
send
(
Pistache
::
Http
::
Code
::
Bad_Request
,
e
.
what
());
...
...
@@ -176,6 +108,7 @@ void IndividualSMContextApi::release_sm_context_handler(
}
}
void
IndividualSMContextApi
::
retrieve_sm_context_handler
(
const
Pistache
::
Rest
::
Request
&
request
,
Pistache
::
Http
::
ResponseWriter
response
)
{
...
...
src/api-server/api/IndividualSMContextApi.h
View file @
0d1c5fd6
...
...
@@ -98,7 +98,7 @@ class IndividualSMContextApi {
/// <param name="smContextReleaseData">representation of the data to be sent to the SMF when releasing the SM context (optional)</param>
virtual
void
release_sm_context
(
const
std
::
string
&
smContextRef
,
const
SmContextRelease
Message
&
smContextReleaseMessage
,
const
SmContextRelease
Data
&
smContextReleaseData
,
Pistache
::
Http
::
ResponseWriter
&
response
)
=
0
;
/// <summary>
...
...
src/api-server/impl/IndividualSMContextApiImpl.cpp
View file @
0d1c5fd6
...
...
@@ -50,7 +50,7 @@ IndividualSMContextApiImpl::IndividualSMContextApiImpl(
void
IndividualSMContextApiImpl
::
release_sm_context
(
const
std
::
string
&
smContextRef
,
const
SmContextRelease
Message
&
smContextReleaseMessage
,
const
SmContextRelease
Data
&
smContextReleaseData
,
Pistache
::
Http
::
ResponseWriter
&
response
)
{
//TODO: to be updated as update_sm_context_handler
...
...
@@ -58,30 +58,15 @@ void IndividualSMContextApiImpl::release_sm_context(
//handle Nsmf_PDUSession_UpdateSMContext Request
Logger
::
smf_api_server
().
info
(
"Received a PDUSession_UpdateSMContext Request: PDU Session Release request from AMF."
);
//Get the SmContextUpdateData from this message and process in smf_app
smf
::
pdu_session_update_sm_context_request
sm_context_req_msg
=
{
};
SmContextReleaseData
smContextReleaseData
=
smContextReleaseMessage
.
getJsonData
();
if
(
smContextReleaseData
.
n2SmInfoIsSet
())
{
//N2 SM (for Session establishment)
std
::
string
n2_sm_information
=
smContextReleaseMessage
.
getBinaryDataN2SmInformation
();
Logger
::
smf_api_server
().
debug
(
"smContextMessage, n2 sm information %s"
,
n2_sm_information
.
c_str
());
std
::
string
n2_sm_info_type
=
smContextReleaseData
.
getN2SmInfoType
();
sm_context_req_msg
.
set_n2_sm_information
(
n2_sm_information
);
sm_context_req_msg
.
set_n2_sm_info_type
(
n2_sm_info_type
);
}
//Step 2. TODO: initialize necessary values for sm context req from smContextReleaseData
"Received a PDUSession_ReleaseSMContext Request: PDU Session Release request from AMF."
);
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
itti_msg
=
std
::
make_shared
<
itti_n11_release_sm_context_request
>
(
TASK_SMF_N11
,
TASK_SMF_APP
,
response
,
smContextRef
);
//Step 3. Handle the itti_n11_update_sm_context_request message in smf_app
//std::shared_ptr<itti_n11_update_sm_context_request> itti_msg = std::make_shared<itti_n11_update_sm_context_request>(TASK_SMF_N11, TASK_SMF_APP, response, smContextRef);
//itti_msg->req = sm_context_req_msg;
//itti_msg->scid = smContextRef;
//m_smf_app->handle_pdu_session_update_sm_context_request(itti_msg);
itti_msg
->
scid
=
smContextRef
;
m_smf_app
->
handle_pdu_session_release_sm_context_request
(
itti_msg
);
}
...
...
src/api-server/impl/IndividualSMContextApiImpl.h
View file @
0d1c5fd6
...
...
@@ -76,7 +76,7 @@ class IndividualSMContextApiImpl :
void
release_sm_context
(
const
std
::
string
&
smContextRef
,
const
SmContextRelease
Message
&
smContextReleaseMessage
,
const
SmContextRelease
Data
&
smContextReleaseData
,
Pistache
::
Http
::
ResponseWriter
&
response
);
void
retrieve_sm_context
(
const
std
::
string
&
smContextRef
,
const
SmContextRetrieveData
&
smContextRetrieveData
,
...
...
src/common/msg/itti_msg_n11.hpp
View file @
0d1c5fd6
...
...
@@ -346,4 +346,86 @@ class itti_n11_n1n2_message_transfer_response_status : public itti_n11_msg {
};
//-----------------------------------------------------------------------------
class
itti_n11_release_sm_context_request
:
public
itti_n11_msg
{
public:
itti_n11_release_sm_context_request
(
const
task_id_t
orig
,
const
task_id_t
dest
,
Pistache
::
Http
::
ResponseWriter
&
response
)
:
itti_n11_msg
(
N11_SESSION_RELEASE_SM_CONTEXT_REQUEST
,
orig
,
dest
),
http_response
(
response
)
{
}
itti_n11_release_sm_context_request
(
const
task_id_t
orig
,
const
task_id_t
dest
,
Pistache
::
Http
::
ResponseWriter
&
response
,
const
std
::
string
id
)
:
itti_n11_msg
(
N11_SESSION_RELEASE_SM_CONTEXT_REQUEST
,
orig
,
dest
),
http_response
(
response
),
scid
(
id
)
{
}
itti_n11_release_sm_context_request
(
const
itti_n11_release_sm_context_request
&
i
)
:
itti_n11_msg
(
i
),
http_response
(
i
.
http_response
),
scid
(
i
.
scid
),
req
(
i
.
req
)
{
}
itti_n11_release_sm_context_request
(
const
itti_n11_release_sm_context_request
&
i
,
const
task_id_t
orig
,
const
task_id_t
dest
)
:
itti_n11_msg
(
i
,
orig
,
dest
),
http_response
(
i
.
http_response
),
scid
(
i
.
scid
),
req
(
i
.
req
)
{
}
const
char
*
get_msg_name
()
{
return
"N11_SESSION_RELEASE_SM_CONTEXT_REQUEST"
;
}
;
smf
::
pdu_session_release_sm_context_request
req
;
Pistache
::
Http
::
ResponseWriter
&
http_response
;
std
::
string
scid
;
//SM Context ID
};
//-----------------------------------------------------------------------------
class
itti_n11_release_sm_context_response
:
public
itti_n11_msg
{
public:
itti_n11_release_sm_context_response
(
const
task_id_t
orig
,
const
task_id_t
dest
,
Pistache
::
Http
::
ResponseWriter
&
response
)
:
itti_n11_msg
(
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE
,
orig
,
dest
),
http_response
(
response
.
clone
()),
res
()
{
}
itti_n11_release_sm_context_response
(
const
itti_n11_release_sm_context_response
&
i
)
:
itti_n11_msg
(
i
),
res
(
i
.
res
),
http_response
(
i
.
http_response
.
clone
())
{
}
itti_n11_release_sm_context_response
(
const
itti_n11_release_sm_context_response
&
i
,
const
task_id_t
orig
,
const
task_id_t
dest
)
:
itti_n11_msg
(
i
,
orig
,
dest
),
res
(
i
.
res
),
http_response
(
i
.
http_response
.
clone
())
{
}
const
char
*
get_msg_name
()
{
return
"N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE"
;
}
;
smf
::
pdu_session_release_sm_context_response
res
;
Pistache
::
Http
::
ResponseWriter
http_response
;
};
#endif
/* ITTI_MSG_N11_HPP_INCLUDED_ */
src/itti/itti_msg.hpp
View file @
0d1c5fd6
...
...
@@ -114,6 +114,8 @@ typedef enum {
N11_SESSION_MODIFICATION_REQUEST_SMF_REQUESTED
,
N11_SESSION_UPDATE_PDU_SESSION_STATUS
,
N11_SESSION_N1N2_MESSAGE_TRANSFER_RESPONSE_STATUS
,
N11_SESSION_RELEASE_SM_CONTEXT_REQUEST
,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE
,
NX_SESSION_MODIFICATION_REQUEST_NETWORK_REQUESTED
,
UDP_INIT
,
UDP_DATA_REQ
,
...
...
src/smf_app/smf_app.cpp
View file @
0d1c5fd6
...
...
@@ -542,7 +542,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError
.
setN1SmMsg
(
refToBinaryData
);
//PDU Session Establishment Reject
smf_n1_n2_inst
.
create_n1_sm_container
(
smreq
->
req
,
PDU_SESSION_ESTABLISHMENT_REJECT
,
PDU_SESSION_ESTABLISHMENT_REJECT
,
n1_sm_message
,
cause_n1
);
smf_app_inst
->
convert_string_2_hex
(
n1_sm_message
,
n1_sm_message_hex
);
smf_n11_inst
->
send_pdu_session_create_sm_context_response
(
...
...
@@ -844,6 +844,85 @@ void smf_app::handle_pdu_session_update_sm_context_request(
}
//------------------------------------------------------------------------------
void
smf_app
::
handle_pdu_session_release_sm_context_request
(
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
smreq
)
{
//TODO:
//handle PDU Session Release SM Context Request
Logger
::
smf_app
().
info
(
"Handle a PDU Session Release SM Context Request from an AMF"
);
//Step 1. get supi, dnn, nssai, pdu_session id from sm_context
//SM Context ID - uint32_t in our case
scid_t
scid
=
{
};
try
{
scid
=
std
::
stoi
(
smreq
->
scid
);
}
catch
(
const
std
::
exception
&
err
)
{
Logger
::
smf_app
().
warn
(
"Received a PDU Session Release SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!"
);
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
smreq
->
http_response
,
Pistache
::
Http
::
Code
::
Not_Found
);
return
;
}
std
::
shared_ptr
<
smf_context_ref
>
scf
=
{
};
if
(
is_scid_2_smf_context
(
scid
))
{
scf
=
scid_2_smf_context
(
scid
);
}
else
{
Logger
::
smf_app
().
warn
(
"Context associated with this id "
SCID_FMT
" does not exit!"
,
scid
);
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
smreq
->
http_response
,
Pistache
::
Http
::
Code
::
Not_Found
);
return
;
}
//Step 2. store supi, dnn, nssai in itti_n11_update_sm_context_request to be processed later on
supi64_t
supi64
=
smf_supi_to_u64
(
scf
.
get
()
->
supi
);
smreq
->
req
.
set_supi
(
scf
.
get
()
->
supi
);
smreq
->
req
.
set_dnn
(
scf
.
get
()
->
dnn
);
smreq
->
req
.
set_snssai
(
scf
.
get
()
->
nssai
);
smreq
->
req
.
set_pdu_session_id
(
scf
.
get
()
->
pdu_session_id
);
//Step 2. find the smf context
std
::
shared_ptr
<
smf_context
>
sc
=
{
};
if
(
is_supi_2_smf_context
(
supi64
))
{
sc
=
supi_2_smf_context
(
supi64
);
Logger
::
smf_app
().
debug
(
"Retrieve SMF context with SUPI "
SUPI_64_FMT
""
,
supi64
);
}
else
{
//send PDUSession_SMReleaseContext Response to AMF
Logger
::
smf_app
().
warn
(
"Received PDU Session Release SM Context Request with Supi "
SUPI_64_FMT
"couldn't retrieve the corresponding SMF context, ignore message!"
,
supi64
);
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
smreq
->
http_response
,
Pistache
::
Http
::
Code
::
Not_Found
);
return
;
}
//get dnn context
std
::
shared_ptr
<
dnn_context
>
sd
=
{
};
if
(
!
sc
.
get
()
->
find_dnn_context
(
scf
.
get
()
->
nssai
,
scf
.
get
()
->
dnn
,
sd
))
{
if
(
nullptr
==
sd
.
get
())
{
//Error, DNN context doesn't exist, send PDUSession_SMUpdateContext Response to AMF
Logger
::
smf_app
().
warn
(
"Received PDU Session Release SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!"
);
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
smreq
->
http_response
,
Pistache
::
Http
::
Code
::
Not_Found
);
return
;
}
}
//Step 3. handle the message in smf_context
sc
.
get
()
->
handle_pdu_session_release_sm_context_request
(
smreq
);
}
//------------------------------------------------------------------------------
void
smf_app
::
handle_network_requested_pdu_session_modification
()
{
std
::
shared_ptr
<
itti_nx_modify_pdu_session_request_network_requested
>
itti_msg
=
...
...
src/smf_app/smf_app.hpp
View file @
0d1c5fd6
...
...
@@ -209,6 +209,14 @@ class smf_app {
void
handle_pdu_session_update_sm_context_request
(
std
::
shared_ptr
<
itti_n11_update_sm_context_request
>
smreq
);
/*
* Handle PDUSession_ReleaseSMContextRequest from AMF
* @param [std::shared_ptr<itti_n11_release_sm_context_request>&] Request message
* @return void
*/
void
handle_pdu_session_release_sm_context_request
(
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
smreq
);
/*
* Handle network-requested pdu session modification
* @param should be updated
...
...
src/smf_app/smf_context.cpp
View file @
0d1c5fd6
...
...
@@ -2269,6 +2269,64 @@ void smf_context::handle_pdu_session_update_sm_context_request(
}
//-------------------------------------------------------------------------------------
void
smf_context
::
handle_pdu_session_release_sm_context_request
(
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
smreq
)
{
Logger
::
smf_app
().
info
(
"Handle a PDU Session Release SM Context Request message from AMF"
);
bool
update_upf
=
false
;
//Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and pdu_session must be existed
std
::
shared_ptr
<
dnn_context
>
sd
=
{
};
std
::
shared_ptr
<
smf_pdu_session
>
sp
=
{
};
bool
find_dnn
=
find_dnn_context
(
smreq
->
req
.
get_snssai
(),
smreq
->
req
.
get_dnn
(),
sd
);
bool
find_pdu
=
false
;
if
(
find_dnn
)
{
find_pdu
=
sd
.
get
()
->
find_pdu_session
(
smreq
->
req
.
get_pdu_session_id
(),
sp
);
}
if
(
!
find_dnn
or
!
find_pdu
)
{
//error, send reply to AMF with error code "Context Not Found"
Logger
::
smf_app
().
warn
(
"DNN or PDU session context does not exist!"
);
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
smreq
->
http_response
,
Pistache
::
Http
::
Code
::
Not_Found
);
return
;
}
//we need to store HttpResponse and session-related information to be used when receiving the response from UPF
itti_n11_release_sm_context_response
*
n11_sm_context_resp
=
new
itti_n11_release_sm_context_response
(
TASK_SMF_APP
,
TASK_SMF_N11
,
smreq
->
http_response
);
std
::
shared_ptr
<
itti_n11_release_sm_context_response
>
sm_context_resp_pending
=
std
::
shared_ptr
<
itti_n11_release_sm_context_response
>
(
n11_sm_context_resp
);
n11_sm_context_resp
->
res
.
set_supi
(
smreq
->
req
.
get_supi
());
n11_sm_context_resp
->
res
.
set_supi_prefix
(
smreq
->
req
.
get_supi_prefix
());
n11_sm_context_resp
->
res
.
set_cause
(
REQUEST_ACCEPTED
);
n11_sm_context_resp
->
res
.
set_pdu_session_id
(
smreq
->
req
.
get_pdu_session_id
());
n11_sm_context_resp
->
res
.
set_snssai
(
smreq
->
req
.
get_snssai
());
n11_sm_context_resp
->
res
.
set_dnn
(
smreq
->
req
.
get_dnn
());
session_release_sm_context_procedure
*
proc
=
new
session_release_sm_context_procedure
(
sp
);
std
::
shared_ptr
<
smf_procedure
>
sproc
=
std
::
shared_ptr
<
smf_procedure
>
(
proc
);
insert_procedure
(
sproc
);
if
(
proc
->
run
(
smreq
,
sm_context_resp_pending
,
shared_from_this
()))
{
// error !
Logger
::
smf_app
().
info
(
"PDU Release SM Context Request procedure failed"
);
}
}
//------------------------------------------------------------------------------
void
smf_context
::
insert_dnn_subscription
(
const
snssai_t
&
snssai
,
...
...
src/smf_app/smf_context.hpp
View file @
0d1c5fd6
...
...
@@ -340,7 +340,7 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
void
handle_itti_msg
(
std
::
shared_ptr
<
itti_n4_session_report_request
>&
);
/*
* Handle messages from AMF (e.g., PDU_SESSION_C
REATE
SMContextRequest)
* Handle messages from AMF (e.g., PDU_SESSION_C
reate
SMContextRequest)
* @param [std::shared_ptr<itti_n11_create_sm_context_request] smreq Request message
* @return void
*/
...
...
@@ -348,14 +348,21 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
std
::
shared_ptr
<
itti_n11_create_sm_context_request
>
smreq
);
/*
* Handle messages from AMF (e.g., PDU_SESSION_U
PDATE
SMContextRequest)
* Handle messages from AMF (e.g., PDU_SESSION_U
pdate
SMContextRequest)
* @param [std::shared_ptr<itti_n11_update_sm_context_request] smreq Request message
* @param [pdu_session_procedure_t procedure] pdu session procedure: session establishment/modification/release
* @return void
*/
void
handle_pdu_session_update_sm_context_request
(
std
::
shared_ptr
<
itti_n11_update_sm_context_request
>
smreq
);
/*
* Handle messages from AMF (e.g., PDU_SESSION_ReleaseSMContextRequest)
* @param [std::shared_ptr<itti_n11_release_sm_context_request] smreq Request message
* @return void
*/
void
handle_pdu_session_release_sm_context_request
(
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
smreq
);
/*
* Find DNN context with name
* @param [const std::string&] dnn
...
...
src/smf_app/smf_msg.cpp
View file @
0d1c5fd6
...
...
@@ -556,3 +556,14 @@ void pdu_session_update_sm_context_response::remove_all_qos_flow_context_updated
qos_flow_context_updateds
.
clear
();
}
//-----------------------------------------------------------------------------
void
pdu_session_release_sm_context_response
::
set_cause
(
uint8_t
cause
)
{
m_cause
=
cause
;
}
//-----------------------------------------------------------------------------
uint8_t
pdu_session_release_sm_context_response
::
get_cause
()
{
return
m_cause
;
}
src/smf_app/smf_msg.hpp
View file @
0d1c5fd6
...
...
@@ -51,6 +51,8 @@ typedef enum {
PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE
,
PDU_SESSION_UPDATE_SM_CONTEXT_REQUEST
,
PDU_SESSION_UPDATE_SM_CONTEXT_RESPONSE
,
PDU_SESSION_RELEASE_SM_CONTEXT_REQUEST
,
PDU_SESSION_RELEASE_SM_CONTEXT_RESPONSE
,
PDU_SESSION_MSG_TYPE_MAX
}
pdu_session_msg_type_t
;
...
...
@@ -550,6 +552,34 @@ class pdu_session_update_sm_context_response : public pdu_session_msg {
};
class
pdu_session_release_sm_context_request
:
public
pdu_session_msg
{
public:
pdu_session_release_sm_context_request
()
:
pdu_session_msg
(
PDU_SESSION_RELEASE_SM_CONTEXT_REQUEST
)
{
}
;
private:
};
class
pdu_session_release_sm_context_response
:
public
pdu_session_msg
{
public:
pdu_session_release_sm_context_response
()
:
pdu_session_msg
(
PDU_SESSION_RELEASE_SM_CONTEXT_RESPONSE
)
{
m_cause
=
0
;
}
;
void
set_cause
(
uint8_t
cause
);
uint8_t
get_cause
();
private:
uint8_t
m_cause
;
};
}
#endif
src/smf_app/smf_n11.cpp
View file @
0d1c5fd6
...
...
@@ -474,6 +474,18 @@ void smf_n11::send_pdu_session_update_sm_context_response(
}
break
;
case
session_management_procedures_type_e
:
:
PDU_SESSION_RELEASE_UE_REQUESTED_STEP2
:
{
Logger
::
smf_n11
().
info
(
"PDU_SESSION_RELEASE_UE_REQUESTED (step 2)"
);
sm_context_res
->
http_response
.
send
(
Pistache
::
Http
::
Code
::
No_Content
);
}
break
;
case
session_management_procedures_type_e
:
:
PDU_SESSION_RELEASE_UE_REQUESTED_STEP3
:
{
Logger
::
smf_n11
().
info
(
"PDU_SESSION_RELEASE_UE_REQUESTED (step 3)"
);
sm_context_res
->
http_response
.
send
(
Pistache
::
Http
::
Code
::
No_Content
);
}
break
;
default:
{
Logger
::
smf_n11
().
debug
(
"Session management procedure: unknown!"
);
}
...
...
@@ -592,6 +604,33 @@ void smf_n11::send_n1n2_message_transfer_request(
//TODO:
}
//------------------------------------------------------------------------------
void
smf_n11
::
send_pdu_session_release_sm_context_response
(
Pistache
::
Http
::
ResponseWriter
&
httpResponse
,
Pistache
::
Http
::
Code
code
)
{
Logger
::
smf_n11
().
debug
(
"[SMF N11] Send PDUSessionReleaseContextResponse to AMF!"
);
httpResponse
.
send
(
code
);
}
//------------------------------------------------------------------------------
void
smf_n11
::
send_pdu_session_release_sm_context_response
(
Pistache
::
Http
::
ResponseWriter
&
httpResponse
,
oai
::
smf_server
::
model
::
ProblemDetails
&
problem
,
Pistache
::
Http
::
Code
code
)
{
Logger
::
smf_n11
().
debug
(
"[SMF N11] Send PDUSessionReleaseContextResponse to AMF!"
);
nlohmann
::
json
json_data
=
{
};
to_json
(
json_data
,
problem
);
if
(
!
json_data
.
empty
())
{
httpResponse
.
headers
().
add
<
Pistache
::
Http
::
Header
::
ContentType
>
(
Pistache
::
Http
::
Mime
::
MediaType
(
"application/json"
));
httpResponse
.
send
(
code
,
json_data
.
dump
().
c_str
());
}
else
{
httpResponse
.
send
(
code
);
}
}
//------------------------------------------------------------------------------
void
smf_n11
::
create_multipart_related_content
(
std
::
string
&
body
,
std
::
string
&
json_part
,
...
...
src/smf_app/smf_n11.hpp
View file @
0d1c5fd6
...
...
@@ -152,6 +152,27 @@ class smf_n11 {
oai
::
smf_server
::
model
::
SmContextCreatedData
&
smContextCreatedData
,
Pistache
::
Http
::
Code
code
);
/*
* Send release session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [Pistache::Http::Code] code, response code
*
*/
void
send_pdu_session_release_sm_context_response
(
Pistache
::
Http
::
ResponseWriter
&
httpResponse
,
Pistache
::
Http
::
Code
code
);
/*
* Send release session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [oai::smf_server::model::ProblemDetails] problem
* @param [Pistache::Http::Code] code, response code
*
*/
void
send_pdu_session_release_sm_context_response
(
Pistache
::
Http
::
ResponseWriter
&
httpResponse
,
oai
::
smf_server
::
model
::
ProblemDetails
&
problem
,
Pistache
::
Http
::
Code
code
);
/*
* Create HTTP body content for multipart/related message
* @param [std::string] body: Body of the created message
...
...
src/smf_app/smf_procedure.cpp
View file @
0d1c5fd6
...
...
@@ -1321,3 +1321,86 @@ void session_update_sm_context_procedure::handle_itti_msg(
}
//------------------------------------------------------------------------------
int
session_release_sm_context_procedure
::
run
(
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
sm_context_req
,
std
::
shared_ptr
<
itti_n11_release_sm_context_response
>
sm_context_res
,
std
::
shared_ptr
<
smf
::
smf_context
>
sc
)
{
Logger
::
smf_app
().
info
(
"Release SM Context Request"
);
// TODO check if compatible with ongoing procedures if any
pfcp
::
node_id_t
up_node_id
=
{
};
if
(
not
pfcp_associations
::
get_instance
().
select_up_node
(
up_node_id
,
NODE_SELECTION_CRITERIA_MIN_PFCP_SESSIONS
))
{
// TODO
sm_context_res
->
res
.
set_cause
(
REMOTE_PEER_NOT_RESPONDING
);
//verify for 5G??
Logger
::
smf_app
().
info
(
"REMOTE_PEER_NOT_RESPONDING"
);
return
RETURNerror
;
}
//-------------------
n11_trigger
=
sm_context_req
;
n11_triggered_pending
=
sm_context_res
;
uint64_t
seid
=
smf_app_inst
->
generate_seid
();
sp
->
set_seid
(
seid
);
itti_n4_session_deletion_request
*
n4_ser
=
new
itti_n4_session_deletion_request
(
TASK_SMF_APP
,
TASK_SMF_N4
);
n4_ser
->
seid
=
sp
->
up_fseid
.
seid
;
n4_ser
->
trxn_id
=
this
->
trxn_id
;
n4_ser
->
r_endpoint
=
endpoint
(
up_node_id
.
u1
.
ipv4_address
,
pfcp
::
default_port
);
n4_triggered
=
std
::
shared_ptr
<
itti_n4_session_deletion_request
>
(
n4_ser
);
Logger
::
smf_app
().
info
(
"Sending ITTI message %s to task TASK_SMF_N4"
,
n4_ser
->
get_msg_name
());
int
ret
=
itti_inst
->
send_msg
(
n4_triggered
);
if
(
RETURNok
!=
ret
)
{
Logger
::
smf_app
().
error
(
"Could not send ITTI message %s to task TASK_SMF_N4"
,
n4_ser
->
get_msg_name
());
return
RETURNerror
;
}
return
RETURNok
;
}
//------------------------------------------------------------------------------
void
session_release_sm_context_procedure
::
handle_itti_msg
(
itti_n4_session_deletion_response
&
resp
,
std
::
shared_ptr
<
smf
::
smf_context
>
sc
)
{
Logger
::
smf_app
().
info
(
"Handle itti_n4_session_deletion_response (Release SM Context Request): pdu-session-id %d"
,
n11_trigger
.
get
()
->
req
.
get_pdu_session_id
());
pfcp
::
cause_t
cause
=
{
};
::
cause_t
cause_gtp
=
{
.
cause_value
=
REQUEST_ACCEPTED
};
// must be there
if
(
resp
.
pfcp_ies
.
get
(
cause
))
{
xgpp_conv
::
pfcp_cause_to_core_cause
(
cause
,
cause_gtp
);
}
if
(
cause
.
cause_value
==
CAUSE_VALUE_REQUEST_ACCEPTED
)
{
Logger
::
smf_app
().
info
(
"PDU Session Release SM Context accepted by UPF"
);
//clear the resources including addresses allocated to this Session and associated QoS flows
sp
->
deallocate_ressources
(
n11_trigger
.
get
()
->
req
.
get_dnn
());
//TODO: for IPv6 (only for Ipv4 for the moment)
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
n11_triggered_pending
->
http_response
,
Pistache
::
Http
::
Code
::
No_Content
);
}
else
{
oai
::
smf_server
::
model
::
ProblemDetails
problem_details
=
{
};
problem_details
.
setCause
(
pdu_session_application_error_e2str
[
PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE
]);
//To be updated
smf_n11_inst
->
send_pdu_session_release_sm_context_response
(
n11_triggered_pending
->
http_response
,
Pistache
::
Http
::
Code
::
Not_Acceptable
);
}
//TODO:
/* If it is the last PDU Session the SMF is handling for the UE for the associated (DNN, S-
NSSAI), the SMF unsubscribes from Session Management Subscription data changes notification with the UDM
by means of the Nudm_SDM_Unsubscribe service operation. The SMF invokes the
Nudm_UECM_Deregistration service operation so that the UDM removes the association it had stored between
the SMF identity and the associated DNN and PDU Session Id
*/
}
src/smf_app/smf_procedure.hpp
View file @
0d1c5fd6
...
...
@@ -173,21 +173,20 @@ class session_update_sm_context_procedure : public smf_procedure {
//------------------------------------------------------------------------------
class
session_release_
pdu_session
_procedure
:
public
smf_procedure
{
class
session_release_
sm_context
_procedure
:
public
smf_procedure
{
public:
explicit
session_release_
pdu_session
_procedure
(
std
::
shared_ptr
<
smf_pdu_session
>
&
sp
pc
)
explicit
session_release_
sm_context
_procedure
(
std
::
shared_ptr
<
smf_pdu_session
>
&
sp
s
)
:
smf_procedure
(),
ppc
(
sppc
),
sp
(
sps
),
n4_triggered
(),
n11_triggered_pending
(),
n11_trigger
(),
session_procedure_type
()
{
n11_trigger
()
{
}
int
run
(
std
::
shared_ptr
<
itti_n11_
updat
e_sm_context_request
>
req
,
std
::
shared_ptr
<
itti_n11_
updat
e_sm_context_response
>
resp
,
int
run
(
std
::
shared_ptr
<
itti_n11_
releas
e_sm_context_request
>
req
,
std
::
shared_ptr
<
itti_n11_
releas
e_sm_context_response
>
resp
,
std
::
shared_ptr
<
smf
::
smf_context
>
sc
);
/*
* Handle N4 modification response from UPF
...
...
@@ -195,16 +194,15 @@ class session_release_pdu_session_procedure : public smf_procedure {
* @param [std::shared_ptr<smf::smf_context>] sc smf context
* @return void
*/
void
handle_itti_msg
(
itti_n4_session_
modifica
tion_response
&
resp
,
void
handle_itti_msg
(
itti_n4_session_
dele
tion_response
&
resp
,
std
::
shared_ptr
<
smf
::
smf_context
>
sc
);
std
::
shared_ptr
<
itti_n4_session_
modifica
tion_request
>
n4_triggered
;
std
::
shared_ptr
<
smf_pdu_session
>
ppc
;
std
::
shared_ptr
<
smf
::
smf_context
>
p
c
;
std
::
shared_ptr
<
itti_n4_session_
dele
tion_request
>
n4_triggered
;
std
::
shared_ptr
<
smf_pdu_session
>
sp
;
std
::
shared_ptr
<
smf
::
smf_context
>
s
c
;
std
::
shared_ptr
<
itti_n11_update_sm_context_request
>
n11_trigger
;
std
::
shared_ptr
<
itti_n11_update_sm_context_response
>
n11_triggered_pending
;
session_management_procedures_type_e
session_procedure_type
;
std
::
shared_ptr
<
itti_n11_release_sm_context_request
>
n11_trigger
;
std
::
shared_ptr
<
itti_n11_release_sm_context_response
>
n11_triggered_pending
;
};
...
...
src/test/amf_client/amf-client.cpp
View file @
0d1c5fd6
...
...
@@ -383,13 +383,12 @@ void send_pdu_session_update_sm_context_establishment(
free
(
buffer
);
}
//------------------------------------------------------------------------------
void
send_pdu_session_modification_request_step1
(
std
::
string
smf_ip_address
)
{
std
::
cout
<<
"[AMF N11] PDU Session Modification Request (SM Context Update, Step 1)"
<<
std
::
endl
;
std
::
cout
<<
"[AMF N11] PDU Session Modification Request (SM Context Update, Step 1)"
<<
std
::
endl
;
nlohmann
::
json
pdu_session_modification_request
;
//encode PDU Session Modification Request
...
...
@@ -403,28 +402,27 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//PDUSessionIdentity
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//ProcedureTransactionIdentity
ENCODE_U8
(
buffer
+
size
,
0xc9
,
size
);
//MessageType - PDU Session Modification Request
ENCODE_U8
(
buffer
+
size
,
0x28
,
size
);
//_5GSMCapability
ENCODE_U8
(
buffer
+
size
,
0x28
,
size
);
//_5GSMCapability
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//_5GSMCapability
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//_5GSMCapability
ENCODE_U8
(
buffer
+
size
,
0x59
,
size
);
//_5GSMCause
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//_5GSMCause
ENCODE_U8
(
buffer
+
size
,
0x7a
,
size
);
//QoS Rules IE
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//QoS Rules length
ENCODE_U8
(
buffer
+
size
,
0x09
,
size
);
//QoS Rules length
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules rule id
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//QoS Rules rule length
ENCODE_U8
(
buffer
+
size
,
0x06
,
size
);
//QoS Rules rule length
ENCODE_U8
(
buffer
+
size
,
0x31
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x31
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules filter 1 length
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x3c
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//_5GSMCause
ENCODE_U8
(
buffer
+
size
,
0x7a
,
size
);
//QoS Rules IE
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//QoS Rules length
ENCODE_U8
(
buffer
+
size
,
0x09
,
size
);
//QoS Rules length
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules rule id
ENCODE_U8
(
buffer
+
size
,
0x00
,
size
);
//QoS Rules rule length
ENCODE_U8
(
buffer
+
size
,
0x06
,
size
);
//QoS Rules rule length
ENCODE_U8
(
buffer
+
size
,
0x31
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x31
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules filter 1 length
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x01
,
size
);
//QoS Rules
ENCODE_U8
(
buffer
+
size
,
0x3c
,
size
);
//QoS Rules
// ENCODE_U8(buffer + size, 0x00, size); //MaximumNumberOfSupportedPacketFilters
// ENCODE_U8(buffer + size, 0x01, size); //MaximumNumberOfSupportedPacketFilters
std
::
cout
<<
"Buffer: "
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
printf
(
"%02x "
,
buffer
[
i
]);
...
...
@@ -498,8 +496,6 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
free
(
buffer
);
}
//------------------------------------------------------------------------------
void
send_pdu_session_release_request
(
std
::
string
smf_ip_address
)
{
...
...
@@ -594,8 +590,7 @@ void send_pdu_session_release_request(std::string smf_ip_address) {
}
//------------------------------------------------------------------------------
void
send_pdu_session_release_resource_release_ack
(
std
::
string
smf_ip_address
)
{
void
send_pdu_session_release_resource_release_ack
(
std
::
string
smf_ip_address
)
{
std
::
cout
<<
"[AMF N11] PDU Session Release Ack (Update SM Context): N2 SM - Resource Release Ack"
...
...
@@ -777,14 +772,12 @@ void send_pdu_session_release_complete(std::string smf_ip_address) {
free
(
buffer
);
}
//------------------------------------------------------------------------------
void
send_pdu_session_update_sm_context_ue_service_request
(
std
::
string
smf_ip_address
)
{
std
::
cout
<<
"[AMF N11] UE-triggered Service Request (SM Context Update Step 1)"
<<
std
::
endl
;
std
::
cout
<<
"[AMF N11] UE-triggered Service Request (SM Context Update Step 1)"
<<
std
::
endl
;
nlohmann
::
json
service_requests
;
//NO NAS, No NGAP
...
...
@@ -808,8 +801,7 @@ void send_pdu_session_update_sm_context_ue_service_request(
CURLcode
res
=
{
};
struct
curl_slist
*
headers
=
nullptr
;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers
=
curl_slist_append
(
headers
,
"content-type: application/json"
);
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
);
...
...
@@ -847,12 +839,12 @@ void send_pdu_session_update_sm_context_ue_service_request(
}
//------------------------------------------------------------------------------
void
send_pdu_session_update_sm_context_ue_service_request_step2
(
std
::
string
smf_ip_address
)
{
std
::
cout
<<
"[AMF N11] UE-triggered Service Request (SM Context Update Step 2)"
<<
std
::
endl
;
std
::
cout
<<
"[AMF N11] UE-triggered Service Request (SM Context Update Step 2)"
<<
std
::
endl
;
nlohmann
::
json
service_requests
;
//encode PDU Session Resource Setup Response Transfer IE
...
...
@@ -898,7 +890,6 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
service_requests
[
"anType"
]
=
"3GPP_ACCESS"
;
service_requests
[
"ratType"
]
=
"NR"
;
std
::
string
body
;
std
::
string
boundary
=
"----Boundary"
;
std
::
string
json_part
=
service_requests
.
dump
();
...
...
@@ -962,6 +953,66 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
free
(
buffer
);
}
//------------------------------------------------------------------------------
void
send_release_sm_context_request
(
std
::
string
smf_ip_address
)
{
std
::
cout
<<
"[AMF N11] PDU Session Release SM context Request"
<<
std
::
endl
;
nlohmann
::
json
send_release_sm_context_request
;
std
::
string
url
=
std
::
string
(
"http://"
);
url
.
append
(
smf_ip_address
);
url
.
append
(
std
::
string
(
"/nsmf-pdusession/v2/sm-contexts/1/release"
));
//Fill the json part
send_release_sm_context_request
[
"pduSessionId"
]
=
1
;
std
::
string
body
=
send_release_sm_context_request
.
dump
();
curl_global_init
(
CURL_GLOBAL_ALL
);
CURL
*
curl
=
curl
=
curl_easy_init
();
if
(
curl
)
{
CURLcode
res
=
{
};
struct
curl_slist
*
headers
=
nullptr
;
//headers = curl_slist_append(headers, "charsets: utf-8");
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
,
100L
);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
// 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
);
//get cause from the response
nlohmann
::
json
response_data
;
try
{
response_data
=
nlohmann
::
json
::
parse
(
*
httpData
.
get
());
}
catch
(
nlohmann
::
json
::
exception
&
e
)
{
std
::
cout
<<
"Could not get json data from the response"
<<
std
::
endl
;
}
std
::
cout
<<
"[AMF N11] PDU Session Release SM Context Request, response from SMF, Http Code "
<<
httpCode
<<
std
::
endl
;
curl_easy_cleanup
(
curl
);
}
curl_global_cleanup
();
}
//------------------------------------------------------------------------------
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
@@ -1010,6 +1061,9 @@ int main(int argc, char *argv[]) {
usleep
(
200000
);
send_pdu_session_release_complete
(
smf_ip_address
);
usleep
(
200000
);
//Release SM context
send_release_sm_context_request
(
smf_ip_address
);
return
0
;
}
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