Commit 4ce48382 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen
Browse files

update SMF client/SMF_n11 to display correctly N1/N2 messages in wireshark

parent c98c86ee
......@@ -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.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment