Commit 0aa531ee authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

first version for HTTP2 support

parent 89d041b9
......@@ -87,7 +87,7 @@ cd /openair-cn-cups/build/scripts
#configure SPGWU using an example configure file (spgw_u.conf)
cd /oai-cn5g-smf/src/test/upf/
./spgwu_conf.sh
sudo spgwu -c /usr/local/etc/oai/spgw_u.conf -o
sudo spgwu -c /usr/local/etc/oai/spgw_u.conf
## Build and launch AMF client
......@@ -98,4 +98,8 @@ cmake ..
make
./amf-client -i 172.16.1.101
#Launch AMF client with HTTP2 (-v: http version, -p: port)
./amf-client -i 172.16.1.101 -v 2 -p 9090
......@@ -36,9 +36,10 @@ SMF =
{
# SMF binded interface for SBI interface (e.g., communication with AMF, UDM)
INTERFACE_NAME = "@SMF_INTERFACE_NAME_FOR_SBI@"; # STRING, interface name
#IPV4_ADDRESS = "@SMF_INTERFACE_IPV4_ADDRESS_FOR_SBI@"; # STRING, CIDR or "read" to let app read interface configured IP address
#IPV4_ADDRESS = "@SMF_INTERFACE_IPV4_ADDRESS_FOR_SBI@"; # STRING, CIDR or "read" to let app read interface configured IP address
IPV4_ADDRESS = "read";
PORT = @SMF_INTERFACE_PORT_FOR_SBI@ #Normally we don't need this (default port 80)
HTTP2_PORT = @SMF_INTERFACE_HTTP2_PORT_FOR_SBI@
};
TEST_UPF : #for BUPT test only!
......
cmake_minimum_required (VERSION 3.2)
project(smf-api-server)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pg -g3" )
include_directories(model)
include_directories(api)
include_directories(impl)
file(GLOB SRCS
${CMAKE_CURRENT_SOURCE_DIR}/api/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/model/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)
add_executable(${PROJECT_NAME} ${SRCS} )
target_link_libraries(${PROJECT_NAME} pistache pthread)
......@@ -43,7 +43,7 @@
#include "logger.hpp"
#include "Helpers.h"
#include "simple_parser.hpp"
#include "mime_parser.hpp"
namespace oai {
namespace smf_server {
......@@ -103,7 +103,6 @@ void IndividualSMContextApi::release_sm_context_handler(
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void IndividualSMContextApi::retrieve_sm_context_handler(
......@@ -141,7 +140,7 @@ void IndividualSMContextApi::update_sm_context_handler(
SmContextUpdateMessage smContextUpdateMessage = { };
//simple parser
simple_parser sp = { };
mime_parser sp = { };
sp.parse(request.body());
std::vector<mime_part> parts = { };
......
......@@ -43,11 +43,7 @@
#include "logger.hpp"
#include "Helpers.h"
#include "simple_parser.hpp"
extern "C" {
#include "dynamic_memory_check.h"
}
#include "mime_parser.hpp"
namespace oai {
namespace smf_server {
......@@ -90,7 +86,7 @@ void SMContextsCollectionApi::post_sm_contexts_handler(
SmContextCreateData smContextCreateData = { };
//simple parser
simple_parser sp = { };
mime_parser sp = { };
sp.parse(request.body());
std::vector<mime_part> parts = { };
......@@ -99,7 +95,7 @@ void SMContextsCollectionApi::post_sm_contexts_handler(
Logger::smf_api_server().debug("Number of MIME parts %d", size);
//at least 2 parts for Json data and N1 (+ N2)
if (size < 2) {
response.send(Pistache::Http::Code::Bad_Request, "");
response.send(Pistache::Http::Code::Bad_Request);
return;
}
......@@ -107,14 +103,16 @@ void SMContextsCollectionApi::post_sm_contexts_handler(
try {
nlohmann::json::parse(parts[0].body.c_str()).get_to(smContextCreateData);
smContextMessage.setJsonData(smContextCreateData);
//must include N1 NAS msg
if (parts[1].content_type.compare("application/vnd.3gpp.5gnas") == 0) {
smContextMessage.setBinaryDataN1SmMessage(parts[1].body);
} else if (parts[1].content_type.compare("application/vnd.3gpp.ngap")
== 0) {
smContextMessage.setBinaryDataN2SmInformation(parts[1].body);
} else {
response.send(Pistache::Http::Code::Bad_Request);
return;
}
this->post_sm_contexts(smContextMessage, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
Logger::smf_api_server().warn("Can not parse the json data (error: %s)!",
......
......@@ -32,6 +32,8 @@
*/
#include "IndividualSMContextApiImpl.h"
#include <nghttp2/asio_http2_server.h>
#include "mime_parser.hpp"
namespace oai {
namespace smf_server {
......@@ -56,18 +58,35 @@ void IndividualSMContextApiImpl::release_sm_context(
//TODO: to be updated as update_sm_context_handler
Logger::smf_api_server().info("release_sm_context...");
boost::shared_ptr<boost::promise<smf::pdu_session_release_sm_context_response> > p =
boost::make_shared<
boost::promise<smf::pdu_session_release_sm_context_response> >();
boost::shared_future<smf::pdu_session_release_sm_context_response> f;
f = p->get_future();
//Generate ID for this promise (to be used in SMF-APP)
uint32_t promise_id = generate_promise_id();
Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
m_smf_app->add_promise(promise_id, p);
//handle Nsmf_PDUSession_UpdateSMContext Request
Logger::smf_api_server().info(
"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);
TASK_SMF_APP,
promise_id,
smContextRef);
itti_msg->scid = smContextRef;
itti_msg->http_version = 1;
m_smf_app->handle_pdu_session_release_sm_context_request(itti_msg);
//wait for the result from APP and send reply to AMF
smf::pdu_session_release_sm_context_response sm_context_response = f.get();
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
response.send(Pistache::Http::Code(sm_context_response.get_http_code()));
}
void IndividualSMContextApiImpl::retrieve_sm_context(
......@@ -96,7 +115,7 @@ void IndividualSMContextApiImpl::update_sm_context(
//N2 SM (for Session establishment)
std::string n2_sm_information = smContextUpdateMessage
.getBinaryDataN2SmInformation();
Logger::smf_api_server().debug("smContextMessage, n2 sm information %s",
Logger::smf_api_server().debug("N2 SM Information %s",
n2_sm_information.c_str());
std::string n2_sm_info_type = smContextUpdateData.getN2SmInfoType();
sm_context_req_msg.set_n2_sm_information(n2_sm_information);
......@@ -106,8 +125,7 @@ void IndividualSMContextApiImpl::update_sm_context(
//N1 SM (for session modification)
std::string n1_sm_message =
smContextUpdateMessage.getBinaryDataN1SmMessage();
Logger::smf_api_server().debug("smContextMessage, n1 sm message %s",
n1_sm_message.c_str());
Logger::smf_api_server().debug("N1 SM message %s", n1_sm_message.c_str());
sm_context_req_msg.set_n1_sm_message(n1_sm_message);
}
//Step 2. TODO: initialize necessary values for sm context req from smContextUpdateData
......@@ -135,7 +153,6 @@ void IndividualSMContextApiImpl::update_sm_context(
//TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF ID, Request Type, N1 SM Container (PDU Session Establishment Request), User location, Access Type, RAT Type, PEI
//step 15. (SM Context ID -> SCID, N2 SM, Request Type)(Initial Request)
//TODO: verify why Request Type is not define in smContextUpdateData
/* AMF-initiated with a release indication to request the release of the PDU Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/
if (smContextUpdateData.releaseIsSet()) {
sm_context_req_msg.set_release(smContextUpdateData.isRelease());
......@@ -146,18 +163,72 @@ void IndividualSMContextApiImpl::update_sm_context(
//step 1.e (AN initiated modification): SM Context ID, N2 SM information (QFI, User location Information and an indication that the QoS Flow is released)
//step 7a, SM Context ID, N2 SM information, UE location information
//Step 11, SM Context ID, N1 SM (PDU Session Modification Command ACK), User location
boost::shared_ptr<boost::promise<smf::pdu_session_update_sm_context_response> > p =
boost::make_shared<
boost::promise<smf::pdu_session_update_sm_context_response> >();
boost::shared_future<smf::pdu_session_update_sm_context_response> f;
f = p->get_future();
//Generate ID for this promise (to be used in SMF-APP)
uint32_t promise_id = generate_promise_id();
Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
m_smf_app->add_promise(promise_id, p);
//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,
promise_id,
smContextRef);
itti_msg->req = sm_context_req_msg;
itti_msg->scid = smContextRef;
itti_msg->http_version = 1;
m_smf_app->handle_pdu_session_update_sm_context_request(itti_msg);
}
//wait for the result from APP and send reply to AMF
smf::pdu_session_update_sm_context_response sm_context_response = f.get();
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
nlohmann::json json_data = { };
mime_parser parser = { };
std::string body = { };
sm_context_response.get_json_data(json_data);
Logger::smf_api_server().debug("Json data %s", json_data.dump().c_str());
if (sm_context_response.n1_sm_msg_is_set()
and sm_context_response.n2_sm_info_is_set()) {
parser.create_multipart_related_content(
body, json_data.dump(), CURL_MIME_BOUNDARY,
sm_context_response.get_n1_sm_message(),
sm_context_response.get_n2_sm_information());
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
} else if (sm_context_response.n1_sm_msg_is_set()) {
parser.create_multipart_related_content(
body, json_data.dump(), CURL_MIME_BOUNDARY,
sm_context_response.get_n1_sm_message(),
multipart_related_content_part_e::NAS);
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
} else if (sm_context_response.n2_sm_info_is_set()) {
parser.create_multipart_related_content(
body, json_data.dump(), CURL_MIME_BOUNDARY,
sm_context_response.get_n2_sm_information(),
multipart_related_content_part_e::NGAP);
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
} else {
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
body = json_data.dump().c_str();
}
response.send(Pistache::Http::Code(sm_context_response.get_http_code()),
body);
}
}
}
}
......
......@@ -87,6 +87,11 @@ class IndividualSMContextApiImpl :
private:
smf::smf_app *m_smf_app;
std::string m_address;
protected:
static uint64_t generate_promise_id() {
return util::uint_uid_generator<uint64_t>::get_instance().get_uid();
}
};
}
......
......@@ -36,6 +36,7 @@
#include "smf_msg.hpp"
#include "itti_msg_n11.hpp"
#include "3gpp_29.502.h"
#include <nghttp2/asio_http2_server.h>
namespace oai {
namespace smf_server {
......@@ -49,9 +50,7 @@ SMContextsCollectionApiImpl::SMContextsCollectionApiImpl(
:
SMContextsCollectionApi(rtr),
m_smf_app(smf_app_inst),
m_address(address)
{
m_address(address) {
}
void SMContextsCollectionApiImpl::post_sm_contexts(
......@@ -66,8 +65,7 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
SmContextCreateData smContextCreateData = smContextMessage.getJsonData();
std::string n1_sm_msg = smContextMessage.getBinaryDataN1SmMessage();
Logger::smf_api_server().debug("smContextMessage, N1 SM message: %s",
n1_sm_msg.c_str());
Logger::smf_api_server().debug("N1 SM message: %s", n1_sm_msg.c_str());
//Step 2. Create a pdu_session_create_sm_context_request message and store the necessary information
Logger::smf_api_server().debug(
......@@ -87,38 +85,36 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
smf_string_to_supi(&supi, supi_str.c_str());
sm_context_req_msg.set_supi(supi);
sm_context_req_msg.set_supi_prefix(supi_prefix);
Logger::smf_api_server().debug(
"SmContextCreateData, SUPI %s, SUPI Prefix %s, IMSI %s",
smContextCreateData.getSupi().c_str(), supi_prefix.c_str(),
supi_str.c_str());
Logger::smf_api_server().debug("SUPI %s, SUPI Prefix %s, IMSI %s",
smContextCreateData.getSupi().c_str(),
supi_prefix.c_str(), supi_str.c_str());
//dnn
Logger::smf_api_server().debug("SmContextCreateData, DNN %s",
Logger::smf_api_server().debug("DNN %s",
smContextCreateData.getDnn().c_str());
sm_context_req_msg.set_dnn(smContextCreateData.getDnn().c_str());
//S-Nssai
Logger::smf_api_server().debug(
"SmContextCreateData, S-NSSAI SST %d, SD %s",
smContextCreateData.getSNssai().getSst(),
"S-NSSAI SST %d, SD %s", smContextCreateData.getSNssai().getSst(),
smContextCreateData.getSNssai().getSd().c_str());
snssai_t snssai(smContextCreateData.getSNssai().getSst(),
smContextCreateData.getSNssai().getSd());
sm_context_req_msg.set_snssai(snssai);
//PDU session ID
Logger::smf_api_server().debug("SmContextCreateData, PDU Session ID %d",
Logger::smf_api_server().debug("PDU Session ID %d",
smContextCreateData.getPduSessionId());
sm_context_req_msg.set_pdu_session_id(smContextCreateData.getPduSessionId());
//AMF ID (ServingNFId)
Logger::smf_api_server().debug("SmContextCreateDatea, ServingNfId %s",
Logger::smf_api_server().debug("ServingNfId %s",
smContextCreateData.getServingNfId().c_str());
sm_context_req_msg.set_serving_nf_id(
smContextCreateData.getServingNfId().c_str()); //TODO: should be verified that AMF ID is stored in GUAMI or ServingNfId
//Request Type
Logger::smf_api_server().debug("SmContextCreateData, RequestType %s",
Logger::smf_api_server().debug("RequestType %s",
smContextCreateData.getRequestType().c_str());
sm_context_req_msg.set_request_type(smContextCreateData.getRequestType());
//PCF ID
......@@ -136,7 +132,7 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
//PCFId
// DNN Selection Mode
Logger::smf_api_server().debug("SmContextCreateData, SelMode %s",
Logger::smf_api_server().debug("SelMode %s",
smContextCreateData.getSelMode().c_str());
sm_context_req_msg.set_dnn_selection_mode(
smContextCreateData.getSelMode().c_str());
......@@ -152,16 +148,40 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
//SM PDU DN request container (Optional)
//Extended protocol configuration options (Optional) e.g, FOR DHCP
boost::shared_ptr<boost::promise<smf::pdu_session_create_sm_context_response> > p =
boost::make_shared<
boost::promise<smf::pdu_session_create_sm_context_response> >();
boost::shared_future<smf::pdu_session_create_sm_context_response> f;
f = p->get_future();
//Generate ID for this promise (to be used in SMF-APP)
uint32_t promise_id = generate_promise_id();
Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
m_smf_app->add_promise(promise_id, p);
//Step 3. Handle the pdu_session_create_sm_context_request message in smf_app
std::shared_ptr<itti_n11_create_sm_context_request> itti_msg =
std::make_shared<itti_n11_create_sm_context_request>(TASK_SMF_N11,
TASK_SMF_APP,
response);
promise_id);
itti_msg->req = sm_context_req_msg;
itti_msg->http_version = 1;
m_smf_app->handle_pdu_session_create_sm_context_request(itti_msg);
//wait for the result from APP and send reply to AMF
smf::pdu_session_create_sm_context_response sm_context_response = f.get();
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
nlohmann::json json_data = { };
sm_context_response.get_json_data(json_data);
if (!json_data.empty()) {
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
response.send(Pistache::Http::Code(sm_context_response.get_http_code()), json_data.dump().c_str());
} else {
response.send(Pistache::Http::Code(sm_context_response.get_http_code()));
}
}
}
}
}
......@@ -73,6 +73,11 @@ class SMContextsCollectionApiImpl :
private:
smf::smf_app *m_smf_app;
std::string m_address;
protected:
static uint64_t generate_promise_id() {
return util::uint_uid_generator<uint64_t>::get_instance().get_uid();
}
};
}
......
......@@ -659,17 +659,6 @@ void SmContextUpdateData::setN2SmInfoType(std::string const& value)
m_N2SmInfoTypeIsSet = true;
}
/*
N2SmInfoType SmContextUpdateData::getN2SmInfoType() const
{
return m_N2SmInfoType;
}
void SmContextUpdateData::setN2SmInfoType(N2SmInfoType const& value)
{
m_N2SmInfoType = value;
m_N2SmInfoTypeIsSet = true;
}
*/
bool SmContextUpdateData::n2SmInfoTypeIsSet() const
{
return m_N2SmInfoTypeIsSet;
......
......@@ -30,6 +30,7 @@
* contact@openairinterface.org
*/
#include "smf-api-server.h"
#include "pistache/endpoint.h"
#include "pistache/http.h"
#include "pistache/router.h"
......@@ -39,7 +40,6 @@
#include <unistd.h>
#endif
#include "smf-api-server.h"
#define PISTACHE_SERVER_MAX_PAYLOAD 32768
#ifdef __linux__
......@@ -92,19 +92,3 @@ void SMFApiServer::start() {
void SMFApiServer::shutdown() {
m_httpEndpoint->shutdown();
}
/*
int main() {
#ifdef __linux__
std::vector<int> sigs{SIGQUIT, SIGINT, SIGTERM, SIGHUP};
setUpUnixSignals(sigs);
#endif
Pistache::Address addr(Pistache::Ipv4::any(), Pistache::Port(8080));
SMFApiServer smfApiServer(addr);
smfApiServer.init(2);
smfApiServer.start();
smfApiServer.shutdown();
}
*/
......@@ -31,6 +31,9 @@
* contact@openairinterface.org
*/
#ifndef FILE_SMF_API_SERVER_SEEN
#define FILE_SMF_API_SERVER_SEEN
#include "pistache/endpoint.h"
#include "pistache/http.h"
#include "pistache/router.h"
......@@ -63,7 +66,6 @@ class SMFApiServer {
m_smContextsCollectionApiImpl =
std::make_shared<SMContextsCollectionApiImpl>(m_router, smf_app_inst,
m_address);
}
void init(size_t thr = 1);
void start();
......@@ -77,6 +79,6 @@ class SMFApiServer {
std::shared_ptr<PDUSessionsCollectionApiImpl> m_pduSessionsCollectionApiImpl;
std::shared_ptr<SMContextsCollectionApiImpl> m_smContextsCollectionApiImpl;
std::string m_address;
};
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "smf-http2-server.h"
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
#include <nlohmann/json.hpp>
#include "logger.hpp"
#include "smf_msg.hpp"
#include "itti_msg_n11.hpp"
#include "3gpp_29.502.h"
#include "mime_parser.hpp"
#include "3gpp_29.500.h"
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
using namespace oai::smf_server::model;
//------------------------------------------------------------------------------
void smf_http2_server::start() {
boost::system::error_code ec;
//Create SM Context Request
server.handle("/nsmf-pdusession/v2/sm-contexts",
[&](const request &request, const response &response) {
request.on_data([&](const uint8_t *data, std::size_t len) {
if (len > 0) {
std::string msg((char*) data, len);
Logger::smf_api_server().debug("");
Logger::smf_api_server().info("Received a SM context create request from AMF.");
Logger::smf_api_server().debug("Message content \n %s",
msg.c_str());
//check HTTP method manually
if (request.method().compare("POST") != 0) {
//error
Logger::smf_api_server().debug(
"This method (%s) is not supported",
request.method().c_str());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED);
response.end();
return;
}
SmContextMessage smContextMessage = { };
SmContextCreateData smContextCreateData = { };
//simple parser
mime_parser sp = { };
sp.parse(msg);
std::vector<mime_part> parts = { };
sp.get_mime_parts(parts);
uint8_t size = parts.size();
Logger::smf_api_server().debug("Number of MIME parts %d",
size);
//at least 2 parts for Json data and N1 (+ N2)
if (size < 2) {
//send reply!!!
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
}
//step 2. process the request
try {
nlohmann::json::parse(parts[0].body.c_str()).get_to(
smContextCreateData);
smContextMessage.setJsonData(smContextCreateData);
if (parts[1].content_type.compare(
"application/vnd.3gpp.5gnas") == 0) {
smContextMessage.setBinaryDataN1SmMessage(
parts[1].body);
} else if (parts[1].content_type.compare(
"application/vnd.3gpp.ngap") == 0) {
smContextMessage.setBinaryDataN2SmInformation(
parts[1].body);
}
//process the request
this->create_sm_contexts_handler(smContextMessage,
response);
} catch (nlohmann::detail::exception &e) {
Logger::smf_api_server().warn(
"Can not parse the json data (error: %s)!",
e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
} catch (std::exception &e) {
Logger::smf_api_server().warn("Error: %s!", e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
response.end();
return;
}
}
});
});
//Update SM Context Request
server.handle("/nsmf-pdusession/v2/sm-contexts/",
[&](const request &request, const response &response) {
request.on_data([&](const uint8_t *data, std::size_t len) {
if (len > 0) {
std::string msg((char*) data, len);
Logger::smf_api_server().debug("");
Logger::smf_api_server().info("Received a SM context update request from AMF.");
Logger::smf_api_server().debug("Message content \n %s",
msg.c_str());
//Get the smf reference context and method
std::vector<std::string> split_result;
boost::split(split_result, request.uri().path,
boost::is_any_of("/"));
if (split_result.size() != 6) {
Logger::smf_api_server().warn(
"Requested URL is not implemented");
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_501_NOT_IMPLEMENTED);
response.end();
return;
}
std::string smf_ref =
split_result[split_result.size() - 2];
std::string method = split_result[split_result.size() - 1];
Logger::smf_api_server().info(
"smf_ref %s, method %s",
split_result[split_result.size() - 2].c_str(),
split_result[split_result.size() - 1].c_str());
if (method.compare("modify") == 0) { //Update SM Context Request
Logger::smf_api_server().info(
"Handle Update SM Context Request from AMF");
SmContextUpdateMessage smContextUpdateMessage = { };
SmContextUpdateData smContextUpdateData = { };
//simple parser
mime_parser sp = { };
sp.parse(msg);
std::vector<mime_part> parts = { };
sp.get_mime_parts(parts);
uint8_t size = parts.size();
Logger::smf_api_server().debug(
"Number of MIME parts %d", size);
try {
if (size > 0) {
nlohmann::json::parse(parts[0].body.c_str()).get_to(
smContextUpdateData);
} else {
nlohmann::json::parse(msg.c_str()).get_to(
smContextUpdateData);
}
smContextUpdateMessage.setJsonData(
smContextUpdateData);
for (int i = 1; i < size; i++) {
if (parts[i].content_type.compare(
"application/vnd.3gpp.5gnas") == 0) {
smContextUpdateMessage.setBinaryDataN1SmMessage(
parts[i].body);
Logger::smf_api_server().debug(
"N1 SM message is set");
} else if (parts[i].content_type.compare(
"application/vnd.3gpp.ngap") == 0) {
smContextUpdateMessage
.setBinaryDataN2SmInformation(parts[i].body);
Logger::smf_api_server().debug(
"N2 SM information is set");
}
}
this->update_sm_context_handler(
smf_ref, smContextUpdateMessage, response);
} catch (nlohmann::detail::exception &e) {
Logger::smf_api_server().warn(
"Can not parse the json data (error: %s)!",
e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
} catch (std::exception &e) {
Logger::smf_api_server().warn("Error: %s!", e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
response.end();
return;
}
} else if (method.compare("release") == 0) { //smContextReleaseData
Logger::smf_api_server().info(
"Handle Release SM Context Request from AMF");
SmContextReleaseData smContextReleaseData = { };
try {
nlohmann::json::parse(msg.c_str()).get_to(
smContextReleaseData);
this->release_sm_context_handler(smf_ref,
smContextReleaseData,
response);
} catch (nlohmann::detail::exception &e) {
Logger::smf_api_server().warn(
"Can not parse the json data (error: %s)!",
e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_400_BAD_REQUEST);
response.end();
return;
} catch (std::exception &e) {
Logger::smf_api_server().warn("Error: %s!", e.what());
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR);
response.end();
return;
}
} else if (method.compare("retrieve") == 0) { //smContextRetrieveData
//TODO: retrieve_sm_context_handler
} else { //Unknown method
Logger::smf_api_server().warn("Unknown method");
response.write_head(
http_status_code_e::HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED);
response.end();
return;
}
}
});
});
if (server.listen_and_serve(ec, m_address, std::to_string(m_port))) {
std::cerr << "HTTP Server error: " << ec.message() << std::endl;
}
}
//------------------------------------------------------------------------------
void smf_http2_server::create_sm_contexts_handler(
const SmContextMessage &smContextMessage, const response &response) {
Logger::smf_api_server().info(
"Handle PDU Session Create SM Context Request.");
SmContextCreateData smContextCreateData = smContextMessage.getJsonData();
std::string n1_sm_msg = smContextMessage.getBinaryDataN1SmMessage();
Logger::smf_api_server().debug("N1 SM message: %s", n1_sm_msg.c_str());
//Step 1. Create a pdu_session_create_sm_context_request message and store the necessary information
Logger::smf_api_server().debug(
"Create a pdu_session_create_sm_context_request message and store the necessary information");
smf::pdu_session_create_sm_context_request sm_context_req_msg = { };
//set N1 SM Message
sm_context_req_msg.set_n1_sm_message(n1_sm_msg);
//set api root to be used as location header in HTTP response
sm_context_req_msg.set_api_root(
m_address + ":" + std::to_string(m_port)
+ "/nsmf-pdusession/v2/sm-context");
//supi
supi_t supi = { .length = 0 };
std::size_t pos = smContextCreateData.getSupi().find("-");
std::string supi_str = smContextCreateData.getSupi().substr(pos + 1);
std::string supi_prefix = smContextCreateData.getSupi().substr(0, pos);
smf_string_to_supi(&supi, supi_str.c_str());
sm_context_req_msg.set_supi(supi);
sm_context_req_msg.set_supi_prefix(supi_prefix);
Logger::smf_api_server().debug("SUPI %s, SUPI Prefix %s, IMSI %s",
smContextCreateData.getSupi().c_str(),
supi_prefix.c_str(), supi_str.c_str());
//dnn
Logger::smf_api_server().debug("DNN %s",
smContextCreateData.getDnn().c_str());
sm_context_req_msg.set_dnn(smContextCreateData.getDnn().c_str());
//S-Nssai
Logger::smf_api_server().debug(
"S-NSSAI SST %d, SD %s", smContextCreateData.getSNssai().getSst(),
smContextCreateData.getSNssai().getSd().c_str());
snssai_t snssai(smContextCreateData.getSNssai().getSst(),
smContextCreateData.getSNssai().getSd());
sm_context_req_msg.set_snssai(snssai);
//PDU session ID
Logger::smf_api_server().debug("PDU Session ID %d",
smContextCreateData.getPduSessionId());
sm_context_req_msg.set_pdu_session_id(smContextCreateData.getPduSessionId());
//AMF ID (ServingNFId)
Logger::smf_api_server().debug("ServingNfId %s",
smContextCreateData.getServingNfId().c_str());
sm_context_req_msg.set_serving_nf_id(
smContextCreateData.getServingNfId().c_str());
//Request Type
Logger::smf_api_server().debug("RequestType %s",
smContextCreateData.getRequestType().c_str());
sm_context_req_msg.set_request_type(smContextCreateData.getRequestType());
//PCF ID
// Priority Access
//User Location Information
//Access Type
// PEI
// GPSI
// UE presence in LADN service area
//Guami
//servingNetwork
//anType
//UETimeZone
//SMContextStatusUri
//PCFId
// DNN Selection Mode
Logger::smf_api_server().debug("SelMode %s",
smContextCreateData.getSelMode().c_str());
sm_context_req_msg.set_dnn_selection_mode(
smContextCreateData.getSelMode().c_str());
//Subscription for PDU Session Status Notification
// Trace requirement
//SSC mode (Optional)
//5GSM capability (Optional)
//Maximum number of supported (Optional)
//Maximum number of supported packet filters (Optional)
//Always-on PDU session requested (Optional)
//SM PDU DN request container (Optional)
//Extended protocol configuration options (Optional) e.g, FOR DHCP
boost::shared_ptr<boost::promise<smf::pdu_session_create_sm_context_response> > p =
boost::make_shared<
boost::promise<smf::pdu_session_create_sm_context_response> >();
boost::shared_future<smf::pdu_session_create_sm_context_response> f;
f = p->get_future();
//Generate ID for this promise (to be used in SMF-APP)
uint32_t promise_id = generate_promise_id();
Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
m_smf_app->add_promise(promise_id, p);
//Step 2. Handle the pdu_session_create_sm_context_request message in smf_app
std::shared_ptr<itti_n11_create_sm_context_request> itti_msg =
std::make_shared<itti_n11_create_sm_context_request>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
itti_msg->req = sm_context_req_msg;
itti_msg->http_version = 2;
m_smf_app->handle_pdu_session_create_sm_context_request(itti_msg);
//wait for the result from APP and send reply to AMF
smf::pdu_session_create_sm_context_response sm_context_response = f.get();
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
nlohmann::json json_data = { };
sm_context_response.get_json_data(json_data);
if (sm_context_response.get_smf_context_uri().size() > 0) {
Logger::smf_api_server().debug(
"Add location header %s",
sm_context_response.get_smf_context_uri().c_str());
header_map h;
h.emplace("location", header_value {
sm_context_response.get_smf_context_uri().c_str() });
response.write_head(sm_context_response.get_http_code(), h);
} else {
response.write_head(sm_context_response.get_http_code());
}
response.end(json_data.dump().c_str());
}
//------------------------------------------------------------------------------
void smf_http2_server::update_sm_context_handler(
const std::string &smf_ref,
const SmContextUpdateMessage &smContextUpdateMessage,
const response &response) {
Logger::smf_api_server().info(
"Handle PDU Session Update SM Context Request.");
//Get the SmContextUpdateData from this message and process in smf_app
Logger::smf_api_server().info(
"Received a PDUSession_UpdateSMContext Request from AMF.");
smf::pdu_session_update_sm_context_request sm_context_req_msg = { };
SmContextUpdateData smContextUpdateData =
smContextUpdateMessage.getJsonData();
if (smContextUpdateData.n2SmInfoIsSet()) {
//N2 SM (for Session establishment)
std::string n2_sm_information = smContextUpdateMessage
.getBinaryDataN2SmInformation();
Logger::smf_api_server().debug("N2 SM Information %s",
n2_sm_information.c_str());
std::string n2_sm_info_type = smContextUpdateData.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);
} else if (smContextUpdateData.n1SmMsgIsSet()) {
//N1 SM (for session modification)
std::string n1_sm_message =
smContextUpdateMessage.getBinaryDataN1SmMessage();
Logger::smf_api_server().debug("N1 SM Message %s", n1_sm_message.c_str());
sm_context_req_msg.set_n1_sm_message(n1_sm_message);
}
//Step 2. TODO: initialize necessary values for sm context req from smContextUpdateData
/* UE-initiated Service Request Operation, section 4.2.3.2@3GPP TS 23.502 */
//Step 4: PDU Session IDs, Operation Type, UE location Info, Access Type, RAT Type, UE presence in LADN service area, Indication of Access Type can be changed
//PDU Session IDs
//UpCnxState, for activation of user plane (see 5.2.2.3.2.2@3GPP TS 29.502, step 1)
if (smContextUpdateData.upCnxStateIsSet())
sm_context_req_msg.set_upCnx_state(smContextUpdateData.getUpCnxState());
//Access Type (step 1 and 2)
if (smContextUpdateData.anTypeIsSet())
sm_context_req_msg.set_an_type(smContextUpdateData.getAnType());
//RAT Type (step 1 and 2)
if (smContextUpdateData.ratTypeIsSet())
sm_context_req_msg.set_rat_type(smContextUpdateData.getRatType());
//TODO:
//UE presence in LADN service area
//UE location information
//Indication of Access Type can be changed
//if (smContextUpdateData.anTypeCanBeChangedIsSet()) sm_context_req_msg.set_access_type_can_be_changed(smContextUpdateData.isAnTypeCanBeChanged());
//Step 15: N2 SM Info (AN Tunnel Info, List of accepted QoS Flow, List of rejected Qos Flows, PDU Session ID), RAT Type, Access Type
/* UE-initiated PDU Session Establishment Operation - section 4.3.2.2.1@3GPP TS 23.502 */
//TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF ID, Request Type, N1 SM Container (PDU Session Establishment Request), User location, Access Type, RAT Type, PEI
//step 15. (SM Context ID -> SCID, N2 SM, Request Type)(Initial Request)
//TODO: verify why Request Type is not define in smContextUpdateData
/* AMF-initiated with a release indication to request the release of the PDU Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/
if (smContextUpdateData.releaseIsSet()) {
sm_context_req_msg.set_release(smContextUpdateData.isRelease());
}
/* PDU Session Modification (SM Context ID -> SCID, N1/N2), section 4.3.3.2@3GPP TS 23.502: */
//step 1.a,UE-initiated: SM Context ID + N1 (PDU Session Modification Request)
//step 1.e (AN initiated modification): SM Context ID, N2 SM information (QFI, User location Information and an indication that the QoS Flow is released)
//step 7a, SM Context ID, N2 SM information, UE location information
//Step 11, SM Context ID, N1 SM (PDU Session Modification Command ACK), User location
boost::shared_ptr<boost::promise<smf::pdu_session_update_sm_context_response> > p =
boost::make_shared<
boost::promise<smf::pdu_session_update_sm_context_response> >();
boost::shared_future<smf::pdu_session_update_sm_context_response> f;
f = p->get_future();
//Generate ID for this promise (to be used in SMF-APP)
uint32_t promise_id = generate_promise_id();
Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
m_smf_app->add_promise(promise_id, p);
//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,
promise_id, smf_ref);
itti_msg->req = sm_context_req_msg;
itti_msg->http_version = 2;
m_smf_app->handle_pdu_session_update_sm_context_request(itti_msg);
//wait for the result from APP and send reply to AMF
smf::pdu_session_update_sm_context_response sm_context_response = f.get();
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
nlohmann::json json_data = { };
mime_parser parser = { };
std::string body = { };
header_map h = { };
sm_context_response.get_json_data(json_data);
Logger::smf_api_server().debug("Json data %s", json_data.dump().c_str());
if (sm_context_response.n1_sm_msg_is_set()
and sm_context_response.n2_sm_info_is_set()) {
parser.create_multipart_related_content(
body, json_data.dump(), CURL_MIME_BOUNDARY,
sm_context_response.get_n1_sm_message(),
sm_context_response.get_n2_sm_information());
h.emplace(
"content-type",
header_value { "multipart/related; boundary="
+ std::string(CURL_MIME_BOUNDARY) });
} else if (sm_context_response.n1_sm_msg_is_set()) {
parser.create_multipart_related_content(
body, json_data.dump(), CURL_MIME_BOUNDARY,
sm_context_response.get_n1_sm_message(),
multipart_related_content_part_e::NAS);
h.emplace(
"content-type",
header_value { "multipart/related; boundary="
+ std::string(CURL_MIME_BOUNDARY) });
} else if (sm_context_response.n2_sm_info_is_set()) {
parser.create_multipart_related_content(
body, json_data.dump(), CURL_MIME_BOUNDARY,
sm_context_response.get_n2_sm_information(),
multipart_related_content_part_e::NGAP);
h.emplace(
"content-type",
header_value { "multipart/related; boundary="
+ std::string(CURL_MIME_BOUNDARY) });
} else {
h.emplace("content-type", header_value { "application/json" });
body = json_data.dump().c_str();
}
response.write_head(sm_context_response.get_http_code(), h);
response.end(body);
}
//------------------------------------------------------------------------------
void smf_http2_server::release_sm_context_handler(
const std::string &smf_ref,
const SmContextReleaseData &smContextReleaseData,
const response &response) {
Logger::smf_api_server().info(
"Handle PDU Session Release SM Context Request.");
boost::shared_ptr<boost::promise<smf::pdu_session_release_sm_context_response> > p =
boost::make_shared<
boost::promise<smf::pdu_session_release_sm_context_response> >();
boost::shared_future<smf::pdu_session_release_sm_context_response> f;
f = p->get_future();
//Generate ID for this promise (to be used in SMF-APP)
uint32_t promise_id = generate_promise_id();
Logger::smf_api_server().debug("Promise ID generated %d", promise_id);
m_smf_app->add_promise(promise_id, p);
//handle Nsmf_PDUSession_UpdateSMContext Request
Logger::smf_api_server().info(
"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,
promise_id,
smf_ref);
itti_msg->scid = smf_ref;
itti_msg->http_version = 2;
m_smf_app->handle_pdu_session_release_sm_context_request(itti_msg);
//wait for the result from APP and send reply to AMF
smf::pdu_session_release_sm_context_response sm_context_response = f.get();
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
response.write_head(sm_context_response.get_http_code());
response.end();
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef FILE_SMF_HTTP2_SERVER_SEEN
#define FILE_SMF_HTTP2_SERVER_SEEN
#include "smf_app.hpp"
#include <nghttp2/asio_http2_server.h>
#include "SmContextUpdateMessage.h"
#include "SmContextMessage.h"
#include "SmContextReleaseData.h"
#include "uint_generator.hpp"
#include "smf.h"
using namespace nghttp2::asio_http2;
using namespace nghttp2::asio_http2::server;
using namespace oai::smf_server::model;
class smf_http2_server {
public:
smf_http2_server(std::string addr, uint32_t port, smf::smf_app *smf_app_inst)
:
m_address(addr),
m_port(port),
server(),
m_smf_app(smf_app_inst) {
}
void start();
void init(size_t thr) {
}
void create_sm_contexts_handler(const SmContextMessage &smContextMessage,
const response &response);
void update_sm_context_handler(
const std::string &smf_ref,
const SmContextUpdateMessage &smContextUpdateMessage,
const response &response);
void release_sm_context_handler(
const std::string &smf_ref,
const SmContextReleaseData &smContextReleaseData,
const response &response);
private:
util::uint_generator<uint32_t> m_promise_id_generator;
std::string m_address;
uint32_t m_port;
http2 server;
smf::smf_app *m_smf_app;
protected:
static uint64_t generate_promise_id() {
return util::uint_uid_generator<uint64_t>::get_instance().get_uid();
}
};
#endif
......@@ -19,30 +19,40 @@
* contact@openairinterface.org
*/
/*! \file simple_parser.hpp
\brief
\author
\company Eurecom
\email:
*/
#ifndef FILE_SIMPLE_PARSER_HPP_SEEN
#define FILE_SIMPLE_PARSER_HPP_SEEN
# include <string>
#include <map>
#include <vector>
#ifndef FILE_3GPP_29_500_SMF_SEEN
#define FILE_3GPP_29_500_SMF_SEEN
typedef struct mime_part {
std::string content_type;
std::string body;
} mime_part;
enum http_status_code_e {
HTTP_STATUS_CODE_100_CONTINUE = 100,
HTTP_STATUS_CODE_200_OK =200,
HTTP_STATUS_CODE_201_CREATED = 201,
HTTP_STATUS_CODE_202_ACCEPTED = 202,
HTTP_STATUS_CODE_204_NO_CONTENT = 204,
HTTP_STATUS_CODE_300_MULTIPLE_CHOICES = 300,
HTTP_STATUS_CODE_303_SEE_OTHER = 303,
HTTP_STATUS_CODE_307_TEMPORARY_REDIRECT = 307,
HTTP_STATUS_CODE_308_PERMANENT_REDIRECT =308,
HTTP_STATUS_CODE_400_BAD_REQUEST = 400,
HTTP_STATUS_CODE_401_UNAUTHORIZED = 401,
HTTP_STATUS_CODE_403_FORBIDDEN = 403,
HTTP_STATUS_CODE_404_NOT_FOUND = 404,
HTTP_STATUS_CODE_405_METHOD_NOT_ALLOWED = 405,
HTTP_STATUS_CODE_406_NOT_ACCEPTABLE = 406,
HTTP_STATUS_CODE_408_REQUEST_TIMEOUT = 408,
HTTP_STATUS_CODE_409_CONFLICT = 409,
HTTP_STATUS_CODE_410_GONE = 410,
HTTP_STATUS_CODE_411_LENGTH_REQUIRED = 411,
HTTP_STATUS_CODE_412_PRECONDITION_FAILED = 412,
HTTP_STATUS_CODE_413_PAYLOAD_TOO_LARGE = 413,
HTTP_STATUS_CODE_414_URI_TOO_LONG = 414,
HTTP_STATUS_CODE_415_UNSUPPORTED_MEDIA_TYPE_NA = 415,
HTTP_STATUS_CODE_429_TOO_MANY_REQUESTS = 429,
HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR = 500,
HTTP_STATUS_CODE_501_NOT_IMPLEMENTED = 501,
HTTP_STATUS_CODE_503_SERVICE_UNAVAILABLE = 503,
HTTP_STATUS_CODE_504_GATEWAY_TIMEOUT = 504
};
class simple_parser {
public:
bool parse(const std::string &str);
void get_mime_parts(std::vector<mime_part> &parts) const;
private:
std::vector<mime_part> mime_parts;
#endif
};
#endif /* FILE_SIMPLE_PARSER_HPP_SEEN */
......@@ -59,29 +59,32 @@ class itti_n11_msg : public itti_msg {
class itti_n11_create_sm_context_request : public itti_n11_msg {
public:
itti_n11_create_sm_context_request(const task_id_t orig, const task_id_t dest,
Pistache::Http::ResponseWriter &response)
uint32_t promise_id)
:
itti_n11_msg(N11_SESSION_CREATE_SM_CONTEXT_REQUEST, orig, dest),
http_response(response),
pid(promise_id),
req(),
scid() {
scid(),
http_version(1) {
}
itti_n11_create_sm_context_request(
const itti_n11_create_sm_context_request &i)
:
itti_n11_msg(i),
pid(),
req(i.req),
http_response(i.http_response),
scid() {
scid(),
http_version(1) {
}
itti_n11_create_sm_context_request(
const itti_n11_create_sm_context_request &i, const task_id_t orig,
const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
pid(i.pid),
req(i.req),
http_response(i.http_response),
scid(i.scid) {
scid(i.scid),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "N11_SESSION_CREATE_SM_CONTEXT_REQUEST";
......@@ -92,8 +95,9 @@ class itti_n11_create_sm_context_request : public itti_n11_msg {
}
;
smf::pdu_session_create_sm_context_request req;
Pistache::Http::ResponseWriter &http_response;
scid_t scid; //SM Context ID
uint32_t pid; //Promise Id
uint8_t http_version;
};
......@@ -101,41 +105,45 @@ class itti_n11_create_sm_context_request : public itti_n11_msg {
class itti_n11_create_sm_context_response : public itti_n11_msg {
public:
itti_n11_create_sm_context_response(const task_id_t orig,
const task_id_t dest,
Pistache::Http::ResponseWriter &response)
const task_id_t dest, uint32_t promise_id)
:
itti_n11_msg(N11_SESSION_CREATE_SM_CONTEXT_RESPONSE, orig, dest),
http_response(response.clone()),
scid(0) {
pid(promise_id),
scid(0),
http_version() {
}
itti_n11_create_sm_context_response(
const itti_n11_create_sm_context_response &i)
:
itti_n11_msg(i),
pid(i.pid),
res(i.res),
http_response(i.http_response.clone()),
scid(i.scid) {
scid(i.scid),
http_version(i.http_version) {
}
itti_n11_create_sm_context_response(
const itti_n11_create_sm_context_response &i, const task_id_t orig,
const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
pid(i.pid),
res(i.res),
http_response(i.http_response.clone()),
scid(i.scid) {
scid(i.scid),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "N11_SESSION_CREATE_SM_CONTEXT_RESPONSE";
}
;
smf::pdu_session_create_sm_context_response res;
Pistache::Http::ResponseWriter http_response;
void set_scid(scid_t id) {
scid = id;
}
;
smf::pdu_session_create_sm_context_response res;
scid_t scid; //SM Context ID
uint32_t pid; //Promise Id
uint8_t http_version; //HTTP version
};
......@@ -143,54 +151,51 @@ class itti_n11_create_sm_context_response : public itti_n11_msg {
class itti_n11_update_sm_context_request : public itti_n11_msg {
public:
itti_n11_update_sm_context_request(const task_id_t orig, const task_id_t dest,
Pistache::Http::ResponseWriter &response)
uint32_t promise_id)
:
itti_n11_msg(N11_SESSION_UPDATE_SM_CONTEXT_REQUEST, orig, dest),
http_response(response) {
pid(promise_id),
scid(),
req(),
http_version() {
}
itti_n11_update_sm_context_request(const task_id_t orig, const task_id_t dest,
Pistache::Http::ResponseWriter &response,
const std::string id)
int32_t promise_id, const std::string id)
:
itti_n11_msg(N11_SESSION_UPDATE_SM_CONTEXT_REQUEST, orig, dest),
http_response(response),
scid(id) {
req(),
pid(promise_id),
scid(id),
http_version() {
}
itti_n11_update_sm_context_request(
const itti_n11_update_sm_context_request &i)
:
itti_n11_msg(i),
req(i.req),
http_response(i.http_response),
scid(i.scid) {
}
itti_n11_update_sm_context_request(
const itti_n11_update_sm_context_request &i, const task_id_t orig,
const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
req(i.req),
http_response(i.http_response),
scid(i.scid) {
pid(i.pid),
scid(i.scid),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "N11_SESSION_UPDATE_SM_CONTEXT_REQUEST";
}
;
smf::pdu_session_update_sm_context_request req;
Pistache::Http::ResponseWriter &http_response;
uint32_t pid;
std::string scid; //SM Context ID
uint8_t http_version;
};
//-----------------------------------------------------------------------------
class itti_n11_update_sm_context_response : public itti_n11_msg {
public:
itti_n11_update_sm_context_response(const task_id_t orig,
const task_id_t dest,
Pistache::Http::ResponseWriter &response)
const task_id_t dest, uint32_t promise_id)
:
itti_n11_msg(N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE, orig, dest),
http_response(response.clone()),
pid(promise_id),
res(),
session_procedure_type() {
}
......@@ -199,7 +204,7 @@ class itti_n11_update_sm_context_response : public itti_n11_msg {
:
itti_n11_msg(i),
res(i.res),
http_response(i.http_response.clone()),
pid(i.pid),
session_procedure_type(i.session_procedure_type) {
}
itti_n11_update_sm_context_response(
......@@ -208,7 +213,7 @@ class itti_n11_update_sm_context_response : public itti_n11_msg {
:
itti_n11_msg(i, orig, dest),
res(i.res),
http_response(i.http_response.clone()),
pid(i.pid),
session_procedure_type(i.session_procedure_type) {
}
const char* get_msg_name() {
......@@ -216,39 +221,11 @@ class itti_n11_update_sm_context_response : public itti_n11_msg {
}
;
smf::pdu_session_update_sm_context_response res;
Pistache::Http::ResponseWriter http_response;
uint32_t pid; //promise Id
session_management_procedures_type_e session_procedure_type;
};
//-----------------------------------------------------------------------------
class itti_n11_modify_session_request_smf_requested : public itti_n11_msg {
public:
itti_n11_modify_session_request_smf_requested(const task_id_t orig,
const task_id_t dest)
:
itti_n11_msg(N11_SESSION_MODIFICATION_REQUEST_SMF_REQUESTED, orig, dest) {
}
itti_n11_modify_session_request_smf_requested(
const itti_n11_modify_session_request_smf_requested &i)
:
itti_n11_msg(i),
req(i.req) {
}
itti_n11_modify_session_request_smf_requested(
const itti_n11_modify_session_request_smf_requested &i,
const task_id_t orig, const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
req(i.req) {
}
const char* get_msg_name() {
return "N11_SESSION_MODIFICATION_REQUEST_SMF_REQUESTED";
}
;
smf::pdu_session_create_sm_context_request req;
};
//-----------------------------------------------------------------------------
class itti_n11_update_pdu_session_status : public itti_n11_msg {
public:
......@@ -378,45 +355,48 @@ 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)
const task_id_t dest, uint32_t promise_id)
:
itti_n11_msg(N11_SESSION_RELEASE_SM_CONTEXT_REQUEST, orig, dest),
http_response(response) {
pid(promise_id),
http_version(1) {
}
itti_n11_release_sm_context_request(const task_id_t orig,
const task_id_t dest,
Pistache::Http::ResponseWriter &response,
const task_id_t dest, uint32_t promise_id,
const std::string id)
:
itti_n11_msg(N11_SESSION_RELEASE_SM_CONTEXT_REQUEST, orig, dest),
http_response(response),
scid(id) {
pid(promise_id),
scid(id),
http_version(1) {
}
itti_n11_release_sm_context_request(
const itti_n11_release_sm_context_request &i)
:
itti_n11_msg(i),
http_response(i.http_response),
pid(i.pid),
scid(i.scid),
req(i.req) {
req(i.req),
http_version(i.http_version) {
}
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),
pid(i.pid),
scid(i.scid),
req(i.req) {
req(i.req),
http_version(i.http_version) {
}
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
uint32_t pid; //Promise Id
uint8_t http_version; //HTTP version
};
......@@ -425,10 +405,10 @@ 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)
uint32_t promise_id)
:
itti_n11_msg(N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE, orig, dest),
http_response(response.clone()),
pid(promise_id),
res() {
}
itti_n11_release_sm_context_response(
......@@ -436,7 +416,7 @@ class itti_n11_release_sm_context_response : public itti_n11_msg {
:
itti_n11_msg(i),
res(i.res),
http_response(i.http_response.clone()) {
pid(i.pid) {
}
itti_n11_release_sm_context_response(
const itti_n11_release_sm_context_response &i, const task_id_t orig,
......@@ -444,14 +424,14 @@ class itti_n11_release_sm_context_response : public itti_n11_msg {
:
itti_n11_msg(i, orig, dest),
res(i.res),
http_response(i.http_response.clone()) {
pid(i.pid) {
}
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;
uint32_t pid; //Promise Id
};
......@@ -461,23 +441,28 @@ class itti_n11_session_report_request : public itti_n11_msg {
itti_n11_session_report_request(const task_id_t orig, const task_id_t dest)
:
itti_n11_msg(N11_SESSION_REPORT_RESPONSE, orig, dest),
res() {
res(),
http_version() {
}
itti_n11_session_report_request(const itti_n11_session_report_request &i)
:
itti_n11_msg(i) {
itti_n11_msg(i),
res(i.res),
http_version(i.http_version) {
}
itti_n11_session_report_request(const itti_n11_session_report_request &i,
const task_id_t orig, const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
res(i.res) {
res(i.res),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "N11_SESSION_REPORT_RESPONSE";
}
;
smf::pdu_session_report_response res;
uint8_t http_version;
};
......
......@@ -60,26 +60,31 @@ class itti_nx_trigger_pdu_session_modification : public itti_nx_msg {
itti_nx_trigger_pdu_session_modification(const task_id_t orig,
const task_id_t dest)
:
itti_nx_msg(NX_TRIGGER_SESSION_MODIFICATION, orig, dest) {
itti_nx_msg(NX_TRIGGER_SESSION_MODIFICATION, orig, dest),
msg(),
http_version() {
}
itti_nx_trigger_pdu_session_modification(
const itti_nx_trigger_pdu_session_modification &i)
:
itti_nx_msg(i),
msg(i.msg) {
msg(i.msg),
http_version(i.http_version) {
}
itti_nx_trigger_pdu_session_modification(
const itti_nx_trigger_pdu_session_modification &i, const task_id_t orig,
const task_id_t dest)
:
itti_nx_msg(i, orig, dest),
msg() {
msg(),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "NX_TRIGGER_PDU_SESSION_MODIFICATION";
}
;
smf::pdu_session_modification_network_requested msg;
uint8_t http_version;
};
#endif /* ITTI_MSG_NX_HPP_INCLUDED_ */
......@@ -24,21 +24,21 @@
#include <stdint.h>
typedef enum extended_protocol_discriminator_e {
/* Protocol discriminator identifier for 5G Session Management */
// Protocol discriminator identifier for 5G Session Management
EPD_5GS_SESSION_MANAGEMENT_MESSAGES = 0x2e,
/* Protocol discriminator identifier for 5G Mobility Management */
// Protocol discriminator identifier for 5G Mobility Management
EPD_5GS_MOBILITY_MANAGEMENT_MESSAGES = 0x7e,
} extended_protocol_discriminator_t;
/* Procedure transaction identity */
// Procedure transaction identity
//8 bits
#define PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED (uint8_t)0
#define PROCEDURE_TRANSACTION_IDENTITY_FIRST (uint8_t)1
#define PROCEDURE_TRANSACTION_IDENTITY_LAST (uint8_t)254
#define PROCEDURE_TRANSACTION_IDENTITY_RESERVED (uint8_t)255
/* PDU Session Identity */
// PDU Session Identity
typedef uint8_t pdu_session_id_t;
//8 bits
......@@ -46,31 +46,17 @@ typedef uint8_t pdu_session_id_t;
#define PDU_SESSION_IDENTITY_FIRST (uint8_t)1
#define PDU_SESSION_IDENTITY_LAST (uint8_t)15
/* QFI */
// QFI
// type: integer, minimum: 0, maximum: 63
#define NO_QOS_FLOW_IDENTIFIER_ASSIGNED (uint8_t)0
#define QOS_FLOW_IDENTIFIER_FIRST (uint8_t)1
#define QOS_FLOW_IDENTIFIER_LAST (uint8_t)63
/*
//TODO: QFI defined in 3gpp_29.274.h
typedef struct smf_qfi_s {
uint8_t qfi;
smf_qfi_s() : qfi(QOS_FLOW_IDENTIFIER_FIRST) {}
smf_qfi_s(const uint8_t& q) : qfi(q) {}
smf_qfi_s(const struct smf_qfi_s& q) : qfi(q.qfi) {}
inline bool operator==(const struct smf_qfi_s& rhs) const { return qfi == rhs.qfi; }
inline bool operator!=(const struct smf_qfi_s& rhs) const { return !(qfi == rhs.qfi); }
} smf_qfi_t;
*/
//QoS Rule
#define NO_QOS_RULE_IDENTIFIER_ASSIGNED (uint8_t)0
#define QOS_RULE_IDENTIFIER_FIRST (uint8_t)1
#define QOS_RULE_IDENTIFIER_LAST (uint8_t)255
// Integrity protection maximum data rate
typedef struct ipmdr_s {
uint8_t ul;
......
......@@ -38,10 +38,6 @@
#include <stdint.h>
#include <inttypes.h>
#if 0
#include "queue.h"
#endif
#ifndef FILE_SECURITY_TYPES_SEEN
#define FILE_SECURITY_TYPES_SEEN
......
......@@ -33,257 +33,8 @@
#include "Ngap_Criticality.h"
#include "Ngap_CriticalityDiagnostics-IE-Item.h"
#if 0
#include "Ngap_AdditionalQosFlowInformation.h"
#include "Ngap_AllocationAndRetentionPriority.h"
#include "Ngap_AllowedNSSAI.h"
#include "Ngap_AllowedNSSAI-Item.h"
#include "Ngap_AllowedTACs.h"
#include "Ngap_AMFName.h"
#include "Ngap_AMFPagingTarget.h"
#include "Ngap_Cause.h"
#include "Ngap_ResetType.h"
#include "Ngap_RoutingID.h"
#include "Ngap_NRPPa-PDU.h"
#include "Ngap_AMF-UE-NGAP-ID.h"
#include "Ngap_RAN-UE-NGAP-ID.h"
#include "Ngap_TimeToWait.h"
#include "Ngap_CriticalityDiagnostics.h"
#include "Ngap_ServedGUAMIList.h"
#include "Ngap_RelativeAMFCapacity.h"
#include "Ngap_PLMNSupportList.h"
#include "Ngap_AMF-TNLAssociationToAddList.h"
#include "Ngap_AMF-TNLAssociationToRemoveList.h"
#include "Ngap_AMF-TNLAssociationToUpdateList.h"
#include "Ngap_PDUSessionResourceFailedToSetupListCxtFail.h"
#include "Ngap_CriticalityDiagnostics.h"
#include "Ngap_CriticalityDiagnostics.h"
#include "Ngap_RANPagingPriority.h"
#include "Ngap_SecurityKey.h"
#include "Ngap_IndexToRFSP.h"
#include "Ngap_UEAggregateMaximumBitRate.h"
#include "Ngap_UESecurityCapabilities.h"
#include "Ngap_CoreNetworkAssistanceInformation.h"
#include "Ngap_EmergencyFallbackIndicator.h"
#include "Ngap_RRCInactiveTransitionReportRequest.h"
#include "Ngap_IMSVoiceSupportIndicator.h"
#include "Ngap_UserLocationInformation.h"
#include "Ngap_UEPresenceInAreaOfInterestList.h"
#include "Ngap_LocationReportingRequestType.h"
#include "Ngap_PWSFailedCellIDList.h"
#include "Ngap_UserLocationInformation.h"
#include "Ngap_NAS-PDU.h"
#include "Ngap_PDUSessionResourceToReleaseListRelCmd.h"
#include "Ngap_UERadioCapability.h"
#include "Ngap_UERadioCapabilityForPaging.h"
#include "Ngap_MessageIdentifier.h"
#include "Ngap_SerialNumber.h"
#include "Ngap_BroadcastCancelledAreaList.h"
#include "Ngap_PDUSessionResourceAdmittedList.h"
#include "Ngap_PDUSessionResourceFailedToSetupListHOAck.h"
#include "Ngap_TargetToSource-TransparentContainer.h"
#include "Ngap_BroadcastCompletedAreaList.h"
#include "Ngap_SecurityContext.h"
#include "Ngap_NewSecurityContextInd.h"
#include "Ngap_PDUSessionResourceSwitchedList.h"
#include "Ngap_PDUSessionResourceReleasedListPSAck.h"
#include "Ngap_TraceActivation.h"
#include "Ngap_OverloadResponse.h"
#include "Ngap_TrafficLoadReductionIndication.h"
#include "Ngap_OverloadStartNSSAIList.h"
#include "Ngap_AMF-TNLAssociationSetupList.h"
#include "Ngap_TNLAssociationList.h"
#include "Ngap_PDUSessionResourceModifyListModRes.h"
#include "Ngap_PDUSessionResourceFailedToModifyListModRes.h"
#include "Ngap_MobilityRestrictionList.h"
#include "Ngap_PDUSessionResourceSetupListSURes.h"
#include "Ngap_PDUSessionResourceFailedToSetupListSURes.h"
#include "Ngap_NGRANTraceID.h"
#include "Ngap_PDUSessionResourceModifyListModInd.h"
#include "Ngap_SONConfigurationTransfer.h"
#include "Ngap_UEPagingIdentity.h"
#include "Ngap_TAIListForPaging.h"
#include "Ngap_PagingPriority.h"
#include "Ngap_PagingOrigin.h"
#include "Ngap_AssistanceDataForPaging.h"
#include "Ngap_PDUSessionResourceToBeSwitchedDLList.h"
#include "Ngap_PDUSessionResourceFailedToSetupListPSReq.h"
#include "Ngap_WarningAreaList.h"
#include "Ngap_CancelAllWarningMessages.h"
#include "Ngap_InfoOnRecommendedCellsAndRANNodesForPaging.h"
#include "Ngap_PDUSessionResourceListCxtRelCpl.h"
#include "Ngap_PDUSessionResourceReleasedListPSFail.h"
#include "Ngap_UnavailableGUAMIList.h"
#include "Ngap_PDUSessionResourceListCxtRelReq.h"
#include "Ngap_PDUSessionResourceSetupListSUReq.h"
#include "Ngap_PDUSessionResourceSetupListCxtRes.h"
#include "Ngap_PDUSessionResourceFailedToSetupListCxtRes.h"
#include "Ngap_UE-NGAP-IDs.h"
#include "Ngap_RRCEstablishmentCause.h"
#include "Ngap_UEContextRequest.h"
#include "Ngap_RepetitionPeriod.h"
#include "Ngap_NumberOfBroadcastsRequested.h"
#include "Ngap_WarningType.h"
#include "Ngap_WarningSecurityInfo.h"
#include "Ngap_DataCodingScheme.h"
#include "Ngap_WarningMessageContents.h"
#include "Ngap_ConcurrentWarningMessageInd.h"
#include "Ngap_WarningAreaCoordinates.h"
#include "Ngap_RANStatusTransfer-TransparentContainer.h"
#include "Ngap_HandoverType.h"
#include "Ngap_TargetID.h"
#include "Ngap_DirectForwardingPathAvailability.h"
#include "Ngap_PDUSessionResourceListHORqd.h"
#include "Ngap_SourceToTarget-TransparentContainer.h"
#include "Ngap_PDUSessionResourceSetupListCxtReq.h"
#include "Ngap_MaskedIMEISV.h"
#include "Ngap_PDUSessionResourceModifyListModCfm.h"
#include "Ngap_PDUSessionResourceFailedToModifyListModCfm.h"
#include "Ngap_RRCState.h"
#include "Ngap_DirectForwardingPathAvailability.h"
#include "Ngap_PDUSessionResourceListHORqd.h"
#include "Ngap_SourceToTarget-TransparentContainer.h"
#include "Ngap_NASSecurityParametersFromNGRAN.h"
#include "Ngap_PDUSessionResourceHandoverList.h"
#include "Ngap_PDUSessionResourceToReleaseListHOCmd.h"
#include "Ngap_PDUSessionResourceSetupListCxtReq.h"
#include "Ngap_RANNodeName.h"
#include "Ngap_SupportedTAList.h"
#include "Ngap_SupportedTAItem.h"
#include "Ngap_BroadcastPLMNItem.h"
#include "Ngap_MaskedIMEISV.h"
#include "Ngap_RRCState.h"
#include "Ngap_PDUSessionResourceReleasedListRelRes.h"
#include "Ngap_PDUSessionResourceModifyListModCfm.h"
#include "Ngap_PDUSessionResourceFailedToModifyListModCfm.h"
#include "Ngap_RANNodeName.h"
#include "Ngap_SupportedTAList.h"
#include "Ngap_CellIDListForRestart.h"
#include "Ngap_TAIListForRestart.h"
#include "Ngap_EmergencyAreaIDListForRestart.h"
#include "Ngap_PDUSessionResourceNotifyList.h"
#include "Ngap_PDUSessionResourceReleasedListNot.h"
#include "Ngap_PDUSessionResourceSetupListHOReq.h"
#include "Ngap_PDUSessionResourceModifyListModReq.h"
#include "Ngap_ProcedureCode.h"
#include "Ngap_Criticality.h"
#include "Ngap_DownlinkNonUEAssociatedNRPPaTransport.h"
#include "Ngap_UETNLABindingReleaseRequest.h"
#include "Ngap_NGSetupFailure.h"
#include "Ngap_AMFConfigurationUpdate.h"
#include "Ngap_InitialContextSetupFailure.h"
#include "Ngap_UEContextModificationRequest.h"
#include "Ngap_UplinkNonUEAssociatedNRPPaTransport.h"
#include "Ngap_UERadioCapabilityCheckResponse.h"
#include "Ngap_LocationReport.h"
#include "Ngap_PWSFailureIndication.h"
#include "Ngap_HandoverNotify.h"
#include "Ngap_PDUSessionResourceReleaseCommand.h"
#include "Ngap_UERadioCapabilityInfoIndication.h"
#include "Ngap_PWSCancelResponse.h"
#include "Ngap_DownlinkUEAssociatedNRPPaTransport.h"
#include "Ngap_HandoverRequestAcknowledge.h"
#include "Ngap_UplinkNASTransport.h"
#include "Ngap_WriteReplaceWarningResponse.h"
#include "Ngap_PathSwitchRequestAcknowledge.h"
#include "Ngap_TraceStart.h"
#include "Ngap_RANConfigurationUpdateAcknowledge.h"
#include "Ngap_OverloadStart.h"
#include "Ngap_AMFConfigurationUpdateAcknowledge.h"
#include "Ngap_NGSetupResponse.h"
#include "Ngap_PDUSessionResourceModifyResponse.h"
#include "Ngap_DownlinkNASTransport.h"
#include "Ngap_PDUSessionResourceSetupResponse.h"
#include "Ngap_UplinkUEAssociatedNRPPaTransport.h"
#include "Ngap_CellTrafficTrace.h"
#include "Ngap_PDUSessionResourceModifyIndication.h"
#include "Ngap_UplinkRANConfigurationTransfer.h"
#include "Ngap_Paging.h"
#include "Ngap_PathSwitchRequest.h"
#include "Ngap_PWSCancelRequest.h"
#include "Ngap_DeactivateTrace.h"
#include "Ngap_UEContextReleaseComplete.h"
#include "Ngap_LocationReportingControl.h"
#include "Ngap_PathSwitchRequestFailure.h"
#include "Ngap_HandoverCancelAcknowledge.h"
#include "Ngap_HandoverFailure.h"
#include "Ngap_HandoverCancel.h"
#include "Ngap_AMFStatusIndication.h"
#include "Ngap_LocationReportingFailureIndication.h"
#include "Ngap_AMFConfigurationUpdateFailure.h"
#include "Ngap_UEContextReleaseRequest.h"
#include "Ngap_DownlinkRANConfigurationTransfer.h"
#include "Ngap_PDUSessionResourceSetupRequest.h"
#include "Ngap_InitialContextSetupResponse.h"
#include "Ngap_UERadioCapabilityCheckRequest.h"
#include "Ngap_UEContextReleaseCommand.h"
#include "Ngap_HandoverPreparationFailure.h"
#include "Ngap_InitialUEMessage.h"
#include "Ngap_WriteReplaceWarningRequest.h"
#include "Ngap_UplinkRANStatusTransfer.h"
#include "Ngap_HandoverRequired.h"
#include "Ngap_InitialContextSetupRequest.h"
#include "Ngap_PDUSessionResourceModifyConfirm.h"
#include "Ngap_RANConfigurationUpdateFailure.h"
#include "Ngap_RRCInactiveTransitionReport.h"
#include "Ngap_NASNonDeliveryIndication.h"
#include "Ngap_HandoverCommand.h"
#include "Ngap_NGSetupRequest.h"
#include "Ngap_UEContextModificationResponse.h"
#include "Ngap_PDUSessionResourceReleaseResponse.h"
#include "Ngap_DownlinkRANStatusTransfer.h"
#include "Ngap_TraceFailureIndication.h"
#include "Ngap_RANConfigurationUpdate.h"
#include "Ngap_PWSRestartIndication.h"
#include "Ngap_PDUSessionResourceNotify.h"
#include "Ngap_UEContextModificationFailure.h"
#include "Ngap_RerouteNASRequest.h"
#include "Ngap_HandoverRequest.h"
#include "Ngap_NGResetAcknowledge.h"
#include "Ngap_PDUSessionResourceModifyRequest.h"
#include "Ngap_InitialContextSetupResponse.h"
#include "Ngap_UERadioCapabilityCheckRequest.h"
#include "Ngap_UEContextReleaseCommand.h"
#include "Ngap_HandoverPreparationFailure.h"
#include "Ngap_InitialUEMessage.h"
#include "Ngap_WriteReplaceWarningRequest.h"
#include "Ngap_UplinkRANStatusTransfer.h"
#include "Ngap_HandoverRequired.h"
#include "Ngap_InitialContextSetupRequest.h"
#include "Ngap_PDUSessionResourceModifyConfirm.h"
#include "Ngap_RANConfigurationUpdateFailure.h"
#include "Ngap_RRCInactiveTransitionReport.h"
#include "Ngap_NASNonDeliveryIndication.h"
#include "Ngap_HandoverCommand.h"
#include "Ngap_InitiatingMessage.h"
#include "Ngap_SuccessfulOutcome.h"
#include "Ngap_UnsuccessfulOutcome.h"
#include "Ngap_NGReset.h"
#include "Ngap_DownlinkNonUEAssociatedNRPPaTransport.h"
#include "Ngap_UETNLABindingReleaseRequest.h"
#include "Ngap_NGSetupFailure.h"
#include "Ngap_AMFConfigurationUpdate.h"
#include "Ngap_InitialContextSetupFailure.h"
#include "Ngap_ErrorIndication.h"
#include "Ngap_NGRAN-CGI.h"
#include "Ngap_GUAMI.h"
#include "Ngap_ProtocolIE-Field.h"
#include "Ngap_ProtocolIE-ID.h"
#include "Ngap_PLMNIdentity.h"
#include "Ngap_BroadcastPLMNList.h"
#include "Ngap_TAC.h"
#include "Ngap_ServedGUAMIItem.h"
#include "Ngap_GNB-ID.h"
#include "Ngap_NGAP-PDU.h"
#endif
#include "assertions.h"
//#include "log.h"
#define true 1
#define false 0
#define NGAP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
do {\
IE_TYPE **ptr; \
......
......@@ -171,15 +171,6 @@ typedef struct qos_profile_s {
} parameter;
} qos_profile_t;
enum class multipart_related_content_part_e {
JSON = 0,
NAS = 1,
NGAP = 2
};
static const std::vector<std::string> multipart_related_content_part_e2str = {
"JSON", "NAS", "NGAP" };
#define NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL "/namf-comm/v2/ue-contexts/{}/n1-n2-messages" //may get from configuration file
#define NUDM_SDM_GET_SM_DATA_URL "/nudm-sdm/v2/{}/sm-data" //may get from configuration file
#define N1_SM_CONTENT_ID "n1SmMsg"
......
......@@ -36,7 +36,7 @@ set(CN_UTILS_SRC STATIC
${CMAKE_CURRENT_SOURCE_DIR}/pid_file.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string.cpp
${CMAKE_CURRENT_SOURCE_DIR}/thread_sched.cpp
${CMAKE_CURRENT_SOURCE_DIR}/simple_parser.cpp
${CMAKE_CURRENT_SOURCE_DIR}/mime_parser.cpp
)
......
......@@ -13,14 +13,13 @@
* limitations under the License.
*/
#include "simple_parser.hpp"
#include "mime_parser.hpp"
#include "logger.hpp"
#include "conversions.hpp"
bool simple_parser::parse(const std::string &str) {
bool mime_parser::parse(const std::string &str) {
std::string CRLF = "\r\n";
Logger::smf_app().debug("");
Logger::smf_app().debug("Simple parser, parsing a string:");
Logger::smf_app().debug("%s", str.c_str());
Logger::smf_app().debug("Parsing the message with Simple Parser");
//find boundary
std::size_t content_type_pos = str.find("Content-Type"); //first part
......@@ -61,9 +60,99 @@ bool simple_parser::parse(const std::string &str) {
return true;
}
void simple_parser::get_mime_parts(std::vector<mime_part> &parts) const {
void mime_parser::get_mime_parts(std::vector<mime_part> &parts) const {
for (auto it : mime_parts) {
parts.push_back(it);
}
}
//---------------------------------------------------------------------------------------------
unsigned char* mime_parser::format_string_as_hex(const std::string &str) {
unsigned int str_len = str.length();
char *data = (char*) malloc(str_len + 1);
memset(data, 0, str_len + 1);
memcpy((void*) data, (void*) str.c_str(), str_len);
unsigned char *data_hex = (uint8_t*) malloc(str_len / 2 + 1);
conv::ascii_to_hex(data_hex, (const char*) data);
Logger::smf_app().debug("[Format string as Hex] Input string (%d bytes): %s ",
str_len, str.c_str());
Logger::smf_app().debug("Data (formatted):");
#if DEBUG_IS_ON
for (int i = 0; i < str_len / 2; i++)
printf(" %02x ", data_hex[i]);
printf("\n");
#endif
//free memory
//free_wrapper((void**) &data);
free(data);
data = NULL;
return data_hex;
}
//------------------------------------------------------------------------------
void mime_parser::create_multipart_related_content(std::string &body,
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message) {
//format string as hex
unsigned char *n1_msg_hex = format_string_as_hex(n1_message);
unsigned char *n2_msg_hex = format_string_as_hex(n2_message);
std::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);
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF + "Content-Id: n1SmMsg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n1_msg_hex, n1_message.length() / 2) + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n2_msg_hex, n2_message.length() / 2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
//------------------------------------------------------------------------------
void mime_parser::create_multipart_related_content(
std::string &body, const std::string &json_part, const std::string boundary,
const std::string &message, const multipart_related_content_part_e content_type) {
//format string as hex
unsigned char *msg_hex = format_string_as_hex(message);
std::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);
if (content_type == multipart_related_content_part_e::NAS) { //NAS
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF
+ "Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { //NGAP
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
+ CRLF);
}
body.append(CRLF);
body.append(std::string((char*) msg_hex, message.length() / 2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file mime_parser.hpp
\brief
\author
\company Eurecom
\email:
*/
#ifndef FILE_MIME_PARSER_HPP_SEEN
#define FILE_MIME_PARSER_HPP_SEEN
# include <string>
#include <map>
#include <vector>
enum class multipart_related_content_part_e {
JSON = 0,
NAS = 1,
NGAP = 2
};
static const std::vector<std::string> multipart_related_content_part_e2str = {
"JSON", "NAS", "NGAP" };
typedef struct mime_part {
std::string content_type;
std::string body;
} mime_part;
class mime_parser {
public:
/*
* Parse the input string into different Mime parts
* @param [const std::string &] str: input string
* @return void
*/
bool parse(const std::string &str);
/*
* Get vector of Mime parts
* @param [std::vector<mime_part> &] parts: store vector of Mime parts
* @return void
*/
void get_mime_parts(std::vector<mime_part> &parts) const;
/*
* Represent a string as hex
* @param [const std::string&] str: input string
* @return String represents string in hex format
*/
unsigned char* format_string_as_hex(const std::string &str);
/*
* Create HTTP body content for multipart/related message
* @param [std::string] body: Body of the created message
* @param [std::string] json_part: Json part of multipart/related msg
* @param [std::string] boundary: Boundary of multipart/related msg
* @param [std::string] n1_message: N1 (NAS) part
* @param [std::string] n2_message: N2 (NGAP) part
* @return void
*/
void create_multipart_related_content(std::string &body,
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message);
/*
* Create HTTP body content for multipart/related message
* @param [std::string] body: Body of the created message
* @param [std::string] json_part: Json part of multipart/related msg
* @param [std::string] boundary: Boundary of multipart/related msg
* @param [std::string] message: N1 (NAS) or N2 (NGAP) part
* @param [uint8_t] content_type: 1 for NAS content, else NGAP content
* @return void
*/
void create_multipart_related_content(
std::string &body, const std::string &json_part,
const std::string boundary, const std::string &message,
const multipart_related_content_part_e content_type);
private:
std::vector<mime_part> mime_parts;
};
#endif /* FILE_MIME_PARSER_HPP_SEEN */
......@@ -111,7 +111,6 @@ typedef enum {
N11_SESSION_CREATE_SM_CONTEXT_RESPONSE,
N11_SESSION_UPDATE_SM_CONTEXT_REQUEST,
N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE,
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,
......
......@@ -253,8 +253,7 @@ pkg_search_module(CONFIG REQUIRED libconfig++)
include_directories(${CONFIG_INCLUDE_DIRS})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
#find_package(Threads REQUIRED)
################################################################
# Add sub modules
......@@ -277,17 +276,17 @@ ADD_SUBDIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../../src/api-server ${CMAKE_CURREN
################################################################################
# Specific part for oai_smf folder
#SMF_API
set(SMF_API_SERVER_DIR "${SRC_TOP_DIR}/api-server")
file(GLOB SMF_API_SERVER_src_files
${SMF_API_SERVER_DIR}/smf-http2-server.cpp
${SMF_API_SERVER_DIR}/smf-api-server.cpp
${SMF_API_SERVER_DIR}/model/*.cpp
${SMF_API_SERVER_DIR}/api/*.cpp
${SMF_API_SERVER_DIR}/impl/*.cpp
)
set(SMF_API_SERVER_include_files
${SMF_API_SERVER_DIR}/api
${SMF_API_SERVER_DIR}/impl
......@@ -295,7 +294,7 @@ set(SMF_API_SERVER_include_files
${SMF_API_SERVER_DIR}
)
add_library(SMF_API ${SMF_API_SERVER_src_files})
#for NAS
set(NAS_DIR "${SRC_TOP_DIR}/nas")
......@@ -377,7 +376,8 @@ IF(STATIC_LINKING)
# asan do not support static linking
SET(ASAN)
ENDIF(STATIC_LINKING)
target_link_libraries (smf ${ASAN} -Wl,--start-group CN_UTILS SMF UDP GTPV2C PFCP 3GPP_COMMON_TYPES SMF_API -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} NAS gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
target_link_libraries (smf ${ASAN}
-Wl,--start-group CN_UTILS SMF UDP GTPV2C PFCP 3GPP_COMMON_TYPES SMF_API -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} -lnghttp2_asio -lboost_system -lboost_thread -lssl -lcrypto NAS gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
\ No newline at end of file
......@@ -27,6 +27,7 @@
#include "pistache/endpoint.h"
#include "pistache/http.h"
#include "pistache/router.h"
#include "smf-http2-server.h"
#include <iostream>
#include <thread>
......@@ -121,13 +122,16 @@ int main(int argc, char **argv)
exit (-EDEADLK);
}
//SMF API server
//SMF Pistache API server (HTTP1)
Pistache::Address addr(std::string(inet_ntoa (*((struct in_addr *)&smf_cfg.sbi.addr4))) , Pistache::Port(smf_cfg.sbi.port));
SMFApiServer smfApiServer(addr, smf_app_inst);
smfApiServer.init(2);
std::thread smf_api_manager(&SMFApiServer::start, smfApiServer);
//SMF NGHTTP API server (HTTP2)
smf_http2_server *smf_server = new smf_http2_server(conv::toString(smf_cfg.sbi.addr4), smf_cfg.sbi_http2_port, smf_app_inst);
std::thread smf_api(&smf_http2_server::start, smf_server);
FILE *fp = NULL;
std::string filename = fmt::format("/tmp/smf_{}.status", getpid());
fp = fopen(filename.c_str(), "w+");
......
......@@ -39,6 +39,7 @@
#include "itti.hpp"
#include "logger.hpp"
#include "string.hpp"
#include "3gpp_29.500.h"
#include "3gpp_29.502.h"
#include "3gpp_24.007.h"
#include "smf.h"
......@@ -222,6 +223,27 @@ void smf_app_task(void*) {
shared_msg));
break;
case N11_SESSION_CREATE_SM_CONTEXT_RESPONSE:
if (itti_n11_create_sm_context_response *m =
dynamic_cast<itti_n11_create_sm_context_response*>(msg)) {
smf_app_inst->handle_itti_msg(std::ref(*m));
}
break;
case N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE:
if (itti_n11_update_sm_context_response *m =
dynamic_cast<itti_n11_update_sm_context_response*>(msg)) {
smf_app_inst->handle_itti_msg(std::ref(*m));
}
break;
case N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE:
if (itti_n11_release_sm_context_response *m =
dynamic_cast<itti_n11_release_sm_context_response*>(msg)) {
smf_app_inst->handle_itti_msg(std::ref(*m));
}
break;
case TIME_OUT:
if (itti_msg_timeout *to = dynamic_cast<itti_msg_timeout*>(msg)) {
Logger::smf_app().info("TIME-OUT event timer id %d", to->timer_id);
......@@ -233,16 +255,19 @@ void smf_app_task(void*) {
;
}
}
break;
case TERMINATE:
if (itti_msg_terminate *terminate =
dynamic_cast<itti_msg_terminate*>(msg)) {
Logger::smf_app().info("Received terminate message");
return;
}
break;
case HEALTH_PING:
break;
default:
Logger::smf_app().info("no handler for msg type %d", msg->msg_type);
}
......@@ -331,7 +356,7 @@ void smf_app::handle_itti_msg(itti_n4_session_establishment_response &seresp) {
pc.get()->handle_itti_msg(seresp);
} else {
Logger::smf_app().debug(
"Received N4 SESSION ESTABLISHMENT RESPONSE seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
"Received N4 Session Establishment Response seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
seresp.seid, seresp.trxn_id);
}
}
......@@ -343,7 +368,7 @@ void smf_app::handle_itti_msg(itti_n4_session_modification_response &smresp) {
pc.get()->handle_itti_msg(smresp);
} else {
Logger::smf_app().debug(
"Received N4 SESSION MODIFICATION RESPONSE seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
"Received N4 Session Modification Response seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
smresp.seid, smresp.trxn_id);
}
}
......@@ -359,7 +384,7 @@ void smf_app::handle_itti_msg(itti_n4_session_deletion_response &smresp) {
}
} else {
Logger::smf_app().debug(
"Received N4 SESSION DELETION RESPONSE seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
"Received N4 Session Deletion Response seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
smresp.seid, smresp.trxn_id);
}
}
......@@ -372,7 +397,7 @@ void smf_app::handle_itti_msg(
pc.get()->handle_itti_msg(snr);
} else {
Logger::smf_app().debug(
"Received N4 SESSION REPORT REQUEST seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
"Received N4 Session Report Request seid" TEID_FMT " pfcp_tx_id %" PRIX64", smf_context not found, discarded!",
snr->seid, snr->trxn_id);
}
}
......@@ -389,6 +414,7 @@ void smf_app::handle_itti_msg(
pdu_session_status_e status =
{ pdu_session_status_e::PDU_SESSION_INACTIVE };
upCnx_state_e state = { upCnx_state_e::UPCNX_STATE_DEACTIVATED };
if ((static_cast<http_response_codes_e>(m.response_code)
== http_response_codes_e::HTTP_RESPONSE_CODE_OK)
or (static_cast<http_response_codes_e>(m.response_code)
......@@ -402,19 +428,20 @@ void smf_app::handle_itti_msg(
update_pdu_session_status(m.scid, status);
update_pdu_session_upCnx_state(m.scid, state);
Logger::smf_app().debug(
"Got successful response from AMF (Response code %d), set session status to %s",
"Got successful response from AMF (response code %d), set session status to %s",
m.response_code,
pdu_session_status_e2str[static_cast<int>(status)].c_str());
} else {
//TODO:
Logger::smf_app().debug("Got response from AMF (Response code %d)",
Logger::smf_app().debug("Got response from AMF (response code %d)",
m.response_code);
}
}
break;
case session_management_procedures_type_e::SERVICE_REQUEST_NETWORK_TRIGGERED: {
Logger::smf_app().debug("Got response from AMF (Response code %d) with cause %s",
m.response_code, m.cause.c_str());
Logger::smf_app().debug(
"Got response from AMF (response code %d) with cause %s",
m.response_code, m.cause.c_str());
if ((static_cast<http_response_codes_e>(m.response_code)
!= http_response_codes_e::HTTP_RESPONSE_CODE_OK)
and (static_cast<http_response_codes_e>(m.response_code)
......@@ -425,7 +452,6 @@ void smf_app::handle_itti_msg(
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
Logger::smf_app().info("REMOTE_PEER_NOT_RESPONDING");
return;
}
......@@ -435,13 +461,12 @@ void smf_app::handle_itti_msg(
itti_n4->seid = m.seid;
itti_n4->trxn_id = m.trxn_id;
itti_n4->r_endpoint = endpoint(up_node_id.u1.ipv4_address,
pfcp::default_port);
pfcp::default_port);
std::shared_ptr<itti_n4_session_failure_indication> itti_n4_failure_indication =
std::shared_ptr<itti_n4_session_failure_indication>(itti_n4);
Logger::smf_app().info(
"Sending ITTI message %s to task TASK_SMF_N4",
itti_n4->get_msg_name());
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N4",
itti_n4->get_msg_name());
int ret = itti_inst->send_msg(itti_n4_failure_indication);
if (RETURNok != ret) {
Logger::smf_app().error(
......@@ -449,15 +474,14 @@ void smf_app::handle_itti_msg(
itti_n4->get_msg_name());
return;
}
}
}
break;
default: {
//TODO:
}
}
}
//------------------------------------------------------------------------------
......@@ -468,11 +492,36 @@ void smf_app::handle_itti_msg(itti_n11_update_pdu_session_status &m) {
update_pdu_session_status(m.scid, m.pdu_session_status);
}
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(itti_n11_create_sm_context_response &m) {
Logger::smf_app().debug(
"PDU Session Create SM Context: Set promise with ID %d to ready", m.pid);
pdu_session_create_sm_context_response sm_context_response = { };
sm_context_create_promises[m.pid]->set_value(m.res);
}
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(itti_n11_update_sm_context_response &m) {
Logger::smf_app().debug(
"PDU Session Update SM Context: Set promise with ID %d to ready", m.pid);
pdu_session_update_sm_context_response sm_context_response = { };
sm_context_update_promises[m.pid]->set_value(m.res);
}
//------------------------------------------------------------------------------
void smf_app::handle_itti_msg(itti_n11_release_sm_context_response &m) {
Logger::smf_app().debug(
"PDU Session Release SM Context: Set promise with ID %d to ready", m.pid);
pdu_session_release_sm_context_response sm_context_response = { };
sm_context_release_promises[m.pid]->set_value(m.res);
}
//------------------------------------------------------------------------------
void smf_app::handle_pdu_session_create_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_request> smreq) {
Logger::smf_app().info(
"Handle a PDU Session Create SM Context Request from an AMF");
"Handle a PDU Session Create SM Context Request from an AMF (HTTP version %d)",
smreq->http_version);
//handle PDU Session Create SM Context Request as specified in section 4.3.2 3GPP TS 23.502
oai::smf_server::model::SmContextCreateError smContextCreateError = { };
oai::smf_server::model::ProblemDetails problem_details = { };
......@@ -486,7 +535,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
//Step 1. Decode NAS and get the necessary information
std::string n1_sm_msg = smreq->req.get_n1_sm_message();
memset(&decoded_nas_msg, 0, sizeof(nas_message_t));
int decoder_rc = smf_n1_n2_inst.decode_n1_sm_container(decoded_nas_msg,
n1_sm_msg);
......@@ -502,9 +550,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
return;
}
......@@ -553,9 +601,10 @@ void smf_app::handle_pdu_session_create_sm_context_request(
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(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
return;
}
//TODO: SSCMode
......@@ -598,9 +647,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_81_INVALID_PTI_VALUE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
return;
}
smreq->req.set_pti(pti);
......@@ -630,9 +679,10 @@ void smf_app::handle_pdu_session_create_sm_context_request(
n1_sm_message,
cause_value_5gsm_e::CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
return;
}
//check request type
......@@ -650,7 +700,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
if (not smf_cfg.is_dotted_dnn_handled(dnn, pdu_session_type)) {
// Not a valid request...
Logger::smf_app().warn(
"Received PDU_SESSION_CREATESMCONTEXT_REQUEST unknown requested DNN %s, ignore message!",
"Received a PDU Session Create SM Context Request: unknown requested DNN %s, ignore message!",
dnn.c_str());
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_DNN_DENIED]);
......@@ -662,9 +712,9 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_27_MISSING_OR_UNKNOWN_DNN);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
return;
}
......@@ -721,7 +771,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
} else {
// Cannot retrieve information from UDM, reject PDU session establishment
Logger::smf_app().warn(
"Received PDU_SESSION_CREATESMCONTEXT_REQUEST, couldn't retrieve the Session Management Subscription from UDM, ignore message!");
"Received a PDU Session Create SM Context Request, couldn't retrieve the Session Management Subscription from UDM, ignore message!");
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED]);
smContextCreateError.setError(problem_details);
......@@ -734,10 +784,10 @@ void smf_app::handle_pdu_session_create_sm_context_request(
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//Send response (PDU Session Establishment Reject) to AMF
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
return;
}
} else {
......@@ -749,7 +799,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
//update dnn_context with subscription info
sc.get()->insert_dnn_subscription(snssai, subscription);
}
}
}
......@@ -766,7 +815,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
//store scid in the context itself
sc.get()->set_scid(scid);
Logger::smf_app().debug("Generated a SCID " SCID_FMT " ", scid);
Logger::smf_app().debug("Generated a SMF Context ID " SCID_FMT " ", scid);
//Step 8. let the context handle the message
sc.get()->handle_pdu_session_create_sm_context_request(smreq);
......@@ -776,9 +825,11 @@ void smf_app::handle_pdu_session_create_sm_context_request(
//------------------------------------------------------------------------------
void smf_app::handle_pdu_session_update_sm_context_request(
std::shared_ptr<itti_n11_update_sm_context_request> smreq) {
//handle PDU Session Update SM Context Request as specified in section 4.3.2 3GPP TS 23.502
Logger::smf_app().info(
"Handle a PDU Session Update SM Context Request from an AMF");
"Handle a PDU Session Update SM Context Request from an AMF (HTTP version %d)",
smreq->http_version);
oai::smf_server::model::SmContextUpdateError smContextUpdateError = { };
oai::smf_server::model::ProblemDetails problem_details = { };
......@@ -793,9 +844,9 @@ void smf_app::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smContextUpdateError, smreq->pid);
return;
}
......@@ -809,9 +860,9 @@ void smf_app::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smContextUpdateError, smreq->pid);
return;
}
......@@ -836,9 +887,9 @@ void smf_app::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smContextUpdateError, smreq->pid);
return;
}
......@@ -853,9 +904,9 @@ void smf_app::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smContextUpdateError, smreq->pid);
return;
}
}
......@@ -866,12 +917,9 @@ void smf_app::handle_pdu_session_update_sm_context_request(
sc.get()->handle_pdu_session_update_sm_context_request(smreq);
}
//------------------------------------------------------------------------------
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");
......@@ -884,9 +932,9 @@ void smf_app::handle_pdu_session_release_sm_context_request(
} 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);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smreq->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
......@@ -897,8 +945,9 @@ void smf_app::handle_pdu_session_release_sm_context_request(
} 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);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smreq->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
......@@ -920,9 +969,9 @@ void smf_app::handle_pdu_session_release_sm_context_request(
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);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smreq->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
......@@ -934,23 +983,23 @@ void smf_app::handle_pdu_session_release_sm_context_request(
//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);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smreq->pid,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
}
//Step 3. handle the message in smf_context
sc.get()->handle_pdu_session_release_sm_context_request(smreq);
}
//------------------------------------------------------------------------------
void smf_app::trigger_pdu_session_modification(const supi_t &supi, const std::string &dnn,
const pdu_session_id_t pdu_session_id,
const snssai_t &snssai,
const pfcp::qfi_t &qfi) {
void smf_app::trigger_pdu_session_modification(
const supi_t &supi, const std::string &dnn,
const pdu_session_id_t pdu_session_id, const snssai_t &snssai,
const pfcp::qfi_t &qfi, const uint8_t &http_version) {
//SMF-requested session modification, see section 4.3.3.2@3GPP TS 23.502
//The SMF may decide to modify PDU Session. This procedure also may be
//triggered based on locally configured policy or triggered from the (R)AN (see clause 4.2.6 and clause 4.9.1).
......@@ -961,6 +1010,7 @@ void smf_app::trigger_pdu_session_modification(const supi_t &supi, const std::st
std::shared_ptr<itti_nx_trigger_pdu_session_modification> itti_msg =
std::make_shared<itti_nx_trigger_pdu_session_modification>(TASK_SMF_APP,
TASK_SMF_N11);
itti_msg->http_version = http_version;
//step 1. collect the necessary information
/*
......@@ -1060,9 +1110,8 @@ bool smf_app::use_local_configuration_subscription_data(
}
//------------------------------------------------------------------------------
bool smf_app::is_supi_dnn_snssai_subscription_data(const supi_t &supi,
const std::string &dnn,
const snssai_t &snssai) const {
bool smf_app::is_supi_dnn_snssai_subscription_data(
const supi_t &supi, const std::string &dnn, const snssai_t &snssai) const {
//TODO: should be implemented
return false; //Session Management Subscription from UDM isn't available
}
......@@ -1071,7 +1120,6 @@ bool smf_app::is_supi_dnn_snssai_subscription_data(const supi_t &supi,
bool smf_app::is_create_sm_context_request_valid() const {
//TODO: should be implemented
return true;
}
//---------------------------------------------------------------------------------------------
......@@ -1126,7 +1174,6 @@ unsigned char* smf_app::format_string_as_hex(const std::string &str) {
free_wrapper((void**) &data);
return data_hex;
}
//---------------------------------------------------------------------------------------------
......@@ -1245,7 +1292,8 @@ void smf_app::timer_t3591_timeout(timer_id_t timer_id, uint64_t arg2_user) {
}
//---------------------------------------------------------------------------------------------
n2_sm_info_type_e smf_app::n2_sm_info_type_str2e(const std::string &n2_info_type) const {
n2_sm_info_type_e smf_app::n2_sm_info_type_str2e(
const std::string &n2_info_type) const {
std::size_t number_of_types = n2_sm_info_type_e2str.size();
for (auto i = 0; i < number_of_types; ++i) {
if (n2_info_type.compare(n2_sm_info_type_e2str[i]) == 0) {
......@@ -1254,6 +1302,7 @@ n2_sm_info_type_e smf_app::n2_sm_info_type_str2e(const std::string &n2_info_type
}
}
//---------------------------------------------------------------------------------------------
bool smf_app::get_session_management_subscription_data(
const supi64_t &supi, const std::string &dnn, const snssai_t &snssai,
std::shared_ptr<session_management_subscription> subscription) {
......@@ -1317,11 +1366,140 @@ bool smf_app::get_session_management_subscription_data(
subscription->insert_dnn_configuration(dnn, dnn_configuration);
return true;
}
}
return false;
}
//---------------------------------------------------------------------------------------------
void smf_app::add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_create_sm_context_response> > &p) {
sm_context_create_promises.emplace(id, p);
}
//---------------------------------------------------------------------------------------------
void smf_app::add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_update_sm_context_response> > &p) {
sm_context_update_promises.emplace(id, p);
}
//---------------------------------------------------------------------------------------------
void smf_app::add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_release_sm_context_response> > &p) {
sm_context_release_promises.emplace(id, p);
}
//---------------------------------------------------------------------------------------------
void smf_app::trigger_http_response(
const uint32_t &http_code,
const oai::smf_server::model::SmContextCreateError &smContextCreateError,
const std::string &n1_sm_msg, uint32_t &promise_id) {
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of Server");
std::shared_ptr<itti_n11_create_sm_context_response> itti_msg =
std::make_shared<itti_n11_create_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
pdu_session_create_sm_context_response sm_context_response = { };
nlohmann::json json_data = { };
to_json(json_data, smContextCreateError);
sm_context_response.set_json_data(json_data);
sm_context_response.set_n1_sm_message(n1_sm_msg);
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
}
//---------------------------------------------------------------------------------------------
void smf_app::trigger_http_response(
const uint32_t &http_code,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
uint32_t &promise_id) {
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of API Server");
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
std::make_shared<itti_n11_update_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
pdu_session_update_sm_context_response sm_context_response = { };
nlohmann::json json_data = { };
to_json(json_data, smContextUpdateError);
sm_context_response.set_json_data(json_data);
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
}
//---------------------------------------------------------------------------------------------
void smf_app::trigger_http_response(
const uint32_t &http_code,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
const std::string &n1_sm_msg, uint32_t &promise_id) {
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of HTTP Server");
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
std::make_shared<itti_n11_update_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
pdu_session_update_sm_context_response sm_context_response = { };
nlohmann::json json_data = { };
to_json(json_data, smContextUpdateError);
sm_context_response.set_json_data(json_data);
sm_context_response.set_n1_sm_message(n1_sm_msg);
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
}
//---------------------------------------------------------------------------------------------
void smf_app::trigger_http_response(const uint32_t &http_code,
uint32_t &promise_id, uint8_t msg_type) {
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of HTTP Server");
switch (msg_type) {
case N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE: {
std::shared_ptr<itti_n11_release_sm_context_response> itti_msg =
std::make_shared<itti_n11_release_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
pdu_session_release_sm_context_response sm_context_response = { };
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
}
break;
case N11_SESSION_CREATE_SM_CONTEXT_RESPONSE: {
}
break;
default: {
}
}
}
......@@ -35,6 +35,7 @@
#include <shared_mutex>
#include <string>
#include <thread>
#include <future>
#include "pistache/endpoint.h"
#include "pistache/http.h"
......@@ -52,6 +53,10 @@
#include "SmContextCreateError.h"
#include "SmContextUpdateError.h"
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
namespace smf {
#define TASK_SMF_APP_TRIGGER_T3591 (0)
......@@ -113,6 +118,13 @@ class smf_app {
std::map<scid_t, std::shared_ptr<smf_context_ref>> scid2smf_context;
mutable std::shared_mutex m_scid2smf_context;
//Store promise IDs for Create/Update session
std::map<uint32_t,
boost::shared_ptr<boost::promise<pdu_session_create_sm_context_response>>> sm_context_create_promises;
std::map<uint32_t,
boost::shared_ptr<boost::promise<pdu_session_update_sm_context_response>>> sm_context_update_promises;
std::map<uint32_t,
boost::shared_ptr<boost::promise<pdu_session_release_sm_context_response>>> sm_context_release_promises;
/*
* Apply the config from the configuration file for DNN pools
......@@ -285,6 +297,27 @@ class smf_app {
*/
void handle_itti_msg(itti_n11_update_pdu_session_status &snu);
/*
* Handle ITTI message N11 Create SM Context Response to trigger the response to AMF
* @param [itti_n11_create_sm_context_response&] snc
* @return void
*/
void handle_itti_msg(itti_n11_create_sm_context_response &snc);
/*
* Handle ITTI message N11 Update SM Context Response to trigger the response to AMF
* @param [itti_n11_update_sm_context_response&] m
* @return void
*/
void handle_itti_msg(itti_n11_update_sm_context_response &m);
/*
* Handle ITTI message N11 Release SM Context Response to trigger the response to AMF
* @param [itti_n11_release_sm_context_response&] m
* @return void
*/
void handle_itti_msg(itti_n11_release_sm_context_response &m);
/*
* Handle ITTI message from N11 (N1N2MessageTransfer Response)
* @param [itti_n11_n1n2_message_transfer_response_status&] snm
......@@ -381,7 +414,6 @@ 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
......@@ -399,9 +431,12 @@ class smf_app {
* @param [const pfcp::qfi_t &] qfi
* @return void
*/
void trigger_pdu_session_modification(const supi_t &supi, const std::string &dnn,
void trigger_pdu_session_modification(const supi_t &supi,
const std::string &dnn,
const pdu_session_id_t pdu_session_id,
const snssai_t &snssai, const pfcp::qfi_t &qfi);
const snssai_t &snssai,
const pfcp::qfi_t &qfi,
const uint8_t &http_version);
/*
* Verify if SM Context is existed for this Supi
......@@ -494,7 +529,8 @@ class smf_app {
* @param [const std::string] n2_info_type
* @return representing of N2 info type in a form of emum
*/
n2_sm_info_type_e n2_sm_info_type_str2e(const std::string &n2_info_type) const;
n2_sm_info_type_e n2_sm_info_type_str2e(
const std::string &n2_info_type) const;
/*
* Update PDU session UpCnxState
......@@ -520,6 +556,83 @@ class smf_app {
*/
void start_upf_association(const pfcp::node_id_t &node_id);
/*
* To store a promise of a PDU Session Create SM Contex Response to be triggered when the result is ready
* @param [uint32_t] id: promise id
* @param [boost::shared_ptr< boost::promise<pdu_session_create_sm_context_response> >&] p: pointer to the promise
* @return void
*/
void add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_create_sm_context_response> > &p);
/*
* To store a promise of a PDU Session Update SM Contex Response to be triggered when the result is ready
* @param [uint32_t] id: promise id
* @param [boost::shared_ptr< boost::promise<pdu_session_update_sm_context_response> >&] p: pointer to the promise
* @return void
*/
void add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_update_sm_context_response> > &p);
/*
* To store a promise of a PDU Session Release SM Context Response to be triggered when the result is ready
* @param [uint32_t] id: promise id
* @param [boost::shared_ptr< boost::promise<pdu_session_release_sm_context_response> >&] p: pointer to the promise
* @return void
*/
void add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_release_sm_context_response> > &p);
/*
* To trigger the response to the HTTP server by set the value of the corresponding promise to ready
* @param [const uint32_t &] http_code: Status code of HTTP response
* @param [const oai::smf_server::model::SmContextCreateError &] smContextCreateError: store the json content of response message
* @param [const std::string &] n1_sm_msg: N1 SM message
* @param [uint32_t &] promise_id: Promise Id
* @return void
*/
void trigger_http_response(
const uint32_t &http_code,
const oai::smf_server::model::SmContextCreateError &smContextCreateError,
const std::string &n1_sm_msg, uint32_t &promise_id);
/*
* To trigger the response to the HTTP server by set the value of the corresponding promise to ready
* @param [const uint32_t &] http_code: Status code of HTTP response
* @param [const oai::smf_server::model::SmContextCreateError &] smContextCreateError: store the json content of response message
* @param [uint32_t &] promise_id: Promise Id
* @return void
*/
void trigger_http_response(
const uint32_t &http_code,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
uint32_t &promise_id);
/*
* To trigger the response to the HTTP server by set the value of the corresponding promise to ready
* @param [const uint32_t &] http_code: Status code of HTTP response
* @param [const oai::smf_server::model::SmContextUpdateError &] smContextUpdateError: store the json content of response message
* @param [const std::string &] n1_sm_msg: N1 SM message
* @param [uint32_t &] promise_id: Promise Id
* @return void
*/
void trigger_http_response(
const uint32_t &http_code,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
const std::string &n1_sm_msg, uint32_t &promise_id);
/*
* To trigger the response to the HTTP server by set the value of the corresponding promise to ready
* @param [const uint32_t &] http_code: Status code of HTTP response
* @param [uint32_t &] promise_id: Promise Id
* @param [uint8_t] msg_type
* @return void
*/
void trigger_http_response(const uint32_t &http_code, uint32_t &promise_id,
uint8_t msg_type);
};
}
#include "smf_config.hpp"
......
......@@ -307,6 +307,12 @@ int smf_config::load(const string &config_file) {
const Setting &n11_cfg = nw_if_cfg[SMF_CONFIG_STRING_INTERFACE_SBI];
load_interface(n11_cfg, sbi);
//HTTP2 port
if (!(n11_cfg.lookupValue(SMF_CONFIG_STRING_SBI_HTTP2_PORT, sbi_http2_port))) {
Logger::smf_app().error(SMF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
throw(SMF_CONFIG_STRING_SBI_HTTP2_PORT "failed");
}
} catch (const SettingNotFoundException &nfex) {
Logger::smf_app().error("%s : %s", nfex.what(), nfex.getPath());
return RETURNerror ;
......@@ -673,6 +679,7 @@ void smf_config::display() {
Logger::smf_app().info(" ip ...................: %s",
inet_ntoa(sbi.addr4));
Logger::smf_app().info(" port .................: %d", sbi.port);
Logger::smf_app().info(" HTTP2 port ............: %d", sbi_http2_port);
Logger::smf_app().info("- N4 Threading:");
Logger::smf_app().info(" CPU id............: %d",
......
......@@ -54,6 +54,7 @@
#define SMF_CONFIG_STRING_PORT "PORT"
#define SMF_CONFIG_STRING_INTERFACE_N4 "N4"
#define SMF_CONFIG_STRING_INTERFACE_SBI "SBI"
#define SMF_CONFIG_STRING_SBI_HTTP2_PORT "HTTP2_PORT"
#define SMF_CONFIG_STRING_NAS_FORCE_PUSH_PCO "FORCE_PUSH_PROTOCOL_CONFIGURATION_OPTIONS"
......@@ -175,6 +176,7 @@ class smf_config {
interface_cfg_t n4;
interface_cfg_t sbi;
unsigned int sbi_http2_port;
itti_cfg_t itti;
test_upf_cfg_t test_upf_cfg;
......
......@@ -40,6 +40,7 @@
#include "smf_paa_dynamic.hpp"
#include "smf_procedure.hpp"
#include "ProblemDetails.h"
#include "3gpp_29.500.h"
#include "3gpp_29.502.h"
#include "3gpp_24.501.h"
#include "SmContextCreatedData.h"
......@@ -364,7 +365,6 @@ std::string smf_pdu_session::toString() const {
}
}
}
return s;
}
......@@ -512,7 +512,6 @@ void smf_pdu_session::add_qos_rule(const QOSRulesIE &qos_rule) {
Logger::smf_app().error(
"Failed to add rule (Id %d) failed: invalid rule Id", rule_id);
}
}
//------------------------------------------------------------------------------
......@@ -585,13 +584,13 @@ void smf_context::handle_itti_msg(
std::shared_ptr<smf_procedure> proc = { };
if (find_procedure(seresp.trxn_id, proc)) {
Logger::smf_app().debug(
"Received N4 SESSION ESTABLISHMENT RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64"",
"Received N4 Session Establishment Response sender teid " TEID_FMT " pfcp_tx_id %" PRIX64"",
seresp.seid, seresp.trxn_id);
proc->handle_itti_msg(seresp, shared_from_this());
remove_procedure(proc.get());
} else {
Logger::smf_app().debug(
"Received N4 SESSION ESTABLISHMENT RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", smf_procedure not found, discarded!",
"Received N4 Session Establishment Response sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", smf_procedure not found, discarded!",
seresp.seid, seresp.trxn_id);
}
}
......@@ -602,17 +601,17 @@ void smf_context::handle_itti_msg(
std::shared_ptr<smf_procedure> proc = { };
if (find_procedure(smresp.trxn_id, proc)) {
Logger::smf_app().debug(
"Received N4 SESSION MODIFICATION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64" ",
"Received N4 Session Modification Response sender teid " TEID_FMT " pfcp_tx_id %" PRIX64" ",
smresp.seid, smresp.trxn_id);
proc->handle_itti_msg(smresp, shared_from_this());
remove_procedure(proc.get());
} else {
Logger::smf_app().debug(
"Received N4 SESSION MODIFICATION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", smf_procedure not found, discarded!",
"Received N4 Session Modification Response sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", smf_procedure not found, discarded!",
smresp.seid, smresp.trxn_id);
}
Logger::smf_app().info(
"Handle N4 SESSION MODIFICATION RESPONSE with SMF context %s",
"Handle N4 Session Modification Response with SMF context %s",
toString().c_str());
}
......@@ -621,18 +620,18 @@ void smf_context::handle_itti_msg(itti_n4_session_deletion_response &sdresp) {
std::shared_ptr<smf_procedure> proc = { };
if (find_procedure(sdresp.trxn_id, proc)) {
Logger::smf_app().debug(
"Received N4 SESSION DELETION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64" ",
"Received N4 Session Deletion Response sender teid " TEID_FMT " pfcp_tx_id %" PRIX64" ",
sdresp.seid, sdresp.trxn_id);
proc->handle_itti_msg(sdresp, shared_from_this());
remove_procedure(proc.get());
} else {
Logger::smf_app().debug(
"Received N4 SESSION DELETION RESPONSE sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", smf_procedure not found, discarded!",
"Received N4 Session Deletion Response sender teid " TEID_FMT " pfcp_tx_id %" PRIX64", smf_procedure not found, discarded!",
sdresp.seid, sdresp.trxn_id);
}
Logger::smf_app().info(
"Handle N4 SESSION DELETION RESPONSE with SMF context %s",
"Handle N4 Session Deletion Response with SMF context %s",
toString().c_str());
}
......@@ -671,7 +670,6 @@ void smf_context::handle_itti_msg(
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
Logger::smf_app().info("REMOTE_PEER_NOT_RESPONDING");
return;
}
......@@ -739,23 +737,27 @@ void smf_context::handle_itti_msg(
session_report_msg.set_n2_sm_information(n2_sm_info_hex);
//Fill the json part
session_report_msg.n1n2_message_transfer_data["n2InfoContainer"]["n2InformationClass"] =
nlohmann::json json_data = { };
json_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
session_report_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
session_report_msg.get_pdu_session_id();
//N2InfoContent (section 6.1.6.2.27@3GPP TS 29.518)
session_report_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_SETUP_REQ"; //NGAP message type
session_report_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID; //NGAP part
session_report_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] =
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] =
session_report_msg.get_snssai().sST;
session_report_msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
session_report_msg.get_snssai().sD;
session_report_msg.set_json_data(json_data);
itti_n11_session_report_request *itti_n11 =
new itti_n11_session_report_request(TASK_SMF_APP, TASK_SMF_N11);
//use HTTPv1 for the moment
itti_n11->http_version = 1;
std::shared_ptr<itti_n11_session_report_request> itti_n11_report =
std::shared_ptr<itti_n11_session_report_request>(itti_n11);
itti_n11_report->res = session_report_msg;
......@@ -789,7 +791,6 @@ void smf_context::handle_itti_msg(
"TODO PFCP_SESSION_REPORT_REQUEST/User Plane Inactivity Report");
}
}
}
//------------------------------------------------------------------------------
......@@ -803,7 +804,6 @@ std::string smf_context::toString() const {
for (auto it : dnns) {
s.append(it->toString());
}
// s.append("\n");
return s;
}
......@@ -824,7 +824,6 @@ void smf_context::get_default_qos(const snssai_t &snssai,
default_qos = sdc.get()->_5g_qos_profile;
}
}
}
//------------------------------------------------------------------------------
......@@ -1019,7 +1018,6 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr,
}
}
} else {
Logger::smf_app().debug(
"Could not get default info from the subscription information, use default value instead.");
//use default value
......@@ -1030,7 +1028,6 @@ void smf_context::get_session_ambr(SessionAMBR &session_ambr,
session_ambr.uint_for_session_ambr_for_uplink =
AMBR_VALUE_IS_INCREMENTED_IN_MULTIPLES_OF_1MBPS;
}
}
//------------------------------------------------------------------------------
......@@ -1126,7 +1123,8 @@ void smf_context::get_session_ambr(
void smf_context::handle_pdu_session_create_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_request> smreq) {
Logger::smf_app().info(
"Handle a PDU Session Create SM Context Request message from AMF");
"Handle a PDU Session Create SM Context Request message from AMF (HTTP version %d)",
smreq->http_version);
oai::smf_server::model::SmContextCreateError smContextCreateError = { };
oai::smf_server::model::ProblemDetails problem_details = { };
......@@ -1147,7 +1145,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (!verify_sm_context_request(smreq)) {
// Not a valid request...
Logger::smf_app().warn(
"Received PDU_SESSION_CREATESMCONTEXT_REQUEST, the request is not valid!");
"Received a PDU Session Create SM Context Request, the request is not valid!");
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_SUBSCRIPTION_DENIED]);
smContextCreateError.setError(problem_details);
......@@ -1159,9 +1157,10 @@ void smf_context::handle_pdu_session_create_sm_context_request(
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
smreq->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_401_UNAUTHORIZED,
smContextCreateError, n1_sm_msg_hex, smreq->pid);
//TODO:
//SMF unsubscribes to the modifications of Session Management Subscription data for (SUPI, DNN, S-NSSAI)
//using Nudm_SDM_Unsubscribe()
......@@ -1171,9 +1170,13 @@ void smf_context::handle_pdu_session_create_sm_context_request(
//store HttpResponse and session-related information to be used when receiving the response from UPF
itti_n11_create_sm_context_response *sm_context_resp =
new itti_n11_create_sm_context_response(TASK_SMF_APP, TASK_SMF_N11,
smreq->http_response);
smreq->pid);
std::shared_ptr<itti_n11_create_sm_context_response> sm_context_resp_pending =
std::shared_ptr<itti_n11_create_sm_context_response>(sm_context_resp);
sm_context_resp->http_version = smreq->http_version;
sm_context_resp->res.set_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK); //default status code
sm_context_resp->res.set_supi(supi);
sm_context_resp->res.set_supi_prefix(smreq->req.get_supi_prefix());
sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
......@@ -1316,9 +1319,10 @@ void smf_context::handle_pdu_session_create_sm_context_request(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_create_sm_context_response(
sm_context_resp->http_response, smContextCreateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_msg_hex, smreq->pid);
request_accepted = false;
break;
}
......@@ -1335,27 +1339,40 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// Valid PAA sent in CSR ?
//bool paa_res = csreq->gtp_ies.get(paa);
//if ((paa_res) && ( paa.is_ip_assigned())) {
// sp->set(paa);
// sp->set(paa);
//}
}
//(step 5 (4.3.2.2.1 TS 23.502)) Send reply to AMF (PDUSession_CreateSMContextResponse including Cause, SMContextId)
//location header contains the URI of the created resource
oai::smf_server::model::SmContextCreatedData smContextCreatedData;
//TODO: assign values for smContextCreatedData
//include only SmfServiceInstanceId (See section 6.1.6.2.3, 3GPP TS 29.502 v16.0.0)
//Enable to test with tester
// std::string smContextRef = sm_context_req_msg.get_supi_prefix() + "-" + smf_supi_to_string(sm_context_req_msg.get_supi());
//Step 5 (4.3.2.2.1 TS 23.502): Trigger SMF APP to send response to SMF-HTTP-API-SERVER
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of Server");
std::shared_ptr<itti_n11_create_sm_context_response> itti_msg =
std::make_shared<itti_n11_create_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
smreq->pid);
pdu_session_create_sm_context_response sm_context_response = { };
//Cause, SM Context ID, location header contains the URI of the created resource
std::string smContextRef = std::to_string(smreq->scid);
//headers: Location: contains the URI of the newly created resource, according to the structure: {apiRoot}/nsmf-pdusession/{apiVersion}/sm-contexts/{smContextRef}
std::string uri = smreq->req.get_api_root() + "/" + smContextRef.c_str();
sm_context_resp->http_response.headers()
.add<Pistache::Http::Header::Location>(uri);
smf_n11_inst->send_pdu_session_create_sm_context_response(
sm_context_resp->http_response, smContextCreatedData,
Pistache::Http::Code::Created);
std::string smf_context_uri = smreq->req.get_api_root() + "/"
+ smContextRef.c_str();
sm_context_response.set_smf_context_uri(smf_context_uri);
sm_context_response.set_cause(0); //TODO
nlohmann::json json_data = { };
json_data["cause"] = 0;
sm_context_response.set_json_data(json_data);
sm_context_response.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
//TODO: PDU Session authentication/authorization (Optional)
//see section 4.3.2.3@3GPP TS 23.502 and section 6.3.1@3GPP TS 24.501
......@@ -1372,9 +1389,9 @@ void smf_context::handle_pdu_session_create_sm_context_request(
"PDU Session Establishment Request: Create SM Context Request procedure failed");
remove_procedure(proc);
//Set cause to error to trigger PDU session establishment reject (step 10)
sm_context_resp->res.set_cause(REMOTE_PEER_NOT_RESPONDING); //TODO: check cause
sm_context_resp->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING);
}
} else { //if request is rejected
//TODO:
//un-subscribe to the modifications of Session Management Subscription data for (SUPI, DNN, S-NSSAI)
......@@ -1433,14 +1450,16 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp_pending->res.set_amf_url(url);
//Fill the json part
sm_context_resp_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageClass"] =
nlohmann::json json_data = { };
json_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS;
sm_context_resp_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
json_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID;
//sm_context_resp_pending->res.n1n2_message_transfer_data["ppi"] = 1; //Don't need this info for the moment
sm_context_resp_pending->res.n1n2_message_transfer_data["pduSessionId"] =
json_data["pduSessionId"] =
sm_context_resp_pending->res.get_pdu_session_id();
sm_context_resp_pending->res.set_json_data(json_data);
//send ITTI message to N11 interface to trigger N1N2MessageTransfer towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
......@@ -1451,19 +1470,18 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp_pending->get_msg_name());
}
}
}
//-------------------------------------------------------------------------------------
void smf_context::handle_pdu_session_update_sm_context_request(
std::shared_ptr<itti_n11_update_sm_context_request> smreq) {
Logger::smf_app().info(
"Handle a PDU Session Update SM Context Request message from an AMF");
"Handle a PDU Session Update SM Context Request message from an AMF (HTTP version %d)",
smreq->http_version);
pdu_session_update_sm_context_request sm_context_req_msg = smreq->req;
smf_n1_n2 smf_n1_n2_inst = { };
oai::smf_server::model::SmContextUpdateError smContextUpdateError = { };
oai::smf_server::model::SmContextUpdatedData smContextUpdatedData = { };
oai::smf_server::model::ProblemDetails problem_details = { };
oai::smf_server::model::RefToBinaryData refToBinaryData = { };
std::string n1_sm_msg, n1_sm_msg_hex;
......@@ -1488,19 +1506,21 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Not_Found);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
smContextUpdateError, smreq->pid);
return;
}
//we need to store HttpResponse and session-related information to be used when receiving the response from UPF
itti_n11_update_sm_context_response *n11_sm_context_resp =
new itti_n11_update_sm_context_response(TASK_SMF_APP, TASK_SMF_N11,
smreq->http_response);
new itti_n11_update_sm_context_response(TASK_SMF_N11, TASK_SMF_APP,
smreq->pid);
std::shared_ptr<itti_n11_update_sm_context_response> sm_context_resp_pending =
std::shared_ptr<itti_n11_update_sm_context_response>(n11_sm_context_resp);
sm_context_resp_pending->res.set_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK); //default status code
n11_sm_context_resp->res.set_supi(sm_context_req_msg.get_supi());
n11_sm_context_resp->res.set_supi_prefix(
sm_context_req_msg.get_supi_prefix());
......@@ -1526,9 +1546,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N1_SM_ERROR]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
return;
}
......@@ -1630,11 +1651,9 @@ void smf_context::handle_pdu_session_update_sm_context_request(
QOSRulesIE qos_rules_ie = { };
qos_rules_ie = decoded_nas_msg.plain.sm
.pdu_session_modification_request.qosrules.qosrulesie[i];
uint8_t rule_id = { 0 };
pfcp::qfi_t qfi = { };
smf_qos_flow qos_flow = { };
length_of_rule = qos_rules_ie.LengthofQoSrule;
//If UE requested a new GBR flow
......@@ -1648,7 +1667,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
rule_id);
qos_rules_ie.qosruleidentifer = rule_id;
}
sp.get()->add_qos_rule(qos_rules_ie);
qfi.qfi = generated_qfi.qfi;
......@@ -1732,7 +1750,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
}
}
length_of_rule_ie -= (length_of_rule + 3); // 2 for Length of QoS rules IE and 1 for QoS rule identifier
i++;
}
......@@ -1767,20 +1784,22 @@ void smf_context::handle_pdu_session_update_sm_context_request(
n11_sm_context_resp->res.set_n2_sm_info_type("PDU_RES_MOD_REQ");
//Fill the json part
nlohmann::json json_data = { };
//N1SM
n11_sm_context_resp->res.sm_context_updated_data["n1MessageContainer"]["n1MessageClass"] =
json_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS;
n11_sm_context_resp->res.sm_context_updated_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
json_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID; //part 2
n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] =
json_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_MOD_REQ"; //NGAP message
n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID; //part 3
n11_sm_context_resp->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
n11_sm_context_resp->res.get_pdu_session_id();
n11_sm_context_resp->res.set_json_data(json_data);
//Update PDU Session status
sp.get()->set_pdu_session_status(
pdu_session_status_e::PDU_SESSION_MODIFICATION_PENDING);
......@@ -1902,9 +1921,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n1_sm_msg_hex, smreq->pid);
}
//Abnormal cases in network side (see section 6.3.3.5 @3GPP TS 24.501)
if (sp.get()->get_pdu_session_status()
......@@ -2058,10 +2078,11 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); //TODO: need N1SM?
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
return;
}
......@@ -2125,10 +2146,12 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
return;
}
//Logger::smf_app().info("PDU Session Resource Setup Unsuccessful Transfer cause %d",decoded_msg->cause );
......@@ -2142,9 +2165,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n1_sm_msg_hex, smreq->pid);
//TODO: Need release established resources?
return;
}
......@@ -2154,7 +2178,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
case n2_sm_info_type_e::PDU_RES_MOD_RSP: {
Logger::smf_app().info(
"PDU Session Modification Procedure, processing N2 SM Information");
procedure_type =
session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP2;
......@@ -2170,9 +2193,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
return;
}
......@@ -2241,9 +2265,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_N2_SM_ERROR]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
return;
}
......@@ -2264,7 +2289,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
and !sm_context_req_msg.n2_sm_info_is_set()
and sm_context_req_msg.upCnx_state_is_set()) {
Logger::smf_app().info("Service Request (UE-triggered, step 1)");
procedure_type =
session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1;
//Update upCnxState
......@@ -2282,7 +2306,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
qcu.set_ul_fteid(i.ul_fteid);
qcu.set_qos_profile(i.qos_profile);
sm_context_resp_pending->res.add_qos_flow_context_updated(qcu);
}
sm_context_resp_pending->session_procedure_type = procedure_type;
......@@ -2296,17 +2319,16 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->res.set_n2_sm_information(n2_sm_info_hex);
//fill the content of SmContextUpdatedData
sm_context_resp_pending->res.sm_context_updated_data = { };
sm_context_resp_pending->res.sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
sm_context_resp_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
nlohmann::json json_data = { };
json_data["n2InfoContainer"]["n2InformationClass"] = N1N2_MESSAGE_CLASS;
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
sm_context_resp_pending->res.get_pdu_session_id();
sm_context_resp_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID;
sm_context_resp_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_SETUP_REQ"; //NGAP message
sm_context_resp_pending->res.sm_context_updated_data["upCnxState"] =
"ACTIVATING";
json_data["upCnxState"] = "ACTIVATING";
sm_context_resp_pending->res.set_json_data(json_data);
//Update upCnxState to ACTIVATING
sp.get()->set_upCnx_state(upCnx_state_e::UPCNX_STATE_ACTIVATING);
......@@ -2368,9 +2390,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
}
break;
......@@ -2383,9 +2406,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
}
break;
......@@ -2394,18 +2418,19 @@ void smf_context::handle_pdu_session_update_sm_context_request(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
}
}
return;
}
} else {
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
Logger::smf_app().info(
"Sending ITTI message %s to task TASK_SMF_APP to trigger response",
sm_context_resp_pending->get_msg_name());
int ret = itti_inst->send_msg(sm_context_resp_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
......@@ -2428,7 +2453,6 @@ 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
......@@ -2443,20 +2467,22 @@ void smf_context::handle_pdu_session_release_sm_context_request(
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);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND, smreq->pid,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
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);
new itti_n11_release_sm_context_response(TASK_SMF_N11, TASK_SMF_APP,
smreq->pid);
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_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK); //default http response code
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);
......@@ -2472,8 +2498,12 @@ void smf_context::handle_pdu_session_release_sm_context_request(
if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) {
// error !
Logger::smf_app().info("PDU Release SM Context Request procedure failed");
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE); //TODO: check code
return;
}
}
//------------------------------------------------------------------------------
......@@ -2485,7 +2515,6 @@ void smf_context::handle_pdu_session_modification_network_requested(
smf_n1_n2 smf_n1_n2_inst = { };
oai::smf_server::model::SmContextUpdateError smContextUpdateError = { };
oai::smf_server::model::SmContextUpdatedData smContextUpdatedData = { };
oai::smf_server::model::ProblemDetails problem_details = { };
oai::smf_server::model::RefToBinaryData refToBinaryData = { };
std::string n1_sm_msg, n1_sm_msg_hex;
......@@ -2566,29 +2595,30 @@ void smf_context::handle_pdu_session_modification_network_requested(
"N1N2MessageTransfer will be sent to AMF with URL: %s", url.c_str());
//Fill the json part
nlohmann::json json_data = { };
//N1SM
itti_msg->msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageClass"] =
json_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS;
itti_msg->msg.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
json_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID; //NAS part
//N2SM
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["n2InformationClass"] =
json_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
itti_msg->msg.get_pdu_session_id();
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] = itti_msg->msg
.get_pdu_session_id();
//N2InfoContent (section 6.1.6.2.27@3GPP TS 29.518)
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_MOD_REQ"; //NGAP message type
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID; //NGAP part
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] =
itti_msg->msg.get_snssai().sST;
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
itti_msg->msg.get_snssai().sD;
itti_msg->msg.n1n2_message_transfer_data["n2InfoContainer"]["ranInfo"] = "SM";
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] = itti_msg->msg
.get_snssai().sST;
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] = itti_msg->msg
.get_snssai().sD;
json_data["n2InfoContainer"]["ranInfo"] = "SM";
itti_msg->msg.n1n2_message_transfer_data["pduSessionId"] = itti_msg->msg
.get_pdu_session_id();
json_data["pduSessionId"] = itti_msg->msg.get_pdu_session_id();
itti_msg->msg.set_json_data(json_data);
//Step 3. Send ITTI message to N11 interface to trigger N1N2MessageTransfer towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
......@@ -2600,15 +2630,13 @@ void smf_context::handle_pdu_session_modification_network_requested(
"Could not send ITTI message %s to task TASK_SMF_N11",
itti_msg->get_msg_name());
}
}
//------------------------------------------------------------------------------
void smf_context::insert_dnn_subscription(
const snssai_t &snssai,
std::shared_ptr<session_management_subscription> &ss) {
//std::unique_lock<std::recursive_mutex> lock(m_context);
//dnn_subscriptions.insert (std::make_pair <const uint8_t, std::shared_ptr<session_management_subscription> >((uint8_t)snssai.sST, ss));
std::unique_lock<std::recursive_mutex> lock(m_context);
dnn_subscriptions[(uint8_t) snssai.sST] = ss;
Logger::smf_app().info("Inserted DNN Subscription, key: %d",
(uint8_t) snssai.sST);
......@@ -2750,6 +2778,7 @@ void dnn_context::insert_pdu_session(std::shared_ptr<smf_pdu_session> &sp) {
pdu_sessions.push_back(sp);
}
//------------------------------------------------------------------------------
size_t dnn_context::get_number_pdu_sessions() const {
return pdu_sessions.size();
}
......
......@@ -118,7 +118,9 @@ class smf_qos_flow {
class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
public:
smf_pdu_session() {
smf_pdu_session()
:
m_pdu_session_mutex() {
clear();
}
......@@ -137,6 +139,7 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
timer_T3590 = ITTI_INVALID_TIMER_ID;
timer_T3591 = ITTI_INVALID_TIMER_ID;
timer_T3592 = ITTI_INVALID_TIMER_ID;
}
smf_pdu_session(smf_pdu_session &b) = delete;
......@@ -424,6 +427,9 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
uint8_t number_of_supported_packet_filters; //number_of_supported_packet_filters
util::uint_generator<uint32_t> qos_rule_id_generator;
// Recursive lock
mutable std::recursive_mutex m_pdu_session_mutex;
};
class session_management_subscription {
......@@ -604,7 +610,6 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
*/
void handle_pdu_session_create_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_request> smreq);
/*
* Handle messages from AMF (e.g., PDU_SESSION_UpdateSMContextRequest)
* @param [std::shared_ptr<itti_n11_update_sm_context_request] smreq Request message
......@@ -670,7 +675,8 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
* @param [const snssai_t&] snssai: single NSSAI
*@return bool: Return true if a subscription data corresponding with dnn and snssai exist, otherwise return false
*/
bool is_dnn_snssai_subscription_data(const std::string &dnn, const snssai_t &snssai);
bool is_dnn_snssai_subscription_data(const std::string &dnn,
const snssai_t &snssai);
/*
* Find a session management subscription from a SMF context
......@@ -747,7 +753,6 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
*/
void set_supi_prefix(std::string const &value);
/*
* Get the default QoS Rule for all QFIs
* @param [QOSRulesIE] qos_rule
......@@ -809,7 +814,6 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
scid_t scid; //SM Context ID
// Big recursive lock
mutable std::recursive_mutex m_context;
};
}
......
......@@ -30,6 +30,9 @@
using namespace smf;
/*
* class: QoS Flow Context Updated
*/
//-----------------------------------------------------------------------------
void qos_flow_context_updated::set_cause(const uint8_t cause) {
cause_value = cause;
......@@ -62,6 +65,8 @@ void qos_flow_context_updated::add_qos_rule(const QOSRulesIE &rule) {
}
}
//-----------------------------------------------------------------------------
void qos_flow_context_updated::set_qos_profile(const qos_profile_t &profile) {
qos_profile = profile;
}
......@@ -72,6 +77,9 @@ void qos_flow_context_updated::set_priority_level(uint8_t p) {
qos_profile.priority_level = p;
}
/*
* class: PDU Session MSG
*/
//-----------------------------------------------------------------------------
pdu_session_msg_type_t pdu_session_msg::get_msg_type() const {
return m_msg_type;
......@@ -163,203 +171,199 @@ void pdu_session_msg::set_pti(const procedure_transaction_id_t &pti) {
}
//-----------------------------------------------------------------------------
extended_protocol_discriminator_t pdu_session_create_sm_context::get_epd() const {
return m_epd;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context::set_epd(
const extended_protocol_discriminator_t &epd) {
m_epd = epd;
}
//-----------------------------------------------------------------------------
uint8_t pdu_session_create_sm_context::get_message_type() const {
return m_message_type;
std::string pdu_session_msg::get_n1_sm_message() const {
return m_n1_sm_message;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context::set_message_type(
const uint8_t &message_type) {
m_message_type = message_type;
void pdu_session_msg::set_n1_sm_message(
const std::string &value) {
m_n1_sm_message = value;
m_n1_sm_msg_is_set = true;
}
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_request::get_n1_sm_message() const {
return m_n1_sm_message;
bool pdu_session_msg::n1_sm_msg_is_set() const {
return m_n1_sm_msg_is_set;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_n1_sm_message(
std::string const &value) {
m_n1_sm_message = value;
std::string pdu_session_msg::get_n2_sm_information() const {
return m_n2_sm_information;
}
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_request::get_serving_nf_id() const {
return m_serving_nf_id;
void pdu_session_msg::set_n2_sm_information(
const std::string &value) {
m_n2_sm_information = value;
m_n2_sm_info_is_set = true;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_serving_nf_id(
const std::string &serving_nf_id) {
m_serving_nf_id = serving_nf_id;
bool pdu_session_msg::n2_sm_info_is_set() const {
return m_n2_sm_info_is_set;
}
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_request::get_request_type() const {
return m_request_type;
std::string pdu_session_msg::get_n2_sm_info_type() const {
return m_n2_sm_info_type;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_request_type(
const std::string &request_type) {
m_request_type = request_type;
void pdu_session_msg::set_n2_sm_info_type(
const std::string &value) {
m_n2_sm_info_type = value;
m_n2_sm_info_type_is_set = true;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_dnn_selection_mode(
const std::string &dnn_selection_mode) {
m_dnn_selection_mode = dnn_selection_mode;
bool pdu_session_msg::n2_sm_info_type_is_set() const {
return m_n2_sm_info_type_is_set;
}
/*
* class: PDU Session SM Context Request
*/
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_request::get_dnn_selection_mode() const {
return m_dnn_selection_mode;
extended_protocol_discriminator_t pdu_session_sm_context_request::get_epd() const {
return m_epd;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_cause(uint8_t cause) {
m_cause = cause;
void pdu_session_sm_context_request::set_epd(
const extended_protocol_discriminator_t &epd) {
m_epd = epd;
}
//-----------------------------------------------------------------------------
uint8_t pdu_session_create_sm_context_response::get_cause() {
return m_cause;
uint8_t pdu_session_sm_context_request::get_message_type() const {
return m_message_type;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_paa(paa_t paa) {
m_paa = paa;
void pdu_session_sm_context_request::set_message_type(
const uint8_t &message_type) {
m_message_type = message_type;
}
/*
* class: PDU Session SM Context Response
*/
//-----------------------------------------------------------------------------
paa_t pdu_session_create_sm_context_response::get_paa() {
return m_paa;
void pdu_session_sm_context_response::set_cause(const uint8_t cause) {
m_cause = cause;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_http_code(
Pistache::Http::Code code) {
m_code = code;
uint8_t pdu_session_sm_context_response::get_cause() const {
return m_cause;
}
//-----------------------------------------------------------------------------
Pistache::Http::Code pdu_session_create_sm_context_response::get_http_code() {
return m_code;
void pdu_session_sm_context_response::set_http_code(const
uint32_t code) {
m_http_code = code;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_qos_flow_context(
const qos_flow_context_updated &qos_flow) {
qos_flow_context = qos_flow;
uint32_t pdu_session_sm_context_response::get_http_code() const {
return m_http_code;
}
//-----------------------------------------------------------------------------
qos_flow_context_updated pdu_session_create_sm_context_response::get_qos_flow_context() const {
return qos_flow_context;
void pdu_session_sm_context_response::set_json_data(const nlohmann::json &data) {
m_json_data = data;
}
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_response::get_n2_sm_information() const {
return m_n2_sm_information;
void pdu_session_sm_context_response::get_json_data(nlohmann::json &data) const {
data = m_json_data;
}
/*
* class: PDU Session Create SM Context Request
*/
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_n2_sm_information(
const std::string &value) {
m_n2_sm_information = value;
m_n2_sm_info_is_set = true;
std::string pdu_session_create_sm_context_request::get_serving_nf_id() const {
return m_serving_nf_id;
}
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_response::get_n1_sm_message() const {
return m_n1_sm_message;
void pdu_session_create_sm_context_request::set_serving_nf_id(
const std::string &serving_nf_id) {
m_serving_nf_id = serving_nf_id;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_n1_sm_message(
const std::string &value) {
m_n1_sm_message = value;
m_n1_sm_msg_is_set = true;
std::string pdu_session_create_sm_context_request::get_request_type() const {
return m_request_type;
}
//-----------------------------------------------------------------------------
bool pdu_session_create_sm_context_response::n1_sm_msg_is_set() const {
return m_n1_sm_msg_is_set;
void pdu_session_create_sm_context_request::set_request_type(
const std::string &request_type) {
m_request_type = request_type;
}
//-----------------------------------------------------------------------------
bool pdu_session_create_sm_context_response::n2_sm_info_is_set() const {
return m_n2_sm_info_is_set;
void pdu_session_create_sm_context_request::set_dnn_selection_mode(
const std::string &dnn_selection_mode) {
m_dnn_selection_mode = dnn_selection_mode;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_response::set_amf_url(
const std::string &value) {
amf_url = value;
std::string pdu_session_create_sm_context_request::get_dnn_selection_mode() const {
return m_dnn_selection_mode;
}
/*
* class: PDU Session Create SM Context Response
*/
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_response::get_amf_url() const {
return amf_url;
void pdu_session_create_sm_context_response::set_paa(const paa_t &paa) {
m_paa = paa;
}
//-----------------------------------------------------------------------------
std::string pdu_session_update_sm_context::get_n2_sm_information() const {
return m_n2_sm_information;
paa_t pdu_session_create_sm_context_response::get_paa() const {
return m_paa;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context::set_n2_sm_information(
const std::string &value) {
m_n2_sm_information = value;
m_n2_sm_info_is_set = true;
void pdu_session_create_sm_context_response::set_qos_flow_context(
const qos_flow_context_updated &qos_flow) {
m_qos_flow_context = qos_flow;
}
//-----------------------------------------------------------------------------
std::string pdu_session_update_sm_context::get_n2_sm_info_type() const {
return m_n2_sm_info_type;
qos_flow_context_updated pdu_session_create_sm_context_response::get_qos_flow_context() const {
return m_qos_flow_context;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context::set_n2_sm_info_type(
void pdu_session_create_sm_context_response::set_amf_url(
const std::string &value) {
m_n2_sm_info_type = value;
m_n2_sm_info_is_set = true;
m_amf_url = value;
}
//-----------------------------------------------------------------------------
std::string pdu_session_update_sm_context::get_n1_sm_message() const {
return m_n1_sm_message;
std::string pdu_session_create_sm_context_response::get_amf_url() const {
return m_amf_url;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context::set_n1_sm_message(
const std::string &value) {
m_n1_sm_message = value;
m_n1_sm_msg_is_set = true;
void pdu_session_create_sm_context_response::set_smf_context_uri(const std::string &value) {
m_smf_context_uri = value;
}
//-----------------------------------------------------------------------------
bool pdu_session_update_sm_context::n1_sm_msg_is_set() const {
return m_n1_sm_msg_is_set;
std::string pdu_session_create_sm_context_response::get_smf_context_uri() const {
return m_smf_context_uri;
}
//-----------------------------------------------------------------------------
bool pdu_session_update_sm_context::n2_sm_info_is_set() const {
return m_n2_sm_info_is_set;
}
/*
* class: PDU Session Update SM Context Request
*/
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::add_qfi(const pfcp::qfi_t &qfi) {
......@@ -437,16 +441,9 @@ void pdu_session_update_sm_context_request::set_release(bool value) {
m_release_is_set = true;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_response::set_cause(uint8_t cause) {
m_cause = cause;
}
//-----------------------------------------------------------------------------
uint8_t pdu_session_update_sm_context_response::get_cause() {
return m_cause;
}
/*
* class: PDU Session Update SM Context Response
*/
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_response::add_qos_flow_context_updated(
const qos_flow_context_updated &flow) {
......@@ -492,6 +489,20 @@ void pdu_session_update_sm_context_response::remove_all_qos_flow_context_updated
qos_flow_context_updateds.clear();
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_response::set_smf_context_uri(const std::string &value) {
m_smf_context_uri = value;
}
//-----------------------------------------------------------------------------
std::string pdu_session_update_sm_context_response::get_smf_context_uri() const {
return m_smf_context_uri;
}
/*
* class: PDU Session Release SM Context Response
*/
//-----------------------------------------------------------------------------
void pdu_session_release_sm_context_response::set_cause(uint8_t cause) {
m_cause = cause;
......@@ -503,16 +514,20 @@ uint8_t pdu_session_release_sm_context_response::get_cause() {
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::set_http_code(
Pistache::Http::Code code) {
m_code = code;
void pdu_session_release_sm_context_response::set_http_code(const
uint32_t code) {
m_http_code = code;
}
//-----------------------------------------------------------------------------
Pistache::Http::Code pdu_session_modification_network_requested::get_http_code() {
return m_code;
uint32_t pdu_session_release_sm_context_response::get_http_code() const {
return m_http_code;
}
/*
* class: PDU Session Modification Network Requested
*/
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::set_amf_url(
const std::string &value) {
......@@ -544,6 +559,49 @@ void pdu_session_modification_network_requested::get_qfis(
}
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::set_json_data(const nlohmann::json &data) {
m_json_data = data;
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::get_json_data(nlohmann::json &data) const {
data = m_json_data;
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::add_qos_flow_context_updated(
const qos_flow_context_updated &flow) {
if ((flow.qfi.qfi >= QOS_FLOW_IDENTIFIER_FIRST )
and (flow.qfi.qfi <= QOS_FLOW_IDENTIFIER_LAST )) {
qos_flow_context_updateds.erase(flow.qfi.qfi);
qos_flow_context_updateds.insert(
std::pair<uint8_t, qos_flow_context_updated>((uint8_t) flow.qfi.qfi,
flow));
Logger::smf_app().trace(
"A QoS Flow Context (QFI %d) has been added successfully",
flow.qfi.qfi);
} else {
Logger::smf_app().error(
"Failed to add a QoS Flow Context (QFI %d), invalid QFI", flow.qfi.qfi);
}
}
//-----------------------------------------------------------------------------
bool pdu_session_modification_network_requested::get_qos_flow_context_updated(
const pfcp::qfi_t &qfi, qos_flow_context_updated &flow) {
for (auto it : qos_flow_context_updateds) {
if (it.second.qfi == qfi) {
flow = it.second;
return true;
}
}
return false;
}
/*
* class: PDU Session Report Response
*/
//-----------------------------------------------------------------------------
void pdu_session_report_response::set_amf_url(const std::string &value) {
amf_url = value;
......@@ -571,7 +629,6 @@ void pdu_session_report_response::add_qos_flow_context_updated(
Logger::smf_app().error(
"Failed to add a QoS Flow Context (QFI %d), invalid QFI", flow.qfi.qfi);
}
}
//-----------------------------------------------------------------------------
......@@ -596,51 +653,6 @@ void pdu_session_report_response::get_all_qos_flow_context_updateds(
}
}
//-----------------------------------------------------------------------------
std::string pdu_session_report_response::get_n2_sm_information() const {
return m_n2_sm_information;
}
//-----------------------------------------------------------------------------
void pdu_session_report_response::set_n2_sm_information(
const std::string &value) {
m_n2_sm_information = value;
m_n2_sm_info_is_set = true;
}
//-----------------------------------------------------------------------------
std::string pdu_session_report_response::get_n2_sm_info_type() const {
return m_n2_sm_info_type;
}
//-----------------------------------------------------------------------------
void pdu_session_report_response::set_n2_sm_info_type(
const std::string &value) {
m_n2_sm_info_type = value;
m_n2_sm_info_is_set = true;
}
//-----------------------------------------------------------------------------
std::string pdu_session_report_response::get_n1_sm_message() const {
return m_n1_sm_message;
}
//-----------------------------------------------------------------------------
void pdu_session_report_response::set_n1_sm_message(const std::string &value) {
m_n1_sm_message = value;
m_n1_sm_msg_is_set = true;
}
//-----------------------------------------------------------------------------
bool pdu_session_report_response::n1_sm_msg_is_set() const {
return m_n1_sm_msg_is_set;
}
//-----------------------------------------------------------------------------
bool pdu_session_report_response::n2_sm_info_is_set() const {
return m_n2_sm_info_is_set;
}
//-----------------------------------------------------------------------------
void pdu_session_report_response::set_seid(const seid_t &s) {
seid = s;
......@@ -660,4 +672,3 @@ seid_t pdu_session_report_response::get_seid() const {
uint64_t pdu_session_report_response::get_trxn_id() const {
return trxn_id;
}
......@@ -54,11 +54,13 @@ typedef enum {
PDU_SESSION_RELEASE_SM_CONTEXT_REQUEST,
PDU_SESSION_RELEASE_SM_CONTEXT_RESPONSE,
PDU_SESSION_MODIFICATION_SMF_REQUESTED,
PDU_SESSION_REPORT_RESPONSE,
PDU_SESSION_MSG_TYPE_MAX
} pdu_session_msg_type_t;
namespace smf {
//-----------------------------------------------------------------------------
//QoS flow to be created/modified/removed
class qos_flow_context_updated {
public:
......@@ -79,6 +81,7 @@ class qos_flow_context_updated {
void add_qos_rule(const QOSRulesIE &rule);
void set_qos_profile(const qos_profile_t &profile);
void set_priority_level(uint8_t p);
uint8_t cause_value;
pfcp::qfi_t qfi;
fteid_t ul_fteid;
......@@ -99,6 +102,9 @@ class pdu_session_msg {
m_dnn(),
m_snssai(),
m_pdu_session_type(0) {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
m_n2_sm_info_type_is_set = false;
}
;
pdu_session_msg(pdu_session_msg_type_t msg_type)
......@@ -109,6 +115,9 @@ class pdu_session_msg {
m_dnn(),
m_snssai(),
m_pdu_session_type(0) {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
m_n2_sm_info_type_is_set = false;
}
;
pdu_session_msg(pdu_session_msg_type_t msg_type, supi_t supi,
......@@ -120,7 +129,11 @@ class pdu_session_msg {
m_dnn(dnn),
m_snssai(snssai),
m_pdu_session_type(0) {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
m_n2_sm_info_type_is_set = false;
}
virtual ~pdu_session_msg() = default;
pdu_session_msg_type_t get_msg_type() const;
......@@ -141,6 +154,15 @@ class pdu_session_msg {
void set_pdu_session_type(const uint8_t &pdu_session_type);
procedure_transaction_id_t get_pti() const;
void set_pti(const procedure_transaction_id_t &pti);
std::string get_n2_sm_information() const;
void set_n2_sm_information(const std::string &value);
std::string get_n1_sm_message() const;
void set_n1_sm_message(const std::string &value);
bool n1_sm_msg_is_set() const;
bool n2_sm_info_is_set() const;
std::string get_n2_sm_info_type() const;
void set_n2_sm_info_type(const std::string &value);
bool n2_sm_info_type_is_set() const;
private:
pdu_session_msg_type_t m_msg_type;
......@@ -152,29 +174,34 @@ class pdu_session_msg {
snssai_t m_snssai;
uint8_t m_pdu_session_type;
procedure_transaction_id_t m_pti;
std::string m_n1_sm_message;
bool m_n1_sm_msg_is_set;
std::string m_n2_sm_information;
bool m_n2_sm_info_is_set;
std::string m_n2_sm_info_type;
bool m_n2_sm_info_type_is_set;
};
//---------------------------------------------------------------------------------------
class pdu_session_create_sm_context : public pdu_session_msg {
class pdu_session_sm_context_request : public pdu_session_msg {
public:
pdu_session_create_sm_context()
pdu_session_sm_context_request()
:
pdu_session_msg() {
m_epd = EPD_5GS_SESSION_MANAGEMENT_MESSAGES;
m_message_type = PDU_SESSION_MESSAGE_TYPE_UNKNOWN;
}
;
pdu_session_create_sm_context(pdu_session_msg_type_t msg_type)
pdu_session_sm_context_request(pdu_session_msg_type_t msg_type)
:
pdu_session_msg(msg_type) {
m_epd = EPD_5GS_SESSION_MANAGEMENT_MESSAGES;
m_message_type = PDU_SESSION_MESSAGE_TYPE_UNKNOWN;
}
;
pdu_session_create_sm_context(pdu_session_msg_type_t msg_type, supi_t supi,
pdu_session_id_t pdi, std::string dnn,
snssai_t snssai)
pdu_session_sm_context_request(pdu_session_msg_type_t msg_type, supi_t supi,
pdu_session_id_t pdi, std::string dnn,
snssai_t snssai)
:
pdu_session_msg(msg_type, supi, pdi, dnn, snssai) {
m_epd = EPD_5GS_SESSION_MANAGEMENT_MESSAGES;
......@@ -192,25 +219,53 @@ class pdu_session_create_sm_context : public pdu_session_msg {
};
//---------------------------------------------------------------------------------------
class pdu_session_create_sm_context_request :
public pdu_session_create_sm_context {
class pdu_session_sm_context_response : public pdu_session_msg {
public:
pdu_session_sm_context_response(pdu_session_msg_type_t msg_type)
:
pdu_session_msg(msg_type) {
m_cause = 0;
m_http_code = 0;
}
pdu_session_sm_context_response(pdu_session_msg_type_t msg_type, supi_t supi,
pdu_session_id_t pdi, std::string dnn,
snssai_t snssai)
:
pdu_session_msg(msg_type, supi, pdi, dnn, snssai) {
m_cause = 0;
m_http_code = 0;
}
void set_cause(const uint8_t cause);
uint8_t get_cause() const;
void set_http_code(const uint32_t code);
uint32_t get_http_code() const;
void set_json_data(const nlohmann::json &data);
void get_json_data(nlohmann::json &data) const;
private:
uint8_t m_cause;
nlohmann::json m_json_data;
uint32_t m_http_code;
};
//---------------------------------------------------------------------------------------
class pdu_session_create_sm_context_request :
public pdu_session_sm_context_request {
public:
pdu_session_create_sm_context_request()
:
pdu_session_create_sm_context(PDU_SESSION_CREATE_SM_CONTEXT_REQUEST),
pdu_session_sm_context_request(PDU_SESSION_CREATE_SM_CONTEXT_REQUEST),
m_unauthenticated_supi(true) {
}
pdu_session_create_sm_context_request(supi_t supi, pdu_session_id_t pdi,
std::string dnn, snssai_t snssai)
:
pdu_session_create_sm_context(PDU_SESSION_CREATE_SM_CONTEXT_REQUEST, supi,
pdi, dnn, snssai),
pdu_session_sm_context_request(PDU_SESSION_CREATE_SM_CONTEXT_REQUEST,
supi, pdi, dnn, snssai),
m_unauthenticated_supi(true) {
}
std::string get_n1_sm_message() const;
void set_n1_sm_message(const std::string &value);
std::string get_serving_nf_id() const;
void set_serving_nf_id(const std::string &value);
std::string get_request_type() const;
......@@ -219,7 +274,6 @@ class pdu_session_create_sm_context_request :
std::string get_dnn_selection_mode() const;
private:
std::string m_n1_sm_message; //N1 SM Message before decoding
bool m_unauthenticated_supi;
std::string m_serving_nf_id; //AMF Id
std::string m_request_type;
......@@ -231,108 +285,48 @@ class pdu_session_create_sm_context_request :
//---------------------------------------------------------------------------------------
class pdu_session_create_sm_context_response :
public pdu_session_create_sm_context {
public pdu_session_sm_context_response {
public:
pdu_session_create_sm_context_response()
:
pdu_session_create_sm_context(PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE) {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
m_cause = 0;
pdu_session_sm_context_response(PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE) {
m_paa = { };
m_code = { };
qos_flow_context = { };
m_supi = { };
m_qos_flow_context = { };
}
pdu_session_create_sm_context_response(supi_t supi, pdu_session_id_t pdi,
std::string dnn, snssai_t snssai)
:
pdu_session_create_sm_context(PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE,
supi, pdi, dnn, snssai) {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
m_cause = 0;
pdu_session_sm_context_response(PDU_SESSION_CREATE_SM_CONTEXT_RESPONSE,
supi, pdi, dnn, snssai) {
m_paa = { };
m_code = { };
qos_flow_context = { };
m_qos_flow_context = { };
}
void set_cause(uint8_t cause);
uint8_t get_cause();
void set_paa(paa_t paa);
paa_t get_paa();
void set_http_code(Pistache::Http::Code code);
Pistache::Http::Code get_http_code();
void set_paa(const paa_t &paa);
paa_t get_paa() const;
void set_qos_flow_context(const qos_flow_context_updated &qos_flow);
qos_flow_context_updated get_qos_flow_context() const;
std::string get_n2_sm_information() const;
void set_n2_sm_information(const std::string &value);
std::string get_n1_sm_message() const;
void set_n1_sm_message(const std::string &value);
bool n1_sm_msg_is_set() const;
bool n2_sm_info_is_set() const;
void set_amf_url(const std::string &value);
std::string get_amf_url() const;
nlohmann::json n1n2_message_transfer_data; //N1N2MessageTransferReqData from oai::amf::model
void set_smf_context_uri(const std::string &value);
std::string get_smf_context_uri() const;
private:
std::string m_n1_sm_message; //N1 SM message after decoding
bool m_n1_sm_msg_is_set;
std::string m_n2_sm_information; //N2 SM info after decoding
bool m_n2_sm_info_is_set;
uint8_t m_cause;
paa_t m_paa;
Pistache::Http::Code m_code;
qos_flow_context_updated qos_flow_context;
supi_t m_supi;
std::string m_supi_prefix;
std::string amf_url;
qos_flow_context_updated m_qos_flow_context;
std::string m_amf_url;
std::string m_smf_context_uri;
};
//---------------------------------------------------------------------------------------
class pdu_session_update_sm_context : public pdu_session_msg {
public:
pdu_session_update_sm_context()
:
pdu_session_msg() {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
}
;
pdu_session_update_sm_context(pdu_session_msg_type_t msg_type)
:
pdu_session_msg(msg_type) {
m_n1_sm_msg_is_set = false;
m_n2_sm_info_is_set = false;
}
;
std::string get_n2_sm_information() const;
void set_n2_sm_information(std::string const &value);
std::string get_n2_sm_info_type() const;
void set_n2_sm_info_type(const std::string &value);
std::string get_n1_sm_message() const;
void set_n1_sm_message(const std::string &value);
bool n1_sm_msg_is_set() const;
bool n2_sm_info_is_set() const;
private:
std::string m_n1_sm_message; //N1 SM message before decoding
bool m_n1_sm_msg_is_set;
std::string m_n2_sm_information; //N2 SM before decoding
bool m_n2_sm_info_is_set;
std::string m_n2_sm_info_type;
};
//see SmContextUpdateData (TS29502_Nsmf_PDUSession.yaml)
class pdu_session_update_sm_context_request :
public pdu_session_update_sm_context {
public pdu_session_sm_context_request {
public:
pdu_session_update_sm_context_request()
:
pdu_session_update_sm_context(PDU_SESSION_UPDATE_SM_CONTEXT_REQUEST) {
pdu_session_sm_context_request(PDU_SESSION_UPDATE_SM_CONTEXT_REQUEST) {
m_5gMm_cause_value = 0;
m_data_forwarding = false;
m_upCnx_state_is_set = false;
......@@ -381,120 +375,104 @@ class pdu_session_update_sm_context_request :
//---------------------------------------------------------------------------------------
//for PDU session update response
class pdu_session_update_sm_context_response :
public pdu_session_update_sm_context {
public pdu_session_sm_context_response {
public:
pdu_session_update_sm_context_response()
:
pdu_session_update_sm_context(PDU_SESSION_UPDATE_SM_CONTEXT_RESPONSE) {
m_cause = 0;
qos_flow_context_updateds = { };
pdu_session_sm_context_response(PDU_SESSION_UPDATE_SM_CONTEXT_RESPONSE) {
}
;
pdu_session_update_sm_context_response(pdu_session_msg_type_t type)
:
pdu_session_update_sm_context(type) {
m_cause = 0;
qos_flow_context_updateds = { };
pdu_session_sm_context_response(type) {
}
;
void set_cause(uint8_t cause);
uint8_t get_cause();
void add_qos_flow_context_updated(const qos_flow_context_updated &qos_flow);
bool get_qos_flow_context_updated(const pfcp::qfi_t &qfi,
qos_flow_context_updated &qos_flow);
void get_all_qos_flow_context_updateds(
std::map<uint8_t, qos_flow_context_updated> &all_flows);
void remove_all_qos_flow_context_updateds();
nlohmann::json sm_context_updated_data; //N1N2MessageTransferReqData from oai::amf::model
void set_smf_context_uri(const std::string &value);
std::string get_smf_context_uri() const;
private:
uint8_t m_cause;
std::map<uint8_t, qos_flow_context_updated> qos_flow_context_updateds;
std::string m_smf_context_uri;
};
//---------------------------------------------------------------------------------------
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;
m_http_code = 0;
}
;
void set_cause(uint8_t cause);
uint8_t get_cause();
void set_http_code(const uint32_t code);
uint32_t get_http_code() const;
private:
uint8_t m_cause;
uint32_t m_http_code;
};
//---------------------------------------------------------------------------------------
class pdu_session_modification_network_requested :
public pdu_session_update_sm_context_response {
public pdu_session_sm_context_request {
public:
pdu_session_modification_network_requested()
:
pdu_session_update_sm_context_response(
PDU_SESSION_MODIFICATION_SMF_REQUESTED) {
m_code = { };
m_supi = { };
pdu_session_sm_context_request(PDU_SESSION_MODIFICATION_SMF_REQUESTED) {
}
void set_http_code(Pistache::Http::Code code);
Pistache::Http::Code get_http_code();
void set_amf_url(const std::string &value);
std::string get_amf_url() const;
void add_qfi(const pfcp::qfi_t &qfi);
void add_qfi(const uint8_t &qfi);
void get_qfis(std::vector<pfcp::qfi_t> &q);
nlohmann::json n1n2_message_transfer_data; //N1N2MessageTransferReqData from oai::amf::model
void set_json_data(const nlohmann::json &data);
void get_json_data(nlohmann::json &data) const;
void add_qos_flow_context_updated(const qos_flow_context_updated &qos_flow);
bool get_qos_flow_context_updated(const pfcp::qfi_t &qfi,
qos_flow_context_updated &qos_flow);
private:
Pistache::Http::Code m_code;
supi_t m_supi;
std::string m_supi_prefix;
std::string amf_url;
std::vector<pfcp::qfi_t> qfis;
std::map<uint8_t, qos_flow_context_updated> qos_flow_context_updateds;
nlohmann::json m_json_data;
};
//---------------------------------------------------------------------------------------
class pdu_session_report_response : public pdu_session_msg {
public:
class pdu_session_report_response : public pdu_session_sm_context_response {
public:
pdu_session_report_response()
:
pdu_session_msg() {
m_n2_sm_info_is_set = false;
m_n1_sm_msg_is_set = false;
seid = 0;
trxn_id = 0;
}
;
pdu_session_report_response(pdu_session_msg_type_t msg_type)
:
pdu_session_msg(msg_type) {
m_n2_sm_info_is_set = false;
m_n1_sm_msg_is_set = false;
pdu_session_sm_context_response(PDU_SESSION_REPORT_RESPONSE) {
seid = 0;
trxn_id = 0;
}
;
void set_amf_url(std::string const &value);
std::string get_amf_url() const;
void add_qos_flow_context_updated(const qos_flow_context_updated &qos_flow);
......@@ -502,35 +480,17 @@ class pdu_session_report_response : public pdu_session_msg {
qos_flow_context_updated &qos_flow);
void get_all_qos_flow_context_updateds(
std::map<uint8_t, qos_flow_context_updated> &all_flows);
std::string get_n2_sm_information() const;
void set_n2_sm_information(const std::string &value);
std::string get_n2_sm_info_type() const;
void set_n2_sm_info_type(const std::string &value);
std::string get_n1_sm_message() const;
void set_n1_sm_message(const std::string &value);
bool n1_sm_msg_is_set() const;
bool n2_sm_info_is_set() const;
void set_seid(const seid_t &s);
void set_trxn_id(const uint64_t &t);
seid_t get_seid() const;
uint64_t get_trxn_id() const;
nlohmann::json n1n2_message_transfer_data; //N1N2MessageTransferReqData from oai::amf::model
private:
supi_t m_supi;
std::string m_supi_prefix;
std::string amf_url;
std::map<uint8_t, qos_flow_context_updated> qos_flow_context_updateds;
std::string m_n1_sm_message;
bool m_n1_sm_msg_is_set;
std::string m_n2_sm_information;
bool m_n2_sm_info_is_set;
std::string m_n2_sm_info_type;
seid_t seid;
uint64_t trxn_id;
};
}
#endif
......@@ -43,6 +43,7 @@
#include "smf_app.hpp"
#include "smf_config.hpp"
#include "smf_n1_n2.hpp"
#include "mime_parser.hpp"
extern "C" {
#include "dynamic_memory_check.h"
......@@ -52,12 +53,10 @@ using namespace Pistache::Http;
using namespace Pistache::Http::Mime;
using namespace smf;
using namespace std;
using json = nlohmann::json;
extern itti_mw *itti_inst;
extern smf_n11 *smf_n11_inst;
extern smf::smf_app *smf_app_inst;
extern smf_config smf_cfg;
void smf_n11_task(void*);
......@@ -85,18 +84,6 @@ void smf_n11_task(void *args_p) {
shared_msg));
break;
case N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE:
smf_n11_inst->send_pdu_session_update_sm_context_response(
std::static_pointer_cast<itti_n11_update_sm_context_response>(
shared_msg));
break;
case N11_SESSION_MODIFICATION_REQUEST_SMF_REQUESTED:
//TODO
smf_n11_inst->send_n1n2_message_transfer_request(
std::static_pointer_cast<
itti_n11_modify_session_request_smf_requested>(shared_msg));
break;
case NX_TRIGGER_SESSION_MODIFICATION:
smf_n11_inst->send_n1n2_message_transfer_request(
std::static_pointer_cast<itti_nx_trigger_pdu_session_modification>(
......@@ -104,7 +91,6 @@ void smf_n11_task(void *args_p) {
break;
case N11_SESSION_REPORT_RESPONSE:
//TODO
smf_n11_inst->send_n1n2_message_transfer_request(
std::static_pointer_cast<itti_n11_session_report_request>(
shared_msg));
......@@ -140,28 +126,33 @@ void smf_n11::send_n1n2_message_transfer_request(
//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");
Logger::smf_n11().debug("Send Communication_N1N2MessageTransfer to AMF (HTTP version %d)", sm_context_res->http_version);
mime_parser parser = {};
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();
nlohmann::json json_data = {};
std::string body;
sm_context_res->res.get_json_data(json_data);
std::string json_part = json_data.dump();
//add N2 content if available
auto n2_sm_found = sm_context_res->res.n1n2_message_transfer_data.count(
auto n2_sm_found = json_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, CURL_MIME_BOUNDARY, n1_message,
parser.create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
n2_message);
} else {
//prepare the body content for Curl
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
parser.create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
multipart_related_content_part_e::NAS);
}
unsigned int str_len = body.length();
Logger::smf_n11().debug("Send Communication_N1N2MessageTransfer to AMF, body %s", body.c_str());
uint32_t 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);
......@@ -183,6 +174,15 @@ void smf_n11::send_n1n2_message_transfer_request(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, smf_cfg.sbi.if_name.c_str());
if (sm_context_res->http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -195,9 +195,7 @@ void smf_n11::send_n1n2_message_transfer_request(
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
json response_data = { };
try {
......@@ -239,36 +237,37 @@ void smf_n11::send_n1n2_message_transfer_request(
}
curl_global_cleanup();
free_wrapper((void**) &data);
}
//------------------------------------------------------------------------------
void smf_n11::send_n1n2_message_transfer_request(
std::shared_ptr<itti_nx_trigger_pdu_session_modification> sm_context_res) {
std::shared_ptr<itti_nx_trigger_pdu_session_modification> sm_session_modification) {
//Transfer N1/N2 message via AMF by using N_amf_Communication_N1N2MessageTransfer (see TS29518_Namf_Communication.yaml)
Logger::smf_n11().debug("Send Communication_N1N2MessageTransfer to AMF");
smf_n1_n2 smf_n1_n2_inst = { };
std::string n1_message = sm_context_res->msg.get_n1_sm_message();
std::string json_part = sm_context_res->msg.n1n2_message_transfer_data.dump();
mime_parser parser = {};
std::string body;
smf_n1_n2 smf_n1_n2_inst = { };
nlohmann::json json_data = {};
std::string json_part;
std::string n1_message = sm_session_modification->msg.get_n1_sm_message();
sm_session_modification->msg.get_json_data(json_data);
json_part = json_data.dump();
//add N2 content if available
auto n2_sm_found = sm_context_res->msg.n1n2_message_transfer_data.count(
auto n2_sm_found = json_data.count(
"n2InfoContainer");
if (n2_sm_found > 0) {
std::string n2_message = sm_context_res->msg.get_n2_sm_information();
//prepare the body content for Curl
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
std::string n2_message = sm_session_modification->msg.get_n2_sm_information();
parser.create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
n2_message);
} else {
//prepare the body content for Curl
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
parser.create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
multipart_related_content_part_e::NAS);
}
unsigned int str_len = body.length();
uint32_t 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);
......@@ -285,11 +284,20 @@ void smf_n11::send_n1n2_message_transfer_request(
headers = curl_slist_append(headers, content_type.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL,
sm_context_res->msg.get_amf_url().c_str());
sm_session_modification->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());
if (sm_session_modification->http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -319,7 +327,6 @@ void smf_n11::send_n1n2_message_transfer_request(
}
curl_global_cleanup();
free_wrapper((void**) &data);
}
//------------------------------------------------------------------------------
......@@ -329,25 +336,28 @@ void smf_n11::send_n1n2_message_transfer_request(
Logger::smf_n11().debug(
"Send Communication_N1N2MessageTransfer to AMF (Network-initiated Service Request)");
mime_parser parser = {};
smf_n1_n2 smf_n1_n2_inst = { };
std::string n2_message = report_msg->res.get_n2_sm_information();
std::string json_part = report_msg->res.n1n2_message_transfer_data.dump();
nlohmann::json json_data = {};
std::string body;
report_msg->res.get_json_data(json_data);
std::string json_part = json_data.dump();
//add N1 content if available
auto n1_sm_found = report_msg->res.n1n2_message_transfer_data.count(
auto n1_sm_found = json_data.count(
"n1MessageContainer");
if (n1_sm_found > 0) {
std::string n1_message = report_msg->res.get_n1_sm_message();
//prepare the body content for Curl
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
parser.create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
n2_message);
} else {
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n2_message,
parser.create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n2_message,
multipart_related_content_part_e::NGAP);
}
unsigned int str_len = body.length();
uint32_t 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);
......@@ -368,6 +378,15 @@ void smf_n11::send_n1n2_message_transfer_request(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
curl_easy_setopt(curl, CURLOPT_INTERFACE, smf_cfg.sbi.if_name.c_str());
if (report_msg->http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
// we use a self-signed test server, skip verification during debugging
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -421,330 +440,4 @@ void smf_n11::send_n1n2_message_transfer_request(
}
curl_global_cleanup();
free_wrapper((void**) &data);
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_update_sm_context_response(
std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res) {
Logger::smf_n11().debug("Send PDUSession_UpdateSMContext Response to AMF.");
switch (sm_context_res->session_procedure_type) {
case session_management_procedures_type_e::PDU_SESSION_TEST: {
Logger::smf_n11().debug("PDU_SESSION_TEST");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
std::string n1_message = sm_context_res->res.get_n1_sm_message();
std::string n2_message = sm_context_res->res.get_n2_sm_information();
std::string body;
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
n2_message);
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
}
break;
case session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED: {
Logger::smf_n11().info("PDU_SESSION_ESTABLISHMENT_UE_REQUESTED");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
sm_context_res->http_response.send(Pistache::Http::Code::Ok,
json_part.c_str());
}
break;
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP1: {
Logger::smf_n11().info("PDU_SESSION_MODIFICATION_UE_INITIATED (step 1)");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
std::string n1_message = sm_context_res->res.get_n1_sm_message();
std::string n2_message = sm_context_res->res.get_n2_sm_information();
std::string body;
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
n2_message);
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
}
break;
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP2: {
Logger::smf_n11().info("PDU_SESSION_MODIFICATION_UE_INITIATED (step 2)");
sm_context_res->http_response.send(Pistache::Http::Code::No_Content);
}
break;
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP3: {
Logger::smf_n11().info("PDU_SESSION_MODIFICATION_UE_INITIATED (step 3)");
sm_context_res->http_response.send(Pistache::Http::Code::No_Content);
}
break;
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1: {
Logger::smf_n11().info("SERVICE_REQUEST_UE_TRIGGERED (step 1)");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
std::string n2_message = sm_context_res->res.get_n2_sm_information();
std::string body;
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n2_message,
multipart_related_content_part_e::NGAP);
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
}
break;
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP2: {
Logger::smf_n11().info("SERVICE_REQUEST_UE_TRIGGERED (step 2)");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
sm_context_res->http_response.send(Pistache::Http::Code::Ok,
json_part.c_str());
}
break;
case session_management_procedures_type_e::PDU_SESSION_RELEASE_UE_REQUESTED_STEP1: {
Logger::smf_n11().info("PDU_SESSION_RELEASE_UE_REQUESTED (step 1)");
std::string json_part =
sm_context_res->res.sm_context_updated_data.dump();
std::string n1_message = sm_context_res->res.get_n1_sm_message();
std::string n2_message = sm_context_res->res.get_n2_sm_information();
std::string body;
create_multipart_related_content(body, json_part, CURL_MIME_BOUNDARY, n1_message,
n2_message);
sm_context_res->http_response.headers()
.add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
sm_context_res->http_response.send(Pistache::Http::Code::Ok, body);
}
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!");
}
}
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
Pistache::Http::Code code) {
Logger::smf_n11().debug("Send PDUSession_UpdateSMContext Response to AMF.");
nlohmann::json json_data = { };
to_json(json_data, smContextUpdateError);
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::send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
Pistache::Http::Code code, std::string &n1_sm_msg) {
Logger::smf_n11().debug("Send PDUSession_UpdateSMContext Response to AMF.");
nlohmann::json json_part = { };
to_json(json_part, smContextUpdateError);
std::string json_str = json_part.dump();
std::string body;
create_multipart_related_content(body, json_str, CURL_MIME_BOUNDARY, n1_sm_msg,
multipart_related_content_part_e::NAS);
httpResponse.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
httpResponse.send(code, body);
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_create_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextCreateError &smContextCreateError,
Pistache::Http::Code code, std::string &n1_sm_msg) {
Logger::smf_n11().debug("Send PDUSession_CreateSMContext Response to AMF.");
nlohmann::json json_part = { };
to_json(json_part, smContextCreateError);
std::string json_str = json_part.dump();
std::string body;
create_multipart_related_content(body, json_str, CURL_MIME_BOUNDARY, n1_sm_msg,
multipart_related_content_part_e::NAS);
httpResponse.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
httpResponse.send(code, body);
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextUpdatedData &smContextUpdatedData,
Pistache::Http::Code code) {
Logger::smf_n11().debug("Send PDUSession_UpdateSMContext Response to AMF.");
nlohmann::json json_data = { };
to_json(json_data, smContextUpdatedData);
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::send_pdu_session_create_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextCreatedData &smContextCreatedData,
Pistache::Http::Code code) {
Logger::smf_n11().debug("Send PDUSession_CreateSMContext Response to AMF.");
nlohmann::json json_data = { };
to_json(json_data, smContextCreatedData);
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::send_n1n2_message_transfer_request(
std::shared_ptr<itti_n11_modify_session_request_smf_requested> sm_context_mod) {
//TODO:
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_release_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse, Pistache::Http::Code code) {
Logger::smf_n11().debug("Send PDUSession_ReleaseSMContext Response to AMF.");
httpResponse.send(code);
}
//------------------------------------------------------------------------------
void smf_n11::send_pdu_session_release_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::ProblemDetails &problem,
Pistache::Http::Code code) {
Logger::smf_n11().debug("Send PDUSession_ReleaseSMContext Response 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,
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message) {
//format string as hex
unsigned char *n1_msg_hex = smf_app_inst->format_string_as_hex(n1_message);
unsigned char *n2_msg_hex = smf_app_inst->format_string_as_hex(n2_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);
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF + "Content-Id: n1SmMsg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n1_msg_hex, n1_message.length() / 2) + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n2_msg_hex, n2_message.length() / 2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
//------------------------------------------------------------------------------
void smf_n11::create_multipart_related_content(
std::string &body, const std::string &json_part, const std::string boundary,
const std::string &message, const multipart_related_content_part_e content_type) {
//format string as hex
unsigned char *msg_hex = smf_app_inst->format_string_as_hex(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);
if (content_type == multipart_related_content_part_e::NAS) { //NAS
body.append(
"Content-Type: application/vnd.3gpp.5gnas" + CRLF
+ "Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { //NGAP
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
+ CRLF);
}
body.append(CRLF);
body.append(std::string((char*) msg_hex, message.length() / 2) + CRLF);
body.append("--" + boundary + "--" + CRLF);
}
......@@ -61,11 +61,11 @@ class smf_n11 {
/*
* Send N1N2 Message Transfer Request to AMF
* @param [std::shared_ptr<itti_nx_trigger_pdu_session_modification>] sm_context_res: Content of message to be sent
* @param [std::shared_ptr<itti_nx_trigger_pdu_session_modification>] sm_session_modification: Content of message to be sent
* @return void
*/
void send_n1n2_message_transfer_request(
std::shared_ptr<itti_nx_trigger_pdu_session_modification> sm_context_res);
std::shared_ptr<itti_nx_trigger_pdu_session_modification> sm_session_modification);
/*
* Send N1N2 Message Transfer Request to AMF
......@@ -75,146 +75,6 @@ class smf_n11 {
void send_n1n2_message_transfer_request(
std::shared_ptr<itti_n11_session_report_request> report_msg);
/*
* Send update session response to AMF
* @param [std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res] sm_context_res
* @return void
*/
void send_pdu_session_update_sm_context_response(
std::shared_ptr<itti_n11_update_sm_context_response> sm_context_res);
/*
* Send N1N2 Message Transfer Request to AMF
* @param [std::shared_ptr<itti_n11_modify_session_request_smf_requested>] sm_context_mod: Content of message to be sent
* @return void
*/
void send_n1n2_message_transfer_request(
std::shared_ptr<itti_n11_modify_session_request_smf_requested> sm_context_mod);
/*
* Send update session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [const oai::smf_server::model::SmContextUpdateError] SmContextUpdateError
* @param [Pistache::Http::Code] code, response code
* @return void
*/
void send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
Pistache::Http::Code code);
/*
* Send Update session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [const oai::smf_server::model::SmContextUpdatedData] smContextUpdatedData
* @param [Pistache::Http::Code] code, response code
* @return void
*/
void send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextUpdatedData &smContextUpdatedData,
Pistache::Http::Code code);
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [const oai::smf_server::model::SmContextCreateError] smContextCreateError
* @param [Pistache::Http::Code] code, response code
* @return void
*/
void send_pdu_session_create_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextCreateError &smContextCreateError,
Pistache::Http::Code code);
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [const oai::smf_server::model::SmContextCreateError] smContextCreateError
* @param [Pistache::Http::Code] code, response code
* @param [std::string] n1_sm_msg, N1 SM message content
* @return void
*/
void send_pdu_session_create_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextCreateError &smContextCreateError,
Pistache::Http::Code code, std::string &n1_sm_msg);
/*
* Send update session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [const oai::smf_server::model::SmContextUpdateError] smContextUpdateError
* @param [Pistache::Http::Code] code, response code
* @param [std::string] n1_sm_msg, N1 SM message content
* @return void
*/
void send_pdu_session_update_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const oai::smf_server::model::SmContextUpdateError &smContextUpdateError,
Pistache::Http::Code code, std::string &n1_sm_msg);
/*
* Send create session response to AMF
* @param [Pistache::Http::ResponseWriter] httpResponse
* @param [const oai::smf_server::model::SmContextCreatedData] smContextCreatedData
* @param [Pistache::Http::Code] code, response code
* @return void
*/
void send_pdu_session_create_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const 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
* @return void
*/
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 [const oai::smf_server::model::ProblemDetails] problem
* @param [Pistache::Http::Code] code, response code
* @return void
*/
void send_pdu_session_release_sm_context_response(
Pistache::Http::ResponseWriter &httpResponse,
const 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
* @param [std::string] json_part: Json part of multipart/related msg
* @param [std::string] boundary: Boundary of multipart/related msg
* @param [std::string] n1_message: N1 (NAS) part
* @param [std::string] n2_message: N2 (NGAP) part
* @return void
*/
void create_multipart_related_content(std::string &body,
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message);
/*
* Create HTTP body content for multipart/related message
* @param [std::string] body: Body of the created message
* @param [std::string] json_part: Json part of multipart/related msg
* @param [std::string] boundary: Boundary of multipart/related msg
* @param [std::string] message: N1 (NAS) or N2 (NGAP) part
* @param [uint8_t] content_type: 1 for NAS content, else NGAP content
* @return void
*/
void create_multipart_related_content(
std::string &body, const std::string &json_part, const std::string boundary,
const std::string &message, const multipart_related_content_part_e content_type);
};
}
#endif /* FILE_SMF_N11_HPP_SEEN */
......@@ -32,6 +32,7 @@
#include "3gpp_29.244.h"
#include "3gpp_29.274.h"
#include "3gpp_29.500.h"
#include "common_defs.h"
#include "3gpp_conversions.hpp"
#include "conversions.hpp"
......@@ -105,7 +106,8 @@ int session_create_sm_context_procedure::run(
if (not pfcp_associations::get_instance().select_up_node(
up_node_id, NODE_SELECTION_CRITERIA_MIN_PFCP_SESSIONS)) {
// TODO
sm_context_resp->res.set_cause(REMOTE_PEER_NOT_RESPONDING); //verify for 5G??
sm_context_resp->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING);
return RETURNerror ;
}
......@@ -151,7 +153,7 @@ int session_create_sm_context_procedure::run(
pfcp::destination_interface_t destination_interface = { };
sps->generate_far_id(far_id);
apply_action.forw = 1; //forward the packets
apply_action.forw = 1; //forward the packets
//wys-test-add
pfcp::outer_header_creation_t outer_header_creation = { };
......@@ -395,9 +397,6 @@ void session_create_sm_context_procedure::handle_itti_msg(
std::string n1_sm_msg, n1_sm_msg_hex;
std::string n2_sm_info, n2_sm_info_hex;
//TODO: should comment this line when including UPF in the test
//n11_triggered_pending->res.set_cause(REQUEST_ACCEPTED); //for testing purpose
if (n11_triggered_pending->res.get_cause() != REQUEST_ACCEPTED) { //PDU Session Establishment Reject
Logger::smf_app().debug(
"Prepare a PDU Session Establishment Reject message and send to UE");
......@@ -456,36 +455,37 @@ void session_create_sm_context_procedure::handle_itti_msg(
"N1N2MessageTransfer will be sent to AMF with URL: %s", url.c_str());
//Fill the json part
nlohmann::json json_data = { };
//N1SM
n11_triggered_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageClass"] =
json_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS;
n11_triggered_pending->res.n1n2_message_transfer_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
json_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID; //NAS part
//N2SM
if (n11_triggered_pending->res.get_cause() == REQUEST_ACCEPTED) {
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["n2InformationClass"] =
json_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
n11_triggered_pending->res.get_pdu_session_id();
//N2InfoContent (section 6.1.6.2.27@3GPP TS 29.518)
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_SETUP_REQ"; //NGAP message type
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID; //NGAP part
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] =
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sst"] =
n11_triggered_pending->res.get_snssai().sST;
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
n11_triggered_pending->res.get_snssai().sD;
n11_triggered_pending->res.n1n2_message_transfer_data["n2InfoContainer"]["ranInfo"] =
"SM";
json_data["n2InfoContainer"]["ranInfo"] = "SM";
}
//Others information
//n11_triggered_pending->res.n1n2_message_transfer_data["pti"] = 1; //Don't need this info for the moment
n11_triggered_pending->res.n1n2_message_transfer_data["pduSessionId"] =
n11_triggered_pending->res.get_pdu_session_id();
json_data["pduSessionId"] = n11_triggered_pending->res.get_pdu_session_id();
n11_triggered_pending->res.set_json_data(json_data);
//send ITTI message to N11 interface to trigger N1N2MessageTransfer towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
//send ITTI message to APP to trigger N1N2MessageTransfer towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_APP",
n11_triggered_pending->get_msg_name());
int ret = itti_inst->send_msg(n11_triggered_pending);
......@@ -494,7 +494,6 @@ void session_create_sm_context_procedure::handle_itti_msg(
"Could not send ITTI message %s to task TASK_SMF_N11",
n11_triggered_pending->get_msg_name());
}
}
//------------------------------------------------------------------------------
......@@ -503,18 +502,16 @@ int session_update_sm_context_procedure::run(
std::shared_ptr<itti_n11_update_sm_context_response> sm_context_resp,
std::shared_ptr<smf::smf_context> sc) {
//Handle SM update sm context request
//first try to reuse from CUPS....
//The SMF initiates an N4 Session Modification procedure with the UPF. The SMF provides AN Tunnel Info to the UPF as well as the corresponding forwarding rules
bool send_n4 = false;
Logger::smf_app().info("Perform a procedure - Update 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_resp->res.set_cause(REMOTE_PEER_NOT_RESPONDING); //verify for 5G??
sm_context_resp->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING);
Logger::smf_app().info("[SMF Procedure] REMOTE_PEER_NOT_RESPONDING");
return RETURNerror ;
}
......@@ -546,69 +543,6 @@ int session_update_sm_context_procedure::run(
.c_str());
switch (session_procedure_type) {
/*
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1: {
//PFCP Session Modification to delete AN Tunnel info
for (auto qfi : list_of_qfis_to_be_modified) {
smf_qos_flow flow = { };
if (!sps->get_qos_flow(qfi, flow)) { //no QoS flow found
Logger::smf_app().error("Could not found any QoS flow with QFI %d",
qfi.qfi);
//Set cause to SYSTEM_FAILURE and send response
qos_flow_context_updated qcu = { };
qcu.set_cause(SYSTEM_FAILURE);
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
continue;
}
pfcp::far_id_t far_id = { };
pfcp::pdr_id_t pdr_id = { };
//if FAR DL exist -> remove it
if ((flow.far_id_dl.first) && (flow.far_id_dl.second.far_id)) {
Logger::smf_app().debug(
"Send a request to remove FAR DL at UPF (QFI %d, FAR ID " "0x%" PRIx32 ")",
flow.qfi, flow.far_id_dl.second.far_id);
// Remove FAR
far_id.far_id = flow.far_id_dl.second.far_id;
pfcp::remove_far remove_far = { };
remove_far.set(flow.far_id_dl.second);
n4_ser->pfcp_ies.set(remove_far);
send_n4 = true;
//qos_flow.far_id_dl.first = true;
}
//remove PDR DL if exist
if (flow.pdr_id_dl.rule_id) {
Logger::smf_app().debug(
"Update SM Context procedure: send a request to remove PDR DL at UPF");
Logger::smf_app().debug(
"Send a request to remove PDR DL at UPF (QFI %d, PDR ID " "0x%" PRIx16 ")",
flow.qfi, flow.pdr_id_dl.rule_id);
//Remove PDR DL
pdr_id.rule_id = flow.pdr_id_dl.rule_id;
pfcp::remove_pdr remove_pdr = { };
remove_pdr.set(flow.pdr_id_dl);
n4_ser->pfcp_ies.set(remove_pdr);
send_n4 = true;
}
// may be modified
smf_qos_flow flow2 = flow;
sps->add_qos_flow(flow2);
qos_flow_context_updated qcu = { };
qcu.set_cause(REQUEST_ACCEPTED);
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
}
}
break;
*/
case session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED:
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP2:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_SMF_REQUESTED:
......@@ -662,7 +596,7 @@ int session_update_sm_context_procedure::run(
.s_addr;
update_forwarding_parameters.set(outer_header_creation);
update_far.set(update_forwarding_parameters);
apply_action.forw = 1; //forward the packets
apply_action.forw = 1; //forward the packets
//apply_action.nocp = 1; //notify the CP function about the arrival of a first DL packet
update_far.set(apply_action);
......@@ -693,7 +627,7 @@ int session_update_sm_context_procedure::run(
//pfcp::proxying_t proxying = {};
sps->generate_far_id(far_id);
apply_action.forw = 1; //forward the packets
apply_action.forw = 1; //forward the packets
//apply_action.nocp = 1; //notify the CP function about the arrival of a first DL packet
destination_interface.interface_value = pfcp::INTERFACE_VALUE_ACCESS; // ACCESS is for downlink, CORE for uplink
......@@ -876,7 +810,7 @@ int session_update_sm_context_procedure::run(
far_id.far_id = flow.far_id_dl.second.far_id;
// apply_action.buff = 1;
pfcp::apply_action_t apply_action = { };
apply_action.nocp = 1; //notify the CP function about the arrival of a first DL packet
apply_action.nocp = 1; //notify the CP function about the arrival of a first DL packet
far.set(far_id);
far.set(apply_action);
......@@ -912,14 +846,13 @@ int session_update_sm_context_procedure::run(
sps->add_qos_flow(flow2);
}
}
break;
default: {
Logger::smf_app().error(
"Update SM Context procedure: Unknown session management type %d",
session_procedure_type);
}
}
if (send_n4) {
......@@ -937,9 +870,7 @@ int session_update_sm_context_procedure::run(
"Update SM Context procedure: There is no QoS flow to be modified");
return RETURNerror ;
}
return RETURNok ;
}
//------------------------------------------------------------------------------
......@@ -983,7 +914,8 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_trigger->req.get_dl_fteid(dl_fteid);
Logger::smf_app().debug("AN F-TEID ID" "0x%" PRIx32 ", IP Addr %s",
dl_fteid.teid_gre_key, conv::toString(dl_fteid.ipv4_address).c_str());
dl_fteid.teid_gre_key,
conv::toString(dl_fteid.ipv4_address).c_str());
std::map<uint8_t, qos_flow_context_updated> qos_flow_context_to_be_updateds =
{ };
......@@ -1038,7 +970,6 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
//TODO: remove this QFI from the list (as well as in n11_trigger->req)
break;
}
}
} else {
......@@ -1090,12 +1021,11 @@ void session_update_sm_context_procedure::handle_itti_msg(
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
n11_triggered_pending->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
return;
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n11_triggered_pending->pid);
}
}
break;
......@@ -1108,20 +1038,18 @@ void session_update_sm_context_procedure::handle_itti_msg(
//clear the resources including addresses allocated to this Session and associated QoS flows
sps->deallocate_ressources(n11_trigger.get()->req.get_dnn()); //TODO: for IPv6 (only for Ipv4 for the moment)
}
}
}
n11_triggered_pending->res.set_cause(cause.cause_value);
n11_triggered_pending->res.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK);
// TODO
// check we got all responses vs n11_triggered_pending->res.flow_context_modified
//TODO: Optional: send ITTI message to N10 to trigger UDM registration (Nudm_UECM_Registration)
//see TS29503_Nudm_UECM.yaml ( /{ueId}/registrations/smf-registrations/{pduSessionId}:)
/* std::shared_ptr<itti_n10_create_smf_registration_request> itti_msg = std::make_shared<itti_n10_create_smf_registration_request>(TASK_SMF_APP, TASK_SMF_N10, response);
int ret = itti_inst->send_msg(itti_msg);
*/
//Prepare response to send to AMF (N1N2MessageTransfer or PDUSession_UpdateSMContextResponse)
nlohmann::json sm_context_updated_data = { };
......@@ -1136,13 +1064,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID;
//SHOULD BE REMOVED, FOR TESTING PURPOSE
//change value here to test the corresponding message
//session_procedure_type =
// session_management_procedures_type_e::PDU_SESSION_TEST;
switch (session_procedure_type) {
//FOR TESTING PURPOSE
case session_management_procedures_type_e::PDU_SESSION_TEST: {
//N1 SM
......@@ -1159,10 +1081,9 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.set_n2_sm_information(n2_sm_info_hex);
//fill the content of SmContextUpdatedData
n11_triggered_pending->res.sm_context_updated_data =
sm_context_updated_data;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_MOD_RSP"; //NGAP message
n11_triggered_pending->res.set_json_data(sm_context_updated_data);
}
break;
......@@ -1171,15 +1092,15 @@ void session_update_sm_context_procedure::handle_itti_msg(
//No need to create N1/N2 Container, just Cause
Logger::smf_app().info(
"PDU Session Establishment Request (UE-Initiated)");
n11_triggered_pending->res.sm_context_updated_data["cause"] =
n11_triggered_pending->res.get_cause();
nlohmann::json json_data = { };
json_data["cause"] = n11_triggered_pending->res.get_cause();
n11_triggered_pending->res.set_json_data(json_data);
//Update PDU session status to ACTIVE
sps->set_pdu_session_status(pdu_session_status_e::PDU_SESSION_ACTIVE);
//set UpCnxState to DEACTIVATED
sps->set_upCnx_state(upCnx_state_e::UPCNX_STATE_ACTIVATED);
}
break;
......@@ -1195,22 +1116,21 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.set_n2_sm_information(n2_sm_info_hex);
//fill the content of SmContextUpdatedData
n11_triggered_pending->res.sm_context_updated_data = { };
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] =
nlohmann::json json_data = { };
json_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
n11_triggered_pending->res.get_pdu_session_id();
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_SETUP_REQ"; //NGAP message
n11_triggered_pending->res.sm_context_updated_data["upCnxState"] =
"ACTIVATING";
json_data["upCnxState"] = "ACTIVATING";
n11_triggered_pending->res.set_json_data(json_data);
//TODO: verify whether cause is needed (as in 23.502 but not in 3GPP TS 29.502)
//Update upCnxState to ACTIVATING
sps->set_upCnx_state(upCnx_state_e::UPCNX_STATE_ACTIVATING);
}
break;
......@@ -1218,8 +1138,12 @@ void session_update_sm_context_procedure::handle_itti_msg(
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP2: {
//No need to create N1/N2 Container, just Cause
Logger::smf_app().info("UE Triggered Service Request (Step 2)");
n11_triggered_pending->res.sm_context_updated_data["cause"] =
n11_triggered_pending->res.get_cause();
nlohmann::json json_data = { };
json_data["cause"] = n11_triggered_pending->res.get_cause();
json_data["upCnxState"] = "ACTIVATED";
n11_triggered_pending->res.set_json_data(json_data);
n11_triggered_pending->res.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK);
}
break;
......@@ -1261,17 +1185,17 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.set_n2_sm_information(n2_sm_info_hex);
//fill the content of SmContextUpdatedData
n11_triggered_pending->res.sm_context_updated_data =
sm_context_updated_data;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_REL_CMD"; //NGAP message
n11_triggered_pending->res.set_json_data(sm_context_updated_data);
} else {
//fill the content of SmContextUpdatedData
n11_triggered_pending->res.sm_context_updated_data = { };
n11_triggered_pending->res.sm_context_updated_data["n1MessageContainer"]["n1MessageClass"] =
nlohmann::json json_data = { };
json_data["n1MessageContainer"]["n1MessageClass"] =
N1N2_MESSAGE_CLASS;
n11_triggered_pending->res.sm_context_updated_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
json_data["n1MessageContainer"]["n1MessageContent"]["contentId"] =
N1_SM_CONTENT_ID;
n11_triggered_pending->res.set_json_data(json_data);
}
//Update PDU session status to PDU_SESSION_INACTIVE_PENDING
......@@ -1315,14 +1239,14 @@ void session_update_sm_context_procedure::handle_itti_msg(
}
}
//send ITTI message to N11 interface to trigger SessionUpdateSMContextResponse towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_N11",
//send ITTI message to SMF_APP interface to trigger SessionUpdateSMContextResponse towards AMFs
Logger::smf_app().info("Sending ITTI message %s to task TASK_SMF_APP",
n11_triggered_pending->get_msg_name());
n11_triggered_pending->session_procedure_type = session_procedure_type;
int ret = itti_inst->send_msg(n11_triggered_pending);
if (RETURNok != ret) {
Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_SMF_N11",
"Could not send ITTI message %s to task TASK_SMF_APP",
n11_triggered_pending->get_msg_name());
}
......@@ -1353,7 +1277,8 @@ int session_release_sm_context_procedure::run(
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??
sm_context_res->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING);
Logger::smf_app().info("REMOTE_PEER_NOT_RESPONDING");
return RETURNerror ;
}
......@@ -1403,16 +1328,18 @@ void session_release_sm_context_procedure::handle_itti_msg(
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
sps->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);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_204_NO_CONTENT,
n11_triggered_pending->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
} 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);
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE,
n11_triggered_pending->pid, N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
}
//TODO:
......
......@@ -103,6 +103,7 @@ class n4_session_restore_procedure : public smf_procedure {
std::set<pfcp::fseid_t> restored_sessions;
};
//------------------------------------------------------------------------------
class session_create_sm_context_procedure : public smf_procedure {
public:
......@@ -143,6 +144,7 @@ class session_create_sm_context_procedure : public smf_procedure {
std::shared_ptr<itti_n11_create_sm_context_response> n11_triggered_pending;
};
//------------------------------------------------------------------------------
class session_update_sm_context_procedure : public smf_procedure {
public:
......
......@@ -5,6 +5,12 @@
#include <unistd.h>
#include <stdexcept>
#ifndef CURLPIPE_MULTIPLEX
#define CURLPIPE_MULTIPLEX 0
#endif
#define HTTP_V1 1
#define HTTP_V2 2
/*
* To read content of the response from UDM
*/
......@@ -157,7 +163,9 @@ void create_multipart_related_content(
}
//------------------------------------------------------------------------------
void send_pdu_session_establishment_request(std::string smf_ip_address) {
void send_pdu_session_establishment_request(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Create)"
<< std::endl;
......@@ -185,6 +193,10 @@ void send_pdu_session_establishment_request(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts"));
//Fill the json part
......@@ -231,6 +243,19 @@ void send_pdu_session_establishment_request(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -253,8 +278,9 @@ void send_pdu_session_establishment_request(std::string smf_ip_address) {
std::cout << "Could not get json data from the response" << std::endl;
}
std::cout
<< "[AMF N11] PDU session establishment request, response from SMF, Http Code "
<< httpCode << std::endl;
<< "[AMF N11] PDU session establishment request, response from SMF "
<< response_data.dump().c_str() << ", Http Code " << httpCode
<< std::endl;
curl_easy_cleanup(curl);
}
......@@ -265,7 +291,7 @@ void send_pdu_session_establishment_request(std::string smf_ip_address) {
//------------------------------------------------------------------------------
void send_pdu_session_update_sm_context_establishment(
std::string smf_ip_address) {
std::string smf_ip_address, uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Update)"
<< std::endl;
......@@ -299,6 +325,11 @@ void send_pdu_session_update_sm_context_establishment(
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -337,6 +368,19 @@ void send_pdu_session_update_sm_context_establishment(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -374,7 +418,9 @@ void send_pdu_session_update_sm_context_establishment(
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
void send_pdu_session_modification_request_step1(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Modification Request (SM Context Update, Step 1)"
......@@ -427,6 +473,11 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -460,6 +511,19 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -493,7 +557,9 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address) {
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step2(std::string smf_ip_address) {
void send_pdu_session_modification_request_step2(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Modification procedure (SM Context Update, step 2)"
......@@ -528,6 +594,11 @@ void send_pdu_session_modification_request_step2(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -561,6 +632,19 @@ void send_pdu_session_modification_request_step2(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -594,7 +678,9 @@ void send_pdu_session_modification_request_step2(std::string smf_ip_address) {
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_complete(std::string smf_ip_address) {
void send_pdu_session_modification_complete(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Modification Complete (Update SM Context): N1 SM - PDU Session Modification Complete"
......@@ -620,6 +706,11 @@ void send_pdu_session_modification_complete(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -652,6 +743,19 @@ void send_pdu_session_modification_complete(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -685,7 +789,8 @@ void send_pdu_session_modification_complete(std::string smf_ip_address) {
}
//------------------------------------------------------------------------------
void send_pdu_session_release_request(std::string smf_ip_address) {
void send_pdu_session_release_request(std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release Request (SM Context Update)"
<< std::endl;
......@@ -712,6 +817,11 @@ void send_pdu_session_release_request(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -745,6 +855,19 @@ void send_pdu_session_release_request(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -778,7 +901,9 @@ 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,
uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] PDU Session Release Ack (Update SM Context): N2 SM - Resource Release Ack"
......@@ -799,6 +924,11 @@ void send_pdu_session_release_resource_release_ack(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -832,6 +962,19 @@ void send_pdu_session_release_resource_release_ack(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -855,7 +998,7 @@ void send_pdu_session_release_resource_release_ack(std::string smf_ip_address) {
}
std::cout
<< "[AMF N11] PDU Session Establishment Request, response from SMF, Http Code "
<< "[AMF N11] PDU Session Release Ack, response from SMF, Http Code "
<< httpCode << std::endl;
curl_easy_cleanup(curl);
......@@ -866,7 +1009,8 @@ void send_pdu_session_release_resource_release_ack(std::string smf_ip_address) {
}
//------------------------------------------------------------------------------
void send_pdu_session_release_complete(std::string smf_ip_address) {
void send_pdu_session_release_complete(std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout
<< "[AMF N11] PDU Session Release Complete (Update SM Context): N1 SM - PDU Session Release Complete"
......@@ -895,6 +1039,11 @@ void send_pdu_session_release_complete(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -928,6 +1077,19 @@ void send_pdu_session_release_complete(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -962,7 +1124,7 @@ void send_pdu_session_release_complete(std::string smf_ip_address) {
//------------------------------------------------------------------------------
void send_pdu_session_update_sm_context_ue_service_request(
std::string smf_ip_address) {
std::string smf_ip_address, uint8_t http_version, std::string port) {
std::cout
<< "[AMF N11] UE-triggered Service Request (SM Context Update Step 1)"
<< std::endl;
......@@ -972,6 +1134,11 @@ void send_pdu_session_update_sm_context_ue_service_request(
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//PDU session ID (as specified in section 4.2.3.2 @ 3GPP TS 23.502, but can't find in Yaml file)
......@@ -996,6 +1163,19 @@ void send_pdu_session_update_sm_context_ue_service_request(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -1029,7 +1209,7 @@ 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::string smf_ip_address, uint8_t http_version, std::string port) {
std::cout
<< "[AMF N11] UE-triggered Service Request (SM Context Update Step 2)"
<< std::endl;
......@@ -1064,6 +1244,11 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
//url.append(std::string(":9090"));
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
......@@ -1105,6 +1290,19 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -1142,7 +1340,8 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
}
//------------------------------------------------------------------------------
void send_release_sm_context_request(std::string smf_ip_address) {
void send_release_sm_context_request(std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release SM context Request" << std::endl;
......@@ -1150,6 +1349,10 @@ void send_release_sm_context_request(std::string smf_ip_address) {
std::string url = std::string("http://");
url.append(smf_ip_address);
if (http_version == 2) {
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/release"));
//Fill the json part
......@@ -1171,6 +1374,19 @@ void send_release_sm_context_request(std::string smf_ip_address) {
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
//curl_easy_setopt(curl, CURLOPT_INTERFACE, "eno1:amf"); //hardcoded
if (http_version == 2) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* we use a self-signed test server, skip verification during debugging */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION,
CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
#if (CURLPIPE_MULTIPLEX > 0)
/* wait for pipe connection to confirm */
curl_easy_setopt(curl, CURLOPT_PIPEWAIT, 1L);
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
......@@ -1205,10 +1421,16 @@ void send_release_sm_context_request(std::string smf_ip_address) {
//------------------------------------------------------------------------------
int main(int argc, char *argv[]) {
std::string smf_ip_address;
uint8_t http_version = 1;
std::string port;
http_version = 1;
port = std::string("80");
if ((argc != 1) && (argc != 3)) {
if ((argc != 1) && (argc != 3) && (argc != 5) && (argc != 7)) {
std::cout << "Error: Usage is " << std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz ]" << std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz -v 1 -p 9090]"
<< std::endl;
return -1;
}
......@@ -1216,46 +1438,63 @@ int main(int argc, char *argv[]) {
smf_ip_address.append(std::string("192.168.28.2"));
} else {
int opt = 0;
while ((opt = getopt(argc, argv, "i:")) != -1) {
while ((opt = getopt(argc, argv, "i:v:p:")) != -1) {
switch (opt) {
case 'i':
smf_ip_address.append(optarg);
break;
case 'v':
http_version = std::stoi(optarg);
break;
case 'p':
port = std::string(optarg);
break;
default:
std::cout << "Error: Usage is " << std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz ]" << std::endl;
std::cout << " " << argv[0] << " [ -i www.xxx.yy.zz -v 1 -p 9090]"
<< std::endl;
return -1;
break;
}
}
}
std::cout << "Command line options: -i " << smf_ip_address.c_str() << ", -v "
<< std::to_string(http_version) << ", -p " << port.c_str()
<< std::endl;
//PDU Session Establishment procedure
send_pdu_session_establishment_request(smf_ip_address);
send_pdu_session_establishment_request(smf_ip_address, http_version, port);
usleep(100000);
send_pdu_session_update_sm_context_establishment(smf_ip_address);
send_pdu_session_update_sm_context_establishment(smf_ip_address, http_version,
port);
usleep(200000);
//UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address);
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address);
send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address,
http_version,
port);
usleep(200000);
//PDU Session Modification
send_pdu_session_modification_request_step1(smf_ip_address);
send_pdu_session_modification_request_step1(smf_ip_address, http_version,
port);
usleep(200000);
send_pdu_session_modification_request_step2(smf_ip_address);
send_pdu_session_modification_request_step2(smf_ip_address, http_version,
port);
usleep(200000);
send_pdu_session_modification_complete(smf_ip_address);
send_pdu_session_modification_complete(smf_ip_address, http_version, port);
usleep(200000);
//PDU Session Release procedure
send_pdu_session_release_request(smf_ip_address);
send_pdu_session_release_request(smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_release_resource_release_ack(smf_ip_address);
send_pdu_session_release_resource_release_ack(smf_ip_address, http_version,
port);
usleep(200000);
send_pdu_session_release_complete(smf_ip_address);
send_pdu_session_release_complete(smf_ip_address, http_version, port);
usleep(200000);
//Release SM context
//send_release_sm_context_request(smf_ip_address);
//send_release_sm_context_request(smf_ip_address, http_version, port);
return 0;
}
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