Commit e08a5729 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'http2' into 'develop'

HTTP version 2

See merge request oai/oai-cn5g-smf!12
parents 89d041b9 18da34cb
......@@ -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
......@@ -197,6 +197,72 @@ install_nlohmann_from_git() {
return 0
}
#-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script)
#arg2 is debug (0 or 1) (install debug libraries)
install_nghttp2_from_git() {
if [ $1 -eq 0 ]; then
read -p "Do you want to install nghttp2 ? <y/N> " prompt
OPTION="-y"
else
prompt='y'
OPTION="-y"
fi
if [ $2 -eq 0 ]; then
debug=0
else
debug=1
fi
if [[ $prompt =~ [yY](es)* ]]
then
$SUDO apt-get install $OPTION \
g++ \
cmake \
binutils \
autoconf \
automake \
autotools-dev \
libtool \
pkg-config \
zlib1g-dev \
libcunit1-dev \
libssl-dev \
libxml2-dev libev-dev libevent-dev libjansson-dev libc-ares-dev \
libjemalloc-dev libsystemd-dev cython python3-dev python-setuptools
ret=$?;[[ $ret -ne 0 ]] && return $ret
GIT_URL=https://github.com/nghttp2/nghttp2.git
echo "Install nghttp2 from $GIT_URL"
pushd $OPENAIRCN_DIR/build/ext
echo "Downloading nghttp2"
if [[ $OPTION =~ [yY](es)* ]]
then
$SUDO rm -rf nghttp2
fi
git clone $GIT_URL
cd nghttp2
git submodule update --init
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
autoreconf -i
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
automake
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
autoconf
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
./configure --enable-asio-lib
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
make
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
$SUDO make install
ret=$?;[[ $ret -ne 0 ]] && popd && return $ret
popd
fi
return 0
}
#-------------------------------------------------------------------------------
#arg1 is force (0 or 1) (no interactive script)
......@@ -333,6 +399,11 @@ check_install_smf_deps() {
install_nlohmann_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
install_nghttp2_from_git $1 $2
ret=$?;[[ $ret -ne 0 ]] && return $ret
$SUDO /sbin/ldconfig -v
ret=$?;[[ $ret -ne 0 ]] && return $ret
return 0
}
#-------------------------------------------------------------------------------
......
......@@ -22,6 +22,7 @@ SMF_CONF[@SMF_INTERFACE_NAME_FOR_SBI@]='eno1:smf'
SMF_CONF[@SMF_INTERFACE_IPV4_ADDRESS_FOR_SBI@]='172.16.1.101'
SMF_CONF[@SMF_INTERFACE_PORT_FOR_SBI@]='80'
SMF_CONF[@SMF_INTERFACE_HTTP2_PORT_FOR_SBI@]='9090'
SMF_CONF[@UDM_IPV4_ADDRESS@]='172.16.1.103'
SMF_CONF[@UDM_PORT@]='80'
......
......@@ -88,6 +88,9 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && DE
WORKDIR /openair-smf/bin
COPY --from=oai-smf-builder /openair-smf/build/smf/build/smf oai_smf
COPY --from=oai-smf-builder /usr/local/lib/libpistache.so /usr/local/lib/
COPY --from=oai-smf-builder /usr/local/lib/libnghttp2_asio.so.1 /usr/local/lib/
COPY --from=oai-smf-builder /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 /usr/lib/x86_64-linux-gnu/
COPY --from=oai-smf-builder /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.65.1 /usr/lib/x86_64-linux-gnu/
COPY --from=oai-smf-builder /openair-smf/build/smf/build/libNAS.so /usr/local/lib/
COPY --from=oai-smf-builder /openair-smf/build/smf/build/libSMF_API.so /usr/local/lib/
RUN ldconfig
......
......@@ -29,6 +29,7 @@ class smfConfigGen():
self.kind = ''
self.sbi_name = ''
self.sbi_port = '80'
self.sbi_http2_port = '9090'
self.n4_name = ''
self.amf_ip_addr = ''
self.amf_port = '80'
......@@ -69,6 +70,7 @@ class smfConfigGen():
smfFile.write('SMF_CONF[@PID_DIRECTORY@]=\'/var/run\'\n')
smfFile.write('SMF_CONF[@SMF_INTERFACE_NAME_FOR_SBI@]=\'' + self.sbi_name + '\'\n')
smfFile.write('SMF_CONF[@SMF_INTERFACE_PORT_FOR_SBI@]=' + self.sbi_port + '\n')
smfFile.write('SMF_CONF[@SMF_INTERFACE_HTTP2_PORT_FOR_SBI@]=' + self.sbi_http2_port + '\n')
smfFile.write('SMF_CONF[@SMF_INTERFACE_NAME_FOR_N4@]=\'' + self.n4_name + '\'\n')
smfFile.write('SMF_CONF[@DEFAULT_DNS_IPV4_ADDRESS@]=$MY_PRIMARY_DNS\n')
smfFile.write('SMF_CONF[@DEFAULT_DNS_SEC_IPV4_ADDRESS@]=$MY_SECONDARY_DNS\n')
......
......@@ -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)
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
This diff is collapsed.
/*
* 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 */
This diff is collapsed.
......@@ -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
......
This diff is collapsed.
......@@ -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+");
......
This diff is collapsed.
......@@ -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;
......
This diff is collapsed.
......@@ -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;
};
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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:
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment