Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
oai-cn5g-smf
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
oai
cn5g
oai-cn5g-smf
Commits
4ce48382
Commit
4ce48382
authored
4 years ago
by
Tien-Thinh Nguyen
Browse files
Options
Downloads
Patches
Plain Diff
update SMF client/SMF_n11 to display correctly N1/N2 messages in wireshark
parent
c98c86ee
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!6
Bug fixes for BUPT
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/smf_app/smf_n11.cpp
+159
-123
159 additions, 123 deletions
src/smf_app/smf_n11.cpp
src/test/amf_client/amf-client.cpp
+423
-325
423 additions, 325 deletions
src/test/amf_client/amf-client.cpp
with
582 additions
and
448 deletions
src/smf_app/smf_n11.cpp
+
159
−
123
View file @
4ce48382
...
...
@@ -44,6 +44,10 @@
#include
"smf_config.hpp"
#include
"smf_n1_n2.hpp"
extern
"C"
{
#include
"dynamic_memory_check.h"
}
using
namespace
Pistache
::
Http
;
using
namespace
Pistache
::
Http
::
Mime
;
...
...
@@ -124,152 +128,63 @@ void smf_n11::send_n1n2_message_transfer_request(
std
::
shared_ptr
<
itti_n11_create_sm_context_response
>
sm_context_res
)
{
//Transfer N1/N2 message via AMF by using N_amf_Communication_N1N2MessageTransfer (see TS29518_Namf_Communication.yaml)
//TODO: use RestSDK for client, use curl to send data for the moment
Logger
::
smf_n11
().
debug
(
"Send Communication_N1N2MessageTransfer to AMF"
);
smf_n1_n2
smf_n1_n2_inst
=
{
};
std
::
string
n1_message
=
sm_context_res
->
res
.
get_n1_sm_message
();
std
::
string
json_part
=
sm_context_res
->
res
.
n1n2_message_transfer_data
.
dump
();
std
::
string
boundary
=
"----Boundary"
;
std
::
string
body
;
pdu_session_create_sm_context_response
context_res_msg
=
sm_context_res
->
res
;
std
::
string
n1_message
=
context_res_msg
.
get_n1_sm_message
();
/*
ENABLE THIS TO TEST NAS PDU SESSION ESTABLISHMENT ACCEPT
Don't forget to disable Http_response in SMF CONTEXT
std::string json_part = context_res_msg.n1n2_message_transfer_data.dump();
std::string boundary = "----Boundary";
std::string body;
create_multipart_related_content(body, json_part, boundary, n1_message, multipart_related_content_part_e::NAS);
sm_context_res->http_response.headers().add<Pistache::Http::Header::ContentType>(Pistache::Http::Mime::MediaType("multipart/related; boundary=" + boundary));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
*/
/*
//format string as hex
unsigned char *msg_hex = smf_app_inst->format_string_as_hex(n1_message);
string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
body.append("--" + boundary + CRLF);
//NAS
body.append("Content-Type: application/vnd.3gpp.5gnas"+ CRLF + "Content-Id: n1SmMsg" + CRLF);
body.append(CRLF);
body.append(std::string((char *)msg_hex, n1_message.length()/2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related; boundary=----Boundary");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, context_res_msg.get_amf_url().c_str() );
curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:sn11"); //Only for testing in all-in-one scenario
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
curl_global_cleanup();
//add N2 content if available
auto
n2_sm_found
=
sm_context_res
->
res
.
n1n2_message_transfer_data
.
count
(
"n2InfoContainer"
);
if
(
n2_sm_found
>
0
)
{
std
::
string
n2_message
=
sm_context_res
->
res
.
get_n2_sm_information
();
//prepare the body content for Curl
create_multipart_related_content
(
body
,
json_part
,
boundary
,
n1_message
,
n2_message
);
}
else
{
//prepare the body content for Curl
create_multipart_related_content
(
body
,
json_part
,
boundary
,
n1_message
,
multipart_related_content_part_e
::
NAS
);
}
*/
//format string as hex
unsigned
char
*
n1_msg_hex
=
smf_app_inst
->
format_string_as_hex
(
n1_message
);
unsigned
int
str_len
=
body
.
length
();
char
*
data
=
(
char
*
)
malloc
(
str_len
+
1
);
memset
(
data
,
0
,
str_len
+
1
);
memcpy
((
void
*
)
data
,
(
void
*
)
body
.
c_str
(),
str_len
);
curl_global_init
(
CURL_GLOBAL_ALL
);
CURL
*
curl
=
curl_easy_init
();
//N1N2MessageTransfer Notification URI??
std
::
string
json_part
=
context_res_msg
.
n1n2_message_transfer_data
.
dump
();
Logger
::
smf_n11
().
debug
(
"Sending message to AMF...."
);
if
(
curl
)
{
CURLcode
res
=
{
};
struct
curl_slist
*
headers
=
nullptr
;
struct
curl_slist
*
slist
=
nullptr
;
curl_mime
*
mime
;
curl_mime
*
alt
;
curl_mimepart
*
part
;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers
=
curl_slist_append
(
headers
,
"content-type: multipart/related"
);
headers
=
curl_slist_append
(
headers
,
"content-type: multipart/related; boundary=----Boundary"
);
//TODO: update Boundary
curl_easy_setopt
(
curl
,
CURLOPT_HTTPHEADER
,
headers
);
curl_easy_setopt
(
curl
,
CURLOPT_URL
,
context_res_msg
.
get_amf_url
().
c_str
());
curl_easy_setopt
(
curl
,
CURLOPT_URL
,
sm_context_res
->
res
.
get_amf_url
().
c_str
());
curl_easy_setopt
(
curl
,
CURLOPT_HTTPGET
,
1
);
curl_easy_setopt
(
curl
,
CURLOPT_TIMEOUT_MS
,
AMF_CURL_TIMEOUT_MS
);
curl_easy_setopt
(
curl
,
CURLOPT_INTERFACE
,
smf_cfg
.
sbi
.
if_name
.
c_str
());
mime
=
curl_mime_init
(
curl
);
alt
=
curl_mime_init
(
curl
);
//part with N1N2MessageTransferReqData (JsonData)
part
=
curl_mime_addpart
(
mime
);
curl_mime_data
(
part
,
json_part
.
c_str
(),
CURL_ZERO_TERMINATED
);
curl_mime_type
(
part
,
"application/json"
);
//N1 SM Container
Logger
::
smf_n11
().
debug
(
"Add N1 SM Container (NAS) into the message: %s (bytes %d)"
,
context_res_msg
.
get_n1_sm_message
().
c_str
(),
context_res_msg
.
get_n1_sm_message
().
length
()
/
2
);
part
=
curl_mime_addpart
(
mime
);
curl_mime_data
(
part
,
reinterpret_cast
<
const
char
*>
(
n1_msg_hex
),
context_res_msg
.
get_n1_sm_message
().
length
()
/
2
);
curl_mime_type
(
part
,
"application/vnd.3gpp.5gnas"
);
curl_mime_name
(
part
,
context_res_msg
.
n1n2_message_transfer_data
[
"n1MessageContainer"
][
"n1MessageContent"
][
"contentId"
]
.
dump
().
c_str
());
auto
n2_sm_found
=
context_res_msg
.
n1n2_message_transfer_data
.
count
(
"n2InfoContainer"
);
if
(
n2_sm_found
>
0
)
{
std
::
string
n2_message
=
context_res_msg
.
get_n2_sm_information
();
unsigned
char
*
n2_msg_hex
=
smf_app_inst
->
format_string_as_hex
(
n2_message
);
Logger
::
smf_n11
().
debug
(
"Add N2 SM Information (NGAP) into the message: %s (bytes %d)"
,
n2_message
.
c_str
(),
n2_message
.
length
()
/
2
);
part
=
curl_mime_addpart
(
mime
);
curl_mime_data
(
part
,
reinterpret_cast
<
const
char
*>
(
n2_msg_hex
),
80
);
//TODO: n2_message.length()/2 ISSUE need to be solved
curl_mime_type
(
part
,
"application/vnd.3gpp.ngap"
);
curl_mime_name
(
part
,
context_res_msg
.
n1n2_message_transfer_data
[
"n2InfoContainer"
][
"smInfo"
][
"n2InfoContent"
][
"ngapData"
][
"contentId"
]
.
dump
().
c_str
());
}
curl_easy_setopt
(
curl
,
CURLOPT_MIMEPOST
,
mime
);
// Response information.
long
httpCode
=
{
0
};
std
::
unique_ptr
<
std
::
string
>
httpData
(
new
std
::
string
());
// Hook up data handling function
.
// Hook up data handling function
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
,
data
);
res
=
curl_easy_perform
(
curl
);
curl_easy_getinfo
(
curl
,
CURLINFO_RESPONSE_CODE
,
&
httpCode
);
//get cause from the response
...
...
@@ -291,7 +206,7 @@ void smf_n11::send_n1n2_message_transfer_request(
itti_msg
->
set_response_code
(
httpCode
);
itti_msg
->
set_scid
(
sm_context_res
->
scid
);
itti_msg
->
set_cause
(
response_data
[
"cause"
]);
if
(
context_res
_msg
.
get_cause
()
==
REQUEST_ACCEPTED
)
{
if
(
sm_
context_res
->
res
.
get_cause
()
==
REQUEST_ACCEPTED
)
{
itti_msg
->
set_msg_type
(
PDU_SESSION_ESTABLISHMENT_ACCEPT
);
}
else
{
itti_msg
->
set_msg_type
(
PDU_SESSION_ESTABLISHMENT_REJECT
);
...
...
@@ -308,9 +223,130 @@ void smf_n11::send_n1n2_message_transfer_request(
curl_slist_free_all
(
headers
);
curl_easy_cleanup
(
curl
);
curl_mime_free
(
mime
);
}
curl_global_cleanup
();
free_wrapper
((
void
**
)
&
data
);
/*
//Curl MIME
//format string as hex
unsigned char *n1_msg_hex = smf_app_inst->format_string_as_hex(n1_message);
CURL *curl = curl_easy_init();
//N1N2MessageTransfer Notification URI??
std::string json_part = context_res_msg.n1n2_message_transfer_data.dump();
Logger::smf_n11().debug("Sending message to AMF....");
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
struct curl_slist *slist = nullptr;
curl_mime *mime;
curl_mime *alt;
curl_mimepart *part;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: multipart/related");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, context_res_msg.get_amf_url().c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, smf_cfg.sbi.if_name.c_str());
mime = curl_mime_init(curl);
alt = curl_mime_init(curl);
//part with N1N2MessageTransferReqData (JsonData)
part = curl_mime_addpart(mime);
curl_mime_data(part, json_part.c_str(), CURL_ZERO_TERMINATED);
curl_mime_type(part, "application/json");
//N1 SM Container
Logger::smf_n11().debug(
"Add N1 SM Container (NAS) into the message: %s (bytes %d)",
context_res_msg.get_n1_sm_message().c_str(),
context_res_msg.get_n1_sm_message().length() / 2);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n1_msg_hex),
context_res_msg.get_n1_sm_message().length() / 2);
curl_mime_type(part, "application/vnd.3gpp.5gnas");
curl_mime_name(
part,
context_res_msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"]
.dump().c_str());
auto n2_sm_found = context_res_msg.n1n2_message_transfer_data.count(
"n2InfoContainer");
if (n2_sm_found > 0) {
std::string n2_message = context_res_msg.get_n2_sm_information();
unsigned char *n2_msg_hex = smf_app_inst->format_string_as_hex(
n2_message);
Logger::smf_n11().debug(
"Add N2 SM Information (NGAP) into the message: %s (bytes %d)",
n2_message.c_str(), n2_message.length() / 2);
part = curl_mime_addpart(mime);
curl_mime_data(part, reinterpret_cast<const char*>(n2_msg_hex), 80); //TODO: n2_message.length()/2 ISSUE need to be solved
curl_mime_type(part, "application/vnd.3gpp.ngap");
curl_mime_name(
part,
context_res_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"]
.dump().c_str());
}
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
//get cause from the response
json response_data = { };
try {
response_data = json::parse(*httpData.get());
} catch (json::exception &e) {
Logger::smf_n11().error("Could not get the cause from the response");
//Set the default Cause
response_data["cause"] = "504 Gateway Timeout";
}
Logger::smf_n11().debug("Response from AMF, Http Code: %d, cause %s",
httpCode, response_data["cause"].dump().c_str());
//send response to APP to process
itti_n11_n1n2_message_transfer_response_status *itti_msg =
new itti_n11_n1n2_message_transfer_response_status(TASK_SMF_N11,
TASK_SMF_APP);
itti_msg->set_response_code(httpCode);
itti_msg->set_scid(sm_context_res->scid);
itti_msg->set_cause(response_data["cause"]);
if (context_res_msg.get_cause() == REQUEST_ACCEPTED) {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_ACCEPT);
} else {
itti_msg->set_msg_type(PDU_SESSION_ESTABLISHMENT_REJECT);
}
std::shared_ptr<itti_n11_n1n2_message_transfer_response_status> i =
std::shared_ptr<itti_n11_n1n2_message_transfer_response_status>(
itti_msg);
int ret = itti_inst->send_msg(i);
if (RETURNok != ret) {
Logger::smf_n11().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
i->get_msg_name());
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_mime_free(mime);
}
*/
}
//------------------------------------------------------------------------------
...
...
This diff is collapsed.
Click to expand it.
src/test/amf_client/amf-client.cpp
+
423
−
325
View file @
4ce48382
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment