Commit 74893fdc authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'smf_service_subscribe_notify' into 'develop'

Smf service subscribe notify

See merge request oai/cn5g/oai-cn5g-smf!34
parents 2953cfcc 63c7aca6
......@@ -55,7 +55,7 @@ AlwaysBreakAfterReturnType: None
IndentWrappedFunctionNames: false
# template style
AlwaysBreakTemplateDeclarations: Yes
#AlwaysBreakTemplateDeclarations: Yes
# preprocessor style
IndentPPDirectives: None
......@@ -79,9 +79,9 @@ UseTab: Never
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: true
#SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
#SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
......@@ -92,7 +92,7 @@ SpacesInSquareBrackets: false
# class style
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
#BreakInheritanceList: BeforeColon
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
......@@ -115,3 +115,4 @@ SortUsingDeclarations: true
# PenaltyBreakTemplateDeclaration (unsigned)
# PenaltyExcessCharacter (unsigned)
# PenaltyReturnTypeOnItsOwnLine (unsigned)
......@@ -87,25 +87,61 @@ void IndividualSMContextApi::setupRoutes() {
void IndividualSMContextApi::release_sm_context_handler(
const Pistache::Rest::Request &request,
Pistache::Http::ResponseWriter response) {
// Getting the path params
auto smContextRef = request.param(":smContextRef").as<std::string>();
// Getting the body param
Logger::smf_api_server().debug("");
Logger::smf_api_server().info(
"Received a SM context Release request from AMF.");
Logger::smf_api_server().debug("Request body: %s\n", request.body().c_str());
SmContextReleaseMessage smContextReleaseMessage = { };
//simple parser
mime_parser sp = { };
sp.parse(request.body());
SmContextReleaseData smContextReleaseData;
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);
// Getting the body param
SmContextReleaseData smContextReleaseData = { };
try {
nlohmann::json::parse(request.body()).get_to(smContextReleaseData);
this->release_sm_context(smContextRef, smContextReleaseData, response);
if (size > 0) {
nlohmann::json::parse(parts[0].body.c_str()).get_to(smContextReleaseData);
} else {
nlohmann::json::parse(request.body().c_str()).get_to(
smContextReleaseData);
}
smContextReleaseMessage.setJsonData(smContextReleaseData);
for (int i = 1; i < size; i++) {
if (parts[i].content_type.compare("application/vnd.3gpp.ngap") == 0) {
smContextReleaseMessage.setBinaryDataN2SmInformation(parts[i].body);
Logger::smf_api_server().debug("N2 SM information is set");
}
}
// Getting the path params
auto smContextRef = request.param(":smContextRef").as<std::string>();
this->release_sm_context(smContextRef, smContextReleaseMessage, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
Logger::smf_api_server().warn(
"Error in parsing json (error: %s), send a msg with a 400 error code to AMF",
e.what());
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (std::exception &e) {
//send a 500 error
Logger::smf_api_server().warn(
"Error (%s ), send a msg with a 500 error code to AMF", e.what());
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void IndividualSMContextApi::retrieve_sm_context_handler(
......
......@@ -98,7 +98,7 @@ class IndividualSMContextApi {
/// <param name="smContextReleaseData">representation of the data to be sent to the SMF when releasing the SM context (optional)</param>
virtual void release_sm_context(
const std::string &smContextRef,
const SmContextReleaseData &smContextReleaseData,
const SmContextReleaseMessage &smContextReleaseMessage,
Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
......
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "IndividualSubscriptionDocumentApi.h"
#include "Helpers.h"
#include "smf_config.hpp"
extern smf::smf_config smf_cfg;
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::helpers;
using namespace oai::smf_server::model;
IndividualSubscriptionDocumentApi::IndividualSubscriptionDocumentApi(std::shared_ptr<Pistache::Rest::Router> rtr) {
router = rtr;
}
void IndividualSubscriptionDocumentApi::init() {
setupRoutes();
}
void IndividualSubscriptionDocumentApi::setupRoutes() {
using namespace Pistache::Rest;
Routes::Delete(*router, base + smf_cfg.sbi_api_version + "/subscriptions/:subId", Routes::bind(&IndividualSubscriptionDocumentApi::delete_individual_subcription_handler, this));
Routes::Get(*router, base + smf_cfg.sbi_api_version + "/subscriptions/:subId", Routes::bind(&IndividualSubscriptionDocumentApi::get_individual_subcription_handler, this));
Routes::Put(*router, base + smf_cfg.sbi_api_version + "/subscriptions/:subId", Routes::bind(&IndividualSubscriptionDocumentApi::replace_individual_subcription_handler, this));
// Default handler, called when a route is not found
router->addCustomHandler(Routes::bind(&IndividualSubscriptionDocumentApi::individual_subscription_document_api_default_handler, this));
}
void IndividualSubscriptionDocumentApi::delete_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
// Getting the path params
auto subId = request.param(":subId").as<std::string>();
try {
this->delete_individual_subcription(subId, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
//send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void IndividualSubscriptionDocumentApi::get_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
// Getting the path params
auto subId = request.param(":subId").as<std::string>();
try {
this->get_individual_subcription(subId, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
//send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void IndividualSubscriptionDocumentApi::replace_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
// Getting the path params
auto subId = request.param(":subId").as<std::string>();
// Getting the body param
NsmfEventExposure nsmfEventExposure;
try {
nlohmann::json::parse(request.body()).get_to(nsmfEventExposure);
this->replace_individual_subcription(subId, nsmfEventExposure, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
//send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void IndividualSubscriptionDocumentApi::individual_subscription_document_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
response.send(Pistache::Http::Code::Not_Found, "The requested method does not exist");
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* IndividualSubscriptionDocumentApi.h
*
*
*/
#ifndef IndividualSubscriptionDocumentApi_H_
#define IndividualSubscriptionDocumentApi_H_
#include <pistache/http.h>
#include <pistache/router.h>
#include <pistache/http_headers.h>
#include <pistache/optional.h>
#include "NsmfEventExposure.h"
#include "ProblemDetails.h"
#include <string>
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::model;
class IndividualSubscriptionDocumentApi {
public:
IndividualSubscriptionDocumentApi(std::shared_ptr<Pistache::Rest::Router>);
virtual ~IndividualSubscriptionDocumentApi() {}
void init();
const std::string base = "/nsmf_event-exposure/";
private:
void setupRoutes();
void delete_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void get_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void replace_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void individual_subscription_document_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
std::shared_ptr<Pistache::Rest::Router> router;
/// <summary>
/// Delete an individual subscription for event notifications from the SMF
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="subId">Event Subscription ID</param>
virtual void delete_individual_subcription(const std::string &subId, Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
/// Read an individual subscription for event notifications from the SMF
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="subId">Event Subscription ID</param>
virtual void get_individual_subcription(const std::string &subId, Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
/// Replace an individual subscription for event notifications from the SMF
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="subId">Event Subscription ID</param>
/// <param name="nsmfEventExposure"></param>
virtual void replace_individual_subcription(const std::string &subId, const NsmfEventExposure &nsmfEventExposure, Pistache::Http::ResponseWriter &response) = 0;
};
}
}
}
#endif /* IndividualSubscriptionDocumentApi_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "SubscriptionsCollectionApi.h"
#include "Helpers.h"
#include "smf_config.hpp"
extern smf::smf_config smf_cfg;
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::helpers;
using namespace oai::smf_server::model;
SubscriptionsCollectionApi::SubscriptionsCollectionApi(std::shared_ptr<Pistache::Rest::Router> rtr) {
router = rtr;
}
void SubscriptionsCollectionApi::init() {
setupRoutes();
}
void SubscriptionsCollectionApi::setupRoutes() {
using namespace Pistache::Rest;
Routes::Post(*router, base + smf_cfg.sbi_api_version + "/subscriptions", Routes::bind(&SubscriptionsCollectionApi::create_individual_subcription_handler, this));
// Default handler, called when a route is not found
router->addCustomHandler(Routes::bind(&SubscriptionsCollectionApi::subscriptions_collection_api_default_handler, this));
}
void SubscriptionsCollectionApi::create_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) {
// Getting the body param
NsmfEventExposure nsmfEventExposure;
try {
nlohmann::json::parse(request.body()).get_to(nsmfEventExposure);
this->create_individual_subcription(nsmfEventExposure, response);
} catch (nlohmann::detail::exception &e) {
//send a 400 error
response.send(Pistache::Http::Code::Bad_Request, e.what());
return;
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
//send a 500 error
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
return;
}
}
void SubscriptionsCollectionApi::subscriptions_collection_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
response.send(Pistache::Http::Code::Not_Found, "The requested method does not exist");
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* SubscriptionsCollectionApi.h
*
*
*/
#ifndef SubscriptionsCollectionApi_H_
#define SubscriptionsCollectionApi_H_
#include <pistache/http.h>
#include <pistache/router.h>
#include <pistache/http_headers.h>
#include <pistache/optional.h>
#include "NsmfEventExposure.h"
#include "ProblemDetails.h"
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::model;
class SubscriptionsCollectionApi {
public:
SubscriptionsCollectionApi(std::shared_ptr<Pistache::Rest::Router>);
virtual ~SubscriptionsCollectionApi() {}
void init();
const std::string base = "/nsmf_event-exposure/";
private:
void setupRoutes();
void create_individual_subcription_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void subscriptions_collection_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
std::shared_ptr<Pistache::Rest::Router> router;
/// <summary>
/// Create an individual subscription for event notifications from the SMF
/// </summary>
/// <remarks>
///
/// </remarks>
/// <param name="nsmfEventExposure"></param>
virtual void create_individual_subcription(const NsmfEventExposure &nsmfEventExposure, Pistache::Http::ResponseWriter &response) = 0;
};
}
}
}
#endif /* SubscriptionsCollectionApi_H_ */
......@@ -52,13 +52,41 @@ IndividualSMContextApiImpl::IndividualSMContextApiImpl(
void IndividualSMContextApiImpl::release_sm_context(
const std::string &smContextRef,
const SmContextReleaseData &smContextReleaseData,
const SmContextReleaseMessage &smContextReleaseMessage,
Pistache::Http::ResponseWriter &response) {
//TODO: to be updated as update_sm_context_handler
Logger::smf_api_server().info("release_sm_context...");
//Get the SmContextReleaseData from this message and process in smf_app
Logger::smf_api_server().info(
"Received a PDUSession_ReleaseSMContext Request from AMF.");
smf::pdu_session_release_sm_context_request sm_context_req_msg = { };
SmContextReleaseData smContextReleaseData = smContextReleaseMessage
.getJsonData();
if (smContextReleaseData.n2SmInfoIsSet()) {
//N2 SM (for Session establishment)
std::string n2_sm_information = smContextReleaseMessage
.getBinaryDataN2SmInformation();
Logger::smf_api_server().debug("N2 SM Information %s",
n2_sm_information.c_str());
std::string n2_sm_info_type = smContextReleaseData.getN2SmInfoType();
sm_context_req_msg.set_n2_sm_information(n2_sm_information);
sm_context_req_msg.set_n2_sm_info_type(n2_sm_info_type);
}
boost::shared_ptr<boost::promise<smf::pdu_session_release_sm_context_response> > p =
//Step 2. TODO: initialize necessary values for sm context req from smContextReleaseData
// cause:
// ngApCause:
// 5gMmCauseValue:
// ueLocation:
//ueTimeZone:
//addUeLocation:
//vsmfReleaseOnly:
//ismfReleaseOnly:
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;
......@@ -69,16 +97,11 @@ void IndividualSMContextApiImpl::release_sm_context(
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.");
//Step 3. Handle the itti_n11_release_sm_context_request message in smf_app
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,
smContextRef);
itti_msg->scid = smContextRef;
std::make_shared < itti_n11_release_sm_context_request
> (TASK_SMF_N11, TASK_SMF_APP, promise_id, smContextRef);
itti_msg->req = sm_context_req_msg;
itti_msg->http_version = 1;
m_smf_app->handle_pdu_session_release_sm_context_request(itti_msg);
......@@ -86,7 +109,9 @@ void IndividualSMContextApiImpl::release_sm_context(
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);
//TODO: process the response
response.send(Pistache::Http::Code(sm_context_response.get_http_code()));
}
void IndividualSMContextApiImpl::retrieve_sm_context(
......@@ -121,7 +146,8 @@ void IndividualSMContextApiImpl::update_sm_context(
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()) {
}
if (smContextUpdateData.n1SmMsgIsSet()) {
//N1 SM (for session modification)
std::string n1_sm_message =
smContextUpdateMessage.getBinaryDataN1SmMessage();
......@@ -191,7 +217,9 @@ void IndividualSMContextApiImpl::update_sm_context(
nlohmann::json json_data = { };
mime_parser parser = { };
std::string body = { };
std::string json_format;
sm_context_response.get_json_format(json_format);
sm_context_response.get_json_data(json_data);
Logger::smf_api_server().debug("Json data %s", json_data.dump().c_str());
......@@ -200,7 +228,8 @@ void IndividualSMContextApiImpl::update_sm_context(
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());
sm_context_response.get_n2_sm_information(),
json_format);
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
......@@ -208,7 +237,8 @@ void IndividualSMContextApiImpl::update_sm_context(
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);
multipart_related_content_part_e::NAS,
json_format);
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
......@@ -216,13 +246,14 @@ void IndividualSMContextApiImpl::update_sm_context(
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);
multipart_related_content_part_e::NGAP,
json_format);
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType(
"multipart/related; boundary=" + std::string(CURL_MIME_BOUNDARY)));
} else if (json_data.size() > 0 ){
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
Pistache::Http::Mime::MediaType(json_format));
body = json_data.dump().c_str();
} else {
response.send(Pistache::Http::Code(sm_context_response.get_http_code()));
......
......@@ -76,7 +76,7 @@ class IndividualSMContextApiImpl :
void release_sm_context(
const std::string &smContextRef,
const SmContextReleaseData &smContextReleaseData,
const SmContextReleaseMessage &smContextReleaseMessage,
Pistache::Http::ResponseWriter &response);
void retrieve_sm_context(const std::string &smContextRef,
const SmContextRetrieveData &smContextRetrieveData,
......
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "IndividualSubscriptionDocumentApiImpl.h"
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::model;
IndividualSubscriptionDocumentApiImpl::IndividualSubscriptionDocumentApiImpl(
std::shared_ptr<Pistache::Rest::Router> rtr, smf::smf_app *smf_app_inst,
std::string address)
:
IndividualSubscriptionDocumentApi(rtr),
m_smf_app(smf_app_inst),
m_address(address) {
}
void IndividualSubscriptionDocumentApiImpl::delete_individual_subcription(const std::string &subId, Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("IndividualSubscriptionDocumentApiImpl::delete_individual_subcription...");
response.send(Pistache::Http::Code::Not_Implemented,
"delete_individual_subcription API has not been implemented yet!\n");
}
void IndividualSubscriptionDocumentApiImpl::get_individual_subcription(const std::string &subId, Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("IndividualSubscriptionDocumentApiImpl::get_individual_subcription...");
response.send(Pistache::Http::Code::Not_Implemented,
"get_individual_subcription API has not been implemented yet!\n");
}
void IndividualSubscriptionDocumentApiImpl::replace_individual_subcription(const std::string &subId, const NsmfEventExposure &nsmfEventExposure, Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("IndividualSubscriptionDocumentApiImpl::replace_individual_subcription...");
response.send(Pistache::Http::Code::Not_Implemented,
"replace_individual_subcription API has not been implemented yet!\n");
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* IndividualSubscriptionDocumentApiImpl.h
*
*
*/
#ifndef INDIVIDUAL_SUBSCRIPTION_DOCUMENT_API_IMPL_H_
#define INDIVIDUAL_SUBSCRIPTION_DOCUMENT_API_IMPL_H_
#include <pistache/endpoint.h>
#include <pistache/http.h>
#include <pistache/router.h>
#include <memory>
#include <IndividualSubscriptionDocumentApi.h>
#include <pistache/optional.h>
#include "NsmfEventExposure.h"
#include "ProblemDetails.h"
#include "smf_app.hpp"
#include <string>
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::model;
class IndividualSubscriptionDocumentApiImpl : public oai::smf_server::api::IndividualSubscriptionDocumentApi {
public:
IndividualSubscriptionDocumentApiImpl(std::shared_ptr<Pistache::Rest::Router>,
smf::smf_app *smf_app_inst, std::string address);
~IndividualSubscriptionDocumentApiImpl() {}
void delete_individual_subcription(const std::string &subId, Pistache::Http::ResponseWriter &response);
void get_individual_subcription(const std::string &subId, Pistache::Http::ResponseWriter &response);
void replace_individual_subcription(const std::string &subId, const NsmfEventExposure &nsmfEventExposure, Pistache::Http::ResponseWriter &response);
private:
smf::smf_app *m_smf_app;
std::string m_address;
};
}
}
}
#endif
......@@ -132,6 +132,7 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
//anType
//UETimeZone
//SMContextStatusUri
sm_context_req_msg.set_sm_context_status_uri(smContextCreateData.getSmContextStatusUri());
//PCFId
// DNN Selection Mode
......@@ -180,9 +181,11 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
response.headers().add < Pistache::Http::Header::Location
> (sm_context_response.get_smf_context_uri()); //Location header
sm_context_response.get_json_data(json_data);
std::string json_format;
sm_context_response.get_json_format(json_format);
if (!json_data.empty()) {
response.headers().add < Pistache::Http::Header::ContentType
> (Pistache::Http::Mime::MediaType("application/json"));
> (Pistache::Http::Mime::MediaType(json_format));
response.send(Pistache::Http::Code(sm_context_response.get_http_code()),
json_data.dump().c_str());
} else {
......
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "SubscriptionsCollectionApiImpl.h"
#include "logger.hpp"
#include "smf_msg.hpp"
#include "3gpp_29.508.h"
#include "itti_msg_sbi.hpp"
#include "smf_config.hpp"
extern smf::smf_config smf_cfg;
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::model;
SubscriptionsCollectionApiImpl::SubscriptionsCollectionApiImpl(
std::shared_ptr<Pistache::Rest::Router> rtr, smf::smf_app *smf_app_inst,
std::string address)
:
SubscriptionsCollectionApi(rtr),
m_smf_app(smf_app_inst),
m_address(address) {
}
void SubscriptionsCollectionApiImpl::create_individual_subcription(
const NsmfEventExposure &nsmfEventExposure,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info(
"SubscriptionsCollectionApiImpl::create_individual_subcription...");
//Step1. Create a message and store the necessary information
Logger::smf_api_server().debug(
"Create a Event Exposure message and store the necessary information");
smf::event_exposure_msg event_exposure = { };
//Supi
if (nsmfEventExposure.supiIsSet()) {
supi_t supi = { .length = 0 };
std::size_t pos = nsmfEventExposure.getSupi().find("-");
std::string supi_str = nsmfEventExposure.getSupi().substr(pos + 1);
std::string supi_prefix = nsmfEventExposure.getSupi().substr(0, pos);
smf_string_to_supi(&supi, supi_str.c_str());
event_exposure.set_supi(supi);
event_exposure.set_supi_prefix(supi_prefix);
Logger::smf_api_server().debug("SUPI %s, SUPI Prefix %s, IMSI %s",
nsmfEventExposure.getSupi().c_str(),
supi_prefix.c_str(), supi_str.c_str());
}
//PDU session ID
if (nsmfEventExposure.pduSeIdIsSet()) {
Logger::smf_api_server().debug("PDU Session ID %d",
nsmfEventExposure.getPduSeId());
event_exposure.set_pdu_session_id(nsmfEventExposure.getPduSeId());
}
event_exposure.set_notif_id(nsmfEventExposure.getNotifId()); //NotifId
event_exposure.set_notif_uri(nsmfEventExposure.getNotifUri()); //NotifUri
//EventSubscription: TODO
event_subscription_t event_subscription = { };
event_subscription.smf_event = smf_event_t::SMF_EVENT_PDU_SES_REL;
std::vector<event_subscription_t> event_subscriptions = { };
event_subscriptions.push_back(event_subscription);
event_exposure.set_event_subs(event_subscriptions);
//std::vector<EventSubscription> eventSubscriptions;
//for (auto it: nsmfEventExposure.getEventSubs()){
//event_subscription.smf_event = it.getEvent();
//getDnaiChgType
//event_subscriptions.push_back(event_subscription);
//}
//Step 2. Handle the message in smf_app
std::shared_ptr<itti_sbi_event_exposure_request> itti_msg = std::make_shared
< itti_sbi_event_exposure_request > (TASK_SMF_N11, TASK_SMF_APP);
itti_msg->event_exposure = event_exposure;
itti_msg->http_version = 1;
evsub_id_t sub_id = m_smf_app->handle_event_exposure_subscription(itti_msg);
//send response
nlohmann::json json_data = { };
to_json(json_data, nsmfEventExposure);
if (sub_id != -1) {
json_data["subId"] = std::to_string(sub_id);
response.headers().add < Pistache::Http::Header::Location
> (m_address + base + smf_cfg.sbi_api_version + "/nsmf_event-exposure/"
+ std::to_string(sub_id)); //Location header
}
response.headers().add < Pistache::Http::Header::ContentType
> (Pistache::Http::Mime::MediaType("application/json"));
response.send(Pistache::Http::Code(201), json_data.dump().c_str());
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* SubscriptionsCollectionApiImpl.h
*
*
*/
#ifndef SUBSCRIPTIONS_COLLECTION_API_IMPL_H_
#define SUBSCRIPTIONS_COLLECTION_API_IMPL_H_
#include <pistache/endpoint.h>
#include <pistache/http.h>
#include <pistache/router.h>
#include <memory>
#include <SubscriptionsCollectionApi.h>
#include <pistache/optional.h>
#include "NsmfEventExposure.h"
#include "ProblemDetails.h"
#include "smf_app.hpp"
namespace oai {
namespace smf_server {
namespace api {
using namespace oai::smf_server::model;
class SubscriptionsCollectionApiImpl : public oai::smf_server::api::SubscriptionsCollectionApi {
public:
SubscriptionsCollectionApiImpl(std::shared_ptr<Pistache::Rest::Router>,
smf::smf_app *smf_app_inst, std::string address);
~SubscriptionsCollectionApiImpl() {}
void create_individual_subcription(const NsmfEventExposure &nsmfEventExposure, Pistache::Http::ResponseWriter &response);
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();
}
};
}
}
}
#endif
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "DddStatus.h"
namespace oai {
namespace smf_server {
namespace model {
DddStatus::DddStatus()
{
}
DddStatus::~DddStatus()
{
}
void DddStatus::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const DddStatus& o)
{
j = nlohmann::json();
}
void from_json(const nlohmann::json& j, DddStatus& o)
{
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* DddStatus.h
*
* Possible values are - BUFFERED: The downlink data are buffered. - TRANSMITTED: The downlink data are transmitted - DISCARDED: The downlink data are discarded.
*/
#ifndef DddStatus_H_
#define DddStatus_H_
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
/// Possible values are - BUFFERED: The downlink data are buffered. - TRANSMITTED: The downlink data are transmitted - DISCARDED: The downlink data are discarded.
/// </summary>
class DddStatus
{
public:
DddStatus();
virtual ~DddStatus();
void validate();
/////////////////////////////////////////////
/// DddStatus members
friend void to_json(nlohmann::json& j, const DddStatus& o);
friend void from_json(const nlohmann::json& j, DddStatus& o);
protected:
};
}
}
}
#endif /* DddStatus_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "DddTrafficDescriptor.h"
namespace oai {
namespace smf_server {
namespace model {
DddTrafficDescriptor::DddTrafficDescriptor()
{
m_Ipv4Addr = "";
m_Ipv4AddrIsSet = false;
m_Ipv6AddrIsSet = false;
m_Port = 0;
m_PortIsSet = false;
}
DddTrafficDescriptor::~DddTrafficDescriptor()
{
}
void DddTrafficDescriptor::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const DddTrafficDescriptor& o)
{
j = nlohmann::json();
if(o.ipv4AddrIsSet())
j["ipv4Addr"] = o.m_Ipv4Addr;
if(o.ipv6AddrIsSet())
j["ipv6Addr"] = o.m_Ipv6Addr;
if(o.portIsSet())
j["port"] = o.m_Port;
}
void from_json(const nlohmann::json& j, DddTrafficDescriptor& o)
{
if(j.find("ipv4Addr") != j.end())
{
j.at("ipv4Addr").get_to(o.m_Ipv4Addr);
o.m_Ipv4AddrIsSet = true;
}
if(j.find("ipv6Addr") != j.end())
{
j.at("ipv6Addr").get_to(o.m_Ipv6Addr);
o.m_Ipv6AddrIsSet = true;
}
if(j.find("port") != j.end())
{
j.at("port").get_to(o.m_Port);
o.m_PortIsSet = true;
}
}
std::string DddTrafficDescriptor::getIpv4Addr() const
{
return m_Ipv4Addr;
}
void DddTrafficDescriptor::setIpv4Addr(std::string const& value)
{
m_Ipv4Addr = value;
m_Ipv4AddrIsSet = true;
}
bool DddTrafficDescriptor::ipv4AddrIsSet() const
{
return m_Ipv4AddrIsSet;
}
void DddTrafficDescriptor::unsetIpv4Addr()
{
m_Ipv4AddrIsSet = false;
}
Ipv6Addr DddTrafficDescriptor::getIpv6Addr() const
{
return m_Ipv6Addr;
}
void DddTrafficDescriptor::setIpv6Addr(Ipv6Addr const& value)
{
m_Ipv6Addr = value;
m_Ipv6AddrIsSet = true;
}
bool DddTrafficDescriptor::ipv6AddrIsSet() const
{
return m_Ipv6AddrIsSet;
}
void DddTrafficDescriptor::unsetIpv6Addr()
{
m_Ipv6AddrIsSet = false;
}
int32_t DddTrafficDescriptor::getPort() const
{
return m_Port;
}
void DddTrafficDescriptor::setPort(int32_t const value)
{
m_Port = value;
m_PortIsSet = true;
}
bool DddTrafficDescriptor::portIsSet() const
{
return m_PortIsSet;
}
void DddTrafficDescriptor::unsetPort()
{
m_PortIsSet = false;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* DddTrafficDescriptor.h
*
*
*/
#ifndef DddTrafficDescriptor_H_
#define DddTrafficDescriptor_H_
#include <string>
#include "Ipv6Addr.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class DddTrafficDescriptor
{
public:
DddTrafficDescriptor();
virtual ~DddTrafficDescriptor();
void validate();
/////////////////////////////////////////////
/// DddTrafficDescriptor members
/// <summary>
///
/// </summary>
std::string getIpv4Addr() const;
void setIpv4Addr(std::string const& value);
bool ipv4AddrIsSet() const;
void unsetIpv4Addr();
/// <summary>
///
/// </summary>
Ipv6Addr getIpv6Addr() const;
void setIpv6Addr(Ipv6Addr const& value);
bool ipv6AddrIsSet() const;
void unsetIpv6Addr();
/// <summary>
///
/// </summary>
int32_t getPort() const;
void setPort(int32_t const value);
bool portIsSet() const;
void unsetPort();
friend void to_json(nlohmann::json& j, const DddTrafficDescriptor& o);
friend void from_json(const nlohmann::json& j, DddTrafficDescriptor& o);
protected:
std::string m_Ipv4Addr;
bool m_Ipv4AddrIsSet;
Ipv6Addr m_Ipv6Addr;
bool m_Ipv6AddrIsSet;
int32_t m_Port;
bool m_PortIsSet;
};
}
}
}
#endif /* DddTrafficDescriptor_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "DnaiChangeType.h"
namespace oai {
namespace smf_server {
namespace model {
DnaiChangeType::DnaiChangeType()
{
}
DnaiChangeType::~DnaiChangeType()
{
}
void DnaiChangeType::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const DnaiChangeType& o)
{
j = nlohmann::json();
}
void from_json(const nlohmann::json& j, DnaiChangeType& o)
{
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* DnaiChangeType.h
*
* Possible values are - EARLY: Early notification of UP path reconfiguration. - EARLY_LATE: Early and late notification of UP path reconfiguration. This value shall only be present in the subscription to the DNAI change event. - LATE: Late notification of UP path reconfiguration.
*/
#ifndef DnaiChangeType_H_
#define DnaiChangeType_H_
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
/// Possible values are - EARLY: Early notification of UP path reconfiguration. - EARLY_LATE: Early and late notification of UP path reconfiguration. This value shall only be present in the subscription to the DNAI change event. - LATE: Late notification of UP path reconfiguration.
/// </summary>
class DnaiChangeType
{
public:
DnaiChangeType();
virtual ~DnaiChangeType();
void validate();
/////////////////////////////////////////////
/// DnaiChangeType members
friend void to_json(nlohmann::json& j, const DnaiChangeType& o);
friend void from_json(const nlohmann::json& j, DnaiChangeType& o);
protected:
};
}
}
}
#endif /* DnaiChangeType_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "EventNotification.h"
namespace oai {
namespace smf_server {
namespace model {
EventNotification::EventNotification()
{
m_TimeStamp = "";
m_Supi = "";
m_SupiIsSet = false;
m_Gpsi = "";
m_GpsiIsSet = false;
m_SourceDnai = "";
m_SourceDnaiIsSet = false;
m_TargetDnai = "";
m_TargetDnaiIsSet = false;
m_DnaiChgTypeIsSet = false;
m_SourceUeIpv4Addr = "";
m_SourceUeIpv4AddrIsSet = false;
m_SourceUeIpv6PrefixIsSet = false;
m_TargetUeIpv4Addr = "";
m_TargetUeIpv4AddrIsSet = false;
m_TargetUeIpv6PrefixIsSet = false;
m_SourceTraRoutingIsSet = false;
m_TargetTraRoutingIsSet = false;
m_UeMac = "";
m_UeMacIsSet = false;
m_AdIpv4Addr = "";
m_AdIpv4AddrIsSet = false;
m_AdIpv6PrefixIsSet = false;
m_ReIpv4Addr = "";
m_ReIpv4AddrIsSet = false;
m_ReIpv6PrefixIsSet = false;
m_PlmnIdIsSet = false;
m_AccTypeIsSet = false;
m_PduSeId = 0;
m_PduSeIdIsSet = false;
m_DddStatusIsSet = false;
m_MaxWaitTime = "";
m_MaxWaitTimeIsSet = false;
}
EventNotification::~EventNotification()
{
}
void EventNotification::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const EventNotification& o)
{
j = nlohmann::json();
j["event"] = o.m_Event;
j["timeStamp"] = o.m_TimeStamp;
if(o.supiIsSet())
j["supi"] = o.m_Supi;
if(o.gpsiIsSet())
j["gpsi"] = o.m_Gpsi;
if(o.sourceDnaiIsSet())
j["sourceDnai"] = o.m_SourceDnai;
if(o.targetDnaiIsSet())
j["targetDnai"] = o.m_TargetDnai;
if(o.dnaiChgTypeIsSet())
j["dnaiChgType"] = o.m_DnaiChgType;
if(o.sourceUeIpv4AddrIsSet())
j["sourceUeIpv4Addr"] = o.m_SourceUeIpv4Addr;
if(o.sourceUeIpv6PrefixIsSet())
j["sourceUeIpv6Prefix"] = o.m_SourceUeIpv6Prefix;
if(o.targetUeIpv4AddrIsSet())
j["targetUeIpv4Addr"] = o.m_TargetUeIpv4Addr;
if(o.targetUeIpv6PrefixIsSet())
j["targetUeIpv6Prefix"] = o.m_TargetUeIpv6Prefix;
if(o.sourceTraRoutingIsSet())
j["sourceTraRouting"] = o.m_SourceTraRouting;
if(o.targetTraRoutingIsSet())
j["targetTraRouting"] = o.m_TargetTraRouting;
if(o.ueMacIsSet())
j["ueMac"] = o.m_UeMac;
if(o.adIpv4AddrIsSet())
j["adIpv4Addr"] = o.m_AdIpv4Addr;
if(o.adIpv6PrefixIsSet())
j["adIpv6Prefix"] = o.m_AdIpv6Prefix;
if(o.reIpv4AddrIsSet())
j["reIpv4Addr"] = o.m_ReIpv4Addr;
if(o.reIpv6PrefixIsSet())
j["reIpv6Prefix"] = o.m_ReIpv6Prefix;
if(o.plmnIdIsSet())
j["plmnId"] = o.m_PlmnId;
if(o.accTypeIsSet())
j["accType"] = o.m_AccType;
if(o.pduSeIdIsSet())
j["pduSeId"] = o.m_PduSeId;
if(o.dddStatusIsSet())
j["dddStatus"] = o.m_DddStatus;
if(o.maxWaitTimeIsSet())
j["maxWaitTime"] = o.m_MaxWaitTime;
}
void from_json(const nlohmann::json& j, EventNotification& o)
{
j.at("event").get_to(o.m_Event);
j.at("timeStamp").get_to(o.m_TimeStamp);
if(j.find("supi") != j.end())
{
j.at("supi").get_to(o.m_Supi);
o.m_SupiIsSet = true;
}
if(j.find("gpsi") != j.end())
{
j.at("gpsi").get_to(o.m_Gpsi);
o.m_GpsiIsSet = true;
}
if(j.find("sourceDnai") != j.end())
{
j.at("sourceDnai").get_to(o.m_SourceDnai);
o.m_SourceDnaiIsSet = true;
}
if(j.find("targetDnai") != j.end())
{
j.at("targetDnai").get_to(o.m_TargetDnai);
o.m_TargetDnaiIsSet = true;
}
if(j.find("dnaiChgType") != j.end())
{
j.at("dnaiChgType").get_to(o.m_DnaiChgType);
o.m_DnaiChgTypeIsSet = true;
}
if(j.find("sourceUeIpv4Addr") != j.end())
{
j.at("sourceUeIpv4Addr").get_to(o.m_SourceUeIpv4Addr);
o.m_SourceUeIpv4AddrIsSet = true;
}
if(j.find("sourceUeIpv6Prefix") != j.end())
{
j.at("sourceUeIpv6Prefix").get_to(o.m_SourceUeIpv6Prefix);
o.m_SourceUeIpv6PrefixIsSet = true;
}
if(j.find("targetUeIpv4Addr") != j.end())
{
j.at("targetUeIpv4Addr").get_to(o.m_TargetUeIpv4Addr);
o.m_TargetUeIpv4AddrIsSet = true;
}
if(j.find("targetUeIpv6Prefix") != j.end())
{
j.at("targetUeIpv6Prefix").get_to(o.m_TargetUeIpv6Prefix);
o.m_TargetUeIpv6PrefixIsSet = true;
}
if(j.find("sourceTraRouting") != j.end())
{
j.at("sourceTraRouting").get_to(o.m_SourceTraRouting);
o.m_SourceTraRoutingIsSet = true;
}
if(j.find("targetTraRouting") != j.end())
{
j.at("targetTraRouting").get_to(o.m_TargetTraRouting);
o.m_TargetTraRoutingIsSet = true;
}
if(j.find("ueMac") != j.end())
{
j.at("ueMac").get_to(o.m_UeMac);
o.m_UeMacIsSet = true;
}
if(j.find("adIpv4Addr") != j.end())
{
j.at("adIpv4Addr").get_to(o.m_AdIpv4Addr);
o.m_AdIpv4AddrIsSet = true;
}
if(j.find("adIpv6Prefix") != j.end())
{
j.at("adIpv6Prefix").get_to(o.m_AdIpv6Prefix);
o.m_AdIpv6PrefixIsSet = true;
}
if(j.find("reIpv4Addr") != j.end())
{
j.at("reIpv4Addr").get_to(o.m_ReIpv4Addr);
o.m_ReIpv4AddrIsSet = true;
}
if(j.find("reIpv6Prefix") != j.end())
{
j.at("reIpv6Prefix").get_to(o.m_ReIpv6Prefix);
o.m_ReIpv6PrefixIsSet = true;
}
if(j.find("plmnId") != j.end())
{
j.at("plmnId").get_to(o.m_PlmnId);
o.m_PlmnIdIsSet = true;
}
if(j.find("accType") != j.end())
{
j.at("accType").get_to(o.m_AccType);
o.m_AccTypeIsSet = true;
}
if(j.find("pduSeId") != j.end())
{
j.at("pduSeId").get_to(o.m_PduSeId);
o.m_PduSeIdIsSet = true;
}
if(j.find("dddStatus") != j.end())
{
j.at("dddStatus").get_to(o.m_DddStatus);
o.m_DddStatusIsSet = true;
}
if(j.find("maxWaitTime") != j.end())
{
j.at("maxWaitTime").get_to(o.m_MaxWaitTime);
o.m_MaxWaitTimeIsSet = true;
}
}
SmfEvent EventNotification::getEvent() const
{
return m_Event;
}
void EventNotification::setEvent(SmfEvent const& value)
{
m_Event = value;
}
std::string EventNotification::getTimeStamp() const
{
return m_TimeStamp;
}
void EventNotification::setTimeStamp(std::string const& value)
{
m_TimeStamp = value;
}
std::string EventNotification::getSupi() const
{
return m_Supi;
}
void EventNotification::setSupi(std::string const& value)
{
m_Supi = value;
m_SupiIsSet = true;
}
bool EventNotification::supiIsSet() const
{
return m_SupiIsSet;
}
void EventNotification::unsetSupi()
{
m_SupiIsSet = false;
}
std::string EventNotification::getGpsi() const
{
return m_Gpsi;
}
void EventNotification::setGpsi(std::string const& value)
{
m_Gpsi = value;
m_GpsiIsSet = true;
}
bool EventNotification::gpsiIsSet() const
{
return m_GpsiIsSet;
}
void EventNotification::unsetGpsi()
{
m_GpsiIsSet = false;
}
std::string EventNotification::getSourceDnai() const
{
return m_SourceDnai;
}
void EventNotification::setSourceDnai(std::string const& value)
{
m_SourceDnai = value;
m_SourceDnaiIsSet = true;
}
bool EventNotification::sourceDnaiIsSet() const
{
return m_SourceDnaiIsSet;
}
void EventNotification::unsetSourceDnai()
{
m_SourceDnaiIsSet = false;
}
std::string EventNotification::getTargetDnai() const
{
return m_TargetDnai;
}
void EventNotification::setTargetDnai(std::string const& value)
{
m_TargetDnai = value;
m_TargetDnaiIsSet = true;
}
bool EventNotification::targetDnaiIsSet() const
{
return m_TargetDnaiIsSet;
}
void EventNotification::unsetTargetDnai()
{
m_TargetDnaiIsSet = false;
}
DnaiChangeType EventNotification::getDnaiChgType() const
{
return m_DnaiChgType;
}
void EventNotification::setDnaiChgType(DnaiChangeType const& value)
{
m_DnaiChgType = value;
m_DnaiChgTypeIsSet = true;
}
bool EventNotification::dnaiChgTypeIsSet() const
{
return m_DnaiChgTypeIsSet;
}
void EventNotification::unsetDnaiChgType()
{
m_DnaiChgTypeIsSet = false;
}
std::string EventNotification::getSourceUeIpv4Addr() const
{
return m_SourceUeIpv4Addr;
}
void EventNotification::setSourceUeIpv4Addr(std::string const& value)
{
m_SourceUeIpv4Addr = value;
m_SourceUeIpv4AddrIsSet = true;
}
bool EventNotification::sourceUeIpv4AddrIsSet() const
{
return m_SourceUeIpv4AddrIsSet;
}
void EventNotification::unsetSourceUeIpv4Addr()
{
m_SourceUeIpv4AddrIsSet = false;
}
Ipv6Prefix EventNotification::getSourceUeIpv6Prefix() const
{
return m_SourceUeIpv6Prefix;
}
void EventNotification::setSourceUeIpv6Prefix(Ipv6Prefix const& value)
{
m_SourceUeIpv6Prefix = value;
m_SourceUeIpv6PrefixIsSet = true;
}
bool EventNotification::sourceUeIpv6PrefixIsSet() const
{
return m_SourceUeIpv6PrefixIsSet;
}
void EventNotification::unsetSourceUeIpv6Prefix()
{
m_SourceUeIpv6PrefixIsSet = false;
}
std::string EventNotification::getTargetUeIpv4Addr() const
{
return m_TargetUeIpv4Addr;
}
void EventNotification::setTargetUeIpv4Addr(std::string const& value)
{
m_TargetUeIpv4Addr = value;
m_TargetUeIpv4AddrIsSet = true;
}
bool EventNotification::targetUeIpv4AddrIsSet() const
{
return m_TargetUeIpv4AddrIsSet;
}
void EventNotification::unsetTargetUeIpv4Addr()
{
m_TargetUeIpv4AddrIsSet = false;
}
Ipv6Prefix EventNotification::getTargetUeIpv6Prefix() const
{
return m_TargetUeIpv6Prefix;
}
void EventNotification::setTargetUeIpv6Prefix(Ipv6Prefix const& value)
{
m_TargetUeIpv6Prefix = value;
m_TargetUeIpv6PrefixIsSet = true;
}
bool EventNotification::targetUeIpv6PrefixIsSet() const
{
return m_TargetUeIpv6PrefixIsSet;
}
void EventNotification::unsetTargetUeIpv6Prefix()
{
m_TargetUeIpv6PrefixIsSet = false;
}
RouteToLocation EventNotification::getSourceTraRouting() const
{
return m_SourceTraRouting;
}
void EventNotification::setSourceTraRouting(RouteToLocation const& value)
{
m_SourceTraRouting = value;
m_SourceTraRoutingIsSet = true;
}
bool EventNotification::sourceTraRoutingIsSet() const
{
return m_SourceTraRoutingIsSet;
}
void EventNotification::unsetSourceTraRouting()
{
m_SourceTraRoutingIsSet = false;
}
RouteToLocation EventNotification::getTargetTraRouting() const
{
return m_TargetTraRouting;
}
void EventNotification::setTargetTraRouting(RouteToLocation const& value)
{
m_TargetTraRouting = value;
m_TargetTraRoutingIsSet = true;
}
bool EventNotification::targetTraRoutingIsSet() const
{
return m_TargetTraRoutingIsSet;
}
void EventNotification::unsetTargetTraRouting()
{
m_TargetTraRoutingIsSet = false;
}
std::string EventNotification::getUeMac() const
{
return m_UeMac;
}
void EventNotification::setUeMac(std::string const& value)
{
m_UeMac = value;
m_UeMacIsSet = true;
}
bool EventNotification::ueMacIsSet() const
{
return m_UeMacIsSet;
}
void EventNotification::unsetUeMac()
{
m_UeMacIsSet = false;
}
std::string EventNotification::getAdIpv4Addr() const
{
return m_AdIpv4Addr;
}
void EventNotification::setAdIpv4Addr(std::string const& value)
{
m_AdIpv4Addr = value;
m_AdIpv4AddrIsSet = true;
}
bool EventNotification::adIpv4AddrIsSet() const
{
return m_AdIpv4AddrIsSet;
}
void EventNotification::unsetAdIpv4Addr()
{
m_AdIpv4AddrIsSet = false;
}
Ipv6Prefix EventNotification::getAdIpv6Prefix() const
{
return m_AdIpv6Prefix;
}
void EventNotification::setAdIpv6Prefix(Ipv6Prefix const& value)
{
m_AdIpv6Prefix = value;
m_AdIpv6PrefixIsSet = true;
}
bool EventNotification::adIpv6PrefixIsSet() const
{
return m_AdIpv6PrefixIsSet;
}
void EventNotification::unsetAdIpv6Prefix()
{
m_AdIpv6PrefixIsSet = false;
}
std::string EventNotification::getReIpv4Addr() const
{
return m_ReIpv4Addr;
}
void EventNotification::setReIpv4Addr(std::string const& value)
{
m_ReIpv4Addr = value;
m_ReIpv4AddrIsSet = true;
}
bool EventNotification::reIpv4AddrIsSet() const
{
return m_ReIpv4AddrIsSet;
}
void EventNotification::unsetReIpv4Addr()
{
m_ReIpv4AddrIsSet = false;
}
Ipv6Prefix EventNotification::getReIpv6Prefix() const
{
return m_ReIpv6Prefix;
}
void EventNotification::setReIpv6Prefix(Ipv6Prefix const& value)
{
m_ReIpv6Prefix = value;
m_ReIpv6PrefixIsSet = true;
}
bool EventNotification::reIpv6PrefixIsSet() const
{
return m_ReIpv6PrefixIsSet;
}
void EventNotification::unsetReIpv6Prefix()
{
m_ReIpv6PrefixIsSet = false;
}
PlmnId EventNotification::getPlmnId() const
{
return m_PlmnId;
}
void EventNotification::setPlmnId(PlmnId const& value)
{
m_PlmnId = value;
m_PlmnIdIsSet = true;
}
bool EventNotification::plmnIdIsSet() const
{
return m_PlmnIdIsSet;
}
void EventNotification::unsetPlmnId()
{
m_PlmnIdIsSet = false;
}
AccessType EventNotification::getAccType() const
{
return m_AccType;
}
void EventNotification::setAccType(AccessType const& value)
{
m_AccType = value;
m_AccTypeIsSet = true;
}
bool EventNotification::accTypeIsSet() const
{
return m_AccTypeIsSet;
}
void EventNotification::unsetAccType()
{
m_AccTypeIsSet = false;
}
int32_t EventNotification::getPduSeId() const
{
return m_PduSeId;
}
void EventNotification::setPduSeId(int32_t const value)
{
m_PduSeId = value;
m_PduSeIdIsSet = true;
}
bool EventNotification::pduSeIdIsSet() const
{
return m_PduSeIdIsSet;
}
void EventNotification::unsetPduSeId()
{
m_PduSeIdIsSet = false;
}
DddStatus EventNotification::getDddStatus() const
{
return m_DddStatus;
}
void EventNotification::setDddStatus(DddStatus const& value)
{
m_DddStatus = value;
m_DddStatusIsSet = true;
}
bool EventNotification::dddStatusIsSet() const
{
return m_DddStatusIsSet;
}
void EventNotification::unsetDddStatus()
{
m_DddStatusIsSet = false;
}
std::string EventNotification::getMaxWaitTime() const
{
return m_MaxWaitTime;
}
void EventNotification::setMaxWaitTime(std::string const& value)
{
m_MaxWaitTime = value;
m_MaxWaitTimeIsSet = true;
}
bool EventNotification::maxWaitTimeIsSet() const
{
return m_MaxWaitTimeIsSet;
}
void EventNotification::unsetMaxWaitTime()
{
m_MaxWaitTimeIsSet = false;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* EventNotification.h
*
*
*/
#ifndef EventNotification_H_
#define EventNotification_H_
#include "DnaiChangeType.h"
#include "DddStatus.h"
#include <string>
#include "Ipv6Prefix.h"
#include "SmfEvent.h"
#include "PlmnId.h"
#include "RouteToLocation.h"
#include "AccessType.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class EventNotification
{
public:
EventNotification();
virtual ~EventNotification();
void validate();
/////////////////////////////////////////////
/// EventNotification members
/// <summary>
///
/// </summary>
SmfEvent getEvent() const;
void setEvent(SmfEvent const& value);
/// <summary>
///
/// </summary>
std::string getTimeStamp() const;
void setTimeStamp(std::string const& value);
/// <summary>
///
/// </summary>
std::string getSupi() const;
void setSupi(std::string const& value);
bool supiIsSet() const;
void unsetSupi();
/// <summary>
///
/// </summary>
std::string getGpsi() const;
void setGpsi(std::string const& value);
bool gpsiIsSet() const;
void unsetGpsi();
/// <summary>
///
/// </summary>
std::string getSourceDnai() const;
void setSourceDnai(std::string const& value);
bool sourceDnaiIsSet() const;
void unsetSourceDnai();
/// <summary>
///
/// </summary>
std::string getTargetDnai() const;
void setTargetDnai(std::string const& value);
bool targetDnaiIsSet() const;
void unsetTargetDnai();
/// <summary>
///
/// </summary>
DnaiChangeType getDnaiChgType() const;
void setDnaiChgType(DnaiChangeType const& value);
bool dnaiChgTypeIsSet() const;
void unsetDnaiChgType();
/// <summary>
///
/// </summary>
std::string getSourceUeIpv4Addr() const;
void setSourceUeIpv4Addr(std::string const& value);
bool sourceUeIpv4AddrIsSet() const;
void unsetSourceUeIpv4Addr();
/// <summary>
///
/// </summary>
Ipv6Prefix getSourceUeIpv6Prefix() const;
void setSourceUeIpv6Prefix(Ipv6Prefix const& value);
bool sourceUeIpv6PrefixIsSet() const;
void unsetSourceUeIpv6Prefix();
/// <summary>
///
/// </summary>
std::string getTargetUeIpv4Addr() const;
void setTargetUeIpv4Addr(std::string const& value);
bool targetUeIpv4AddrIsSet() const;
void unsetTargetUeIpv4Addr();
/// <summary>
///
/// </summary>
Ipv6Prefix getTargetUeIpv6Prefix() const;
void setTargetUeIpv6Prefix(Ipv6Prefix const& value);
bool targetUeIpv6PrefixIsSet() const;
void unsetTargetUeIpv6Prefix();
/// <summary>
///
/// </summary>
RouteToLocation getSourceTraRouting() const;
void setSourceTraRouting(RouteToLocation const& value);
bool sourceTraRoutingIsSet() const;
void unsetSourceTraRouting();
/// <summary>
///
/// </summary>
RouteToLocation getTargetTraRouting() const;
void setTargetTraRouting(RouteToLocation const& value);
bool targetTraRoutingIsSet() const;
void unsetTargetTraRouting();
/// <summary>
///
/// </summary>
std::string getUeMac() const;
void setUeMac(std::string const& value);
bool ueMacIsSet() const;
void unsetUeMac();
/// <summary>
///
/// </summary>
std::string getAdIpv4Addr() const;
void setAdIpv4Addr(std::string const& value);
bool adIpv4AddrIsSet() const;
void unsetAdIpv4Addr();
/// <summary>
///
/// </summary>
Ipv6Prefix getAdIpv6Prefix() const;
void setAdIpv6Prefix(Ipv6Prefix const& value);
bool adIpv6PrefixIsSet() const;
void unsetAdIpv6Prefix();
/// <summary>
///
/// </summary>
std::string getReIpv4Addr() const;
void setReIpv4Addr(std::string const& value);
bool reIpv4AddrIsSet() const;
void unsetReIpv4Addr();
/// <summary>
///
/// </summary>
Ipv6Prefix getReIpv6Prefix() const;
void setReIpv6Prefix(Ipv6Prefix const& value);
bool reIpv6PrefixIsSet() const;
void unsetReIpv6Prefix();
/// <summary>
///
/// </summary>
PlmnId getPlmnId() const;
void setPlmnId(PlmnId const& value);
bool plmnIdIsSet() const;
void unsetPlmnId();
/// <summary>
///
/// </summary>
AccessType getAccType() const;
void setAccType(AccessType const& value);
bool accTypeIsSet() const;
void unsetAccType();
/// <summary>
///
/// </summary>
int32_t getPduSeId() const;
void setPduSeId(int32_t const value);
bool pduSeIdIsSet() const;
void unsetPduSeId();
/// <summary>
///
/// </summary>
DddStatus getDddStatus() const;
void setDddStatus(DddStatus const& value);
bool dddStatusIsSet() const;
void unsetDddStatus();
/// <summary>
///
/// </summary>
std::string getMaxWaitTime() const;
void setMaxWaitTime(std::string const& value);
bool maxWaitTimeIsSet() const;
void unsetMaxWaitTime();
friend void to_json(nlohmann::json& j, const EventNotification& o);
friend void from_json(const nlohmann::json& j, EventNotification& o);
protected:
SmfEvent m_Event;
std::string m_TimeStamp;
std::string m_Supi;
bool m_SupiIsSet;
std::string m_Gpsi;
bool m_GpsiIsSet;
std::string m_SourceDnai;
bool m_SourceDnaiIsSet;
std::string m_TargetDnai;
bool m_TargetDnaiIsSet;
DnaiChangeType m_DnaiChgType;
bool m_DnaiChgTypeIsSet;
std::string m_SourceUeIpv4Addr;
bool m_SourceUeIpv4AddrIsSet;
Ipv6Prefix m_SourceUeIpv6Prefix;
bool m_SourceUeIpv6PrefixIsSet;
std::string m_TargetUeIpv4Addr;
bool m_TargetUeIpv4AddrIsSet;
Ipv6Prefix m_TargetUeIpv6Prefix;
bool m_TargetUeIpv6PrefixIsSet;
RouteToLocation m_SourceTraRouting;
bool m_SourceTraRoutingIsSet;
RouteToLocation m_TargetTraRouting;
bool m_TargetTraRoutingIsSet;
std::string m_UeMac;
bool m_UeMacIsSet;
std::string m_AdIpv4Addr;
bool m_AdIpv4AddrIsSet;
Ipv6Prefix m_AdIpv6Prefix;
bool m_AdIpv6PrefixIsSet;
std::string m_ReIpv4Addr;
bool m_ReIpv4AddrIsSet;
Ipv6Prefix m_ReIpv6Prefix;
bool m_ReIpv6PrefixIsSet;
PlmnId m_PlmnId;
bool m_PlmnIdIsSet;
AccessType m_AccType;
bool m_AccTypeIsSet;
int32_t m_PduSeId;
bool m_PduSeIdIsSet;
DddStatus m_DddStatus;
bool m_DddStatusIsSet;
std::string m_MaxWaitTime;
bool m_MaxWaitTimeIsSet;
};
}
}
}
#endif /* EventNotification_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "EventSubscription.h"
namespace oai {
namespace smf_server {
namespace model {
EventSubscription::EventSubscription()
{
m_DnaiChgTypeIsSet = false;
m_DddTraDesIsSet = false;
m_DddStatiIsSet = false;
}
EventSubscription::~EventSubscription()
{
}
void EventSubscription::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const EventSubscription& o)
{
j = nlohmann::json();
j["event"] = o.m_Event;
if(o.dnaiChgTypeIsSet())
j["dnaiChgType"] = o.m_DnaiChgType;
if(o.dddTraDesIsSet())
j["dddTraDes"] = o.m_DddTraDes;
if(o.dddStatiIsSet() || !o.m_DddStati.empty())
j["dddStati"] = o.m_DddStati;
}
void from_json(const nlohmann::json& j, EventSubscription& o)
{
j.at("event").get_to(o.m_Event);
if(j.find("dnaiChgType") != j.end())
{
j.at("dnaiChgType").get_to(o.m_DnaiChgType);
o.m_DnaiChgTypeIsSet = true;
}
if(j.find("dddTraDes") != j.end())
{
j.at("dddTraDes").get_to(o.m_DddTraDes);
o.m_DddTraDesIsSet = true;
}
if(j.find("dddStati") != j.end())
{
j.at("dddStati").get_to(o.m_DddStati);
o.m_DddStatiIsSet = true;
}
}
SmfEvent EventSubscription::getEvent() const
{
return m_Event;
}
void EventSubscription::setEvent(SmfEvent const& value)
{
m_Event = value;
}
DnaiChangeType EventSubscription::getDnaiChgType() const
{
return m_DnaiChgType;
}
void EventSubscription::setDnaiChgType(DnaiChangeType const& value)
{
m_DnaiChgType = value;
m_DnaiChgTypeIsSet = true;
}
bool EventSubscription::dnaiChgTypeIsSet() const
{
return m_DnaiChgTypeIsSet;
}
void EventSubscription::unsetDnaiChgType()
{
m_DnaiChgTypeIsSet = false;
}
DddTrafficDescriptor EventSubscription::getDddTraDes() const
{
return m_DddTraDes;
}
void EventSubscription::setDddTraDes(DddTrafficDescriptor const& value)
{
m_DddTraDes = value;
m_DddTraDesIsSet = true;
}
bool EventSubscription::dddTraDesIsSet() const
{
return m_DddTraDesIsSet;
}
void EventSubscription::unsetDddTraDes()
{
m_DddTraDesIsSet = false;
}
std::vector<DddStatus>& EventSubscription::getDddStati()
{
return m_DddStati;
}
void EventSubscription::setDddStati(std::vector<DddStatus> const& value)
{
m_DddStati = value;
m_DddStatiIsSet = true;
}
bool EventSubscription::dddStatiIsSet() const
{
return m_DddStatiIsSet;
}
void EventSubscription::unsetDddStati()
{
m_DddStatiIsSet = false;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* EventSubscription.h
*
*
*/
#ifndef EventSubscription_H_
#define EventSubscription_H_
#include "DnaiChangeType.h"
#include "DddTrafficDescriptor.h"
#include "DddStatus.h"
#include "SmfEvent.h"
#include <vector>
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class EventSubscription
{
public:
EventSubscription();
virtual ~EventSubscription();
void validate();
/////////////////////////////////////////////
/// EventSubscription members
/// <summary>
///
/// </summary>
SmfEvent getEvent() const;
void setEvent(SmfEvent const& value);
/// <summary>
///
/// </summary>
DnaiChangeType getDnaiChgType() const;
void setDnaiChgType(DnaiChangeType const& value);
bool dnaiChgTypeIsSet() const;
void unsetDnaiChgType();
/// <summary>
///
/// </summary>
DddTrafficDescriptor getDddTraDes() const;
void setDddTraDes(DddTrafficDescriptor const& value);
bool dddTraDesIsSet() const;
void unsetDddTraDes();
/// <summary>
///
/// </summary>
std::vector<DddStatus>& getDddStati();
void setDddStati(std::vector<DddStatus> const& value);
bool dddStatiIsSet() const;
void unsetDddStati();
friend void to_json(nlohmann::json& j, const EventSubscription& o);
friend void from_json(const nlohmann::json& j, EventSubscription& o);
protected:
SmfEvent m_Event;
DnaiChangeType m_DnaiChgType;
bool m_DnaiChgTypeIsSet;
DddTrafficDescriptor m_DddTraDes;
bool m_DddTraDesIsSet;
std::vector<DddStatus> m_DddStati;
bool m_DddStatiIsSet;
};
}
}
}
#endif /* EventSubscription_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "Ipv6Addr.h"
namespace oai {
namespace smf_server {
namespace model {
Ipv6Addr::Ipv6Addr()
{
}
Ipv6Addr::~Ipv6Addr()
{
}
void Ipv6Addr::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const Ipv6Addr& o)
{
j = nlohmann::json();
}
void from_json(const nlohmann::json& j, Ipv6Addr& o)
{
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* Ipv6Addr.h
*
*
*/
#ifndef Ipv6Addr_H_
#define Ipv6Addr_H_
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class Ipv6Addr
{
public:
Ipv6Addr();
virtual ~Ipv6Addr();
void validate();
/////////////////////////////////////////////
/// Ipv6Addr members
friend void to_json(nlohmann::json& j, const Ipv6Addr& o);
friend void from_json(const nlohmann::json& j, Ipv6Addr& o);
protected:
};
}
}
}
#endif /* Ipv6Addr_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "Ipv6Prefix.h"
namespace oai {
namespace smf_server {
namespace model {
Ipv6Prefix::Ipv6Prefix()
{
}
Ipv6Prefix::~Ipv6Prefix()
{
}
void Ipv6Prefix::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const Ipv6Prefix& o)
{
j = nlohmann::json();
}
void from_json(const nlohmann::json& j, Ipv6Prefix& o)
{
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* Ipv6Prefix.h
*
*
*/
#ifndef Ipv6Prefix_H_
#define Ipv6Prefix_H_
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class Ipv6Prefix
{
public:
Ipv6Prefix();
virtual ~Ipv6Prefix();
void validate();
/////////////////////////////////////////////
/// Ipv6Prefix members
friend void to_json(nlohmann::json& j, const Ipv6Prefix& o);
friend void from_json(const nlohmann::json& j, Ipv6Prefix& o);
protected:
};
}
}
}
#endif /* Ipv6Prefix_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "NotificationMethod.h"
namespace oai {
namespace smf_server {
namespace model {
NotificationMethod::NotificationMethod()
{
}
NotificationMethod::~NotificationMethod()
{
}
void NotificationMethod::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const NotificationMethod& o)
{
j = nlohmann::json();
}
void from_json(const nlohmann::json& j, NotificationMethod& o)
{
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* NotificationMethod.h
*
* Possible values are - PERIODIC - ONE_TIME - ON_EVENT_DETECTION
*/
#ifndef NotificationMethod_H_
#define NotificationMethod_H_
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
/// Possible values are - PERIODIC - ONE_TIME - ON_EVENT_DETECTION
/// </summary>
class NotificationMethod
{
public:
NotificationMethod();
virtual ~NotificationMethod();
void validate();
/////////////////////////////////////////////
/// NotificationMethod members
friend void to_json(nlohmann::json& j, const NotificationMethod& o);
friend void from_json(const nlohmann::json& j, NotificationMethod& o);
protected:
};
}
}
}
#endif /* NotificationMethod_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "NsmfEventExposure.h"
namespace oai {
namespace smf_server {
namespace model {
NsmfEventExposure::NsmfEventExposure()
{
m_Supi = "";
m_SupiIsSet = false;
m_Gpsi = "";
m_GpsiIsSet = false;
m_AnyUeInd = false;
m_AnyUeIndIsSet = false;
m_GroupId = "";
m_GroupIdIsSet = false;
m_PduSeId = 0;
m_PduSeIdIsSet = false;
m_SubId = "";
m_SubIdIsSet = false;
m_NotifId = "";
m_NotifUri = "";
m_AltNotifIpv4AddrsIsSet = false;
m_AltNotifIpv6AddrsIsSet = false;
m_ImmeRep = false;
m_ImmeRepIsSet = false;
m_NotifMethodIsSet = false;
m_MaxReportNbr = 0;
m_MaxReportNbrIsSet = false;
m_Expiry = "";
m_ExpiryIsSet = false;
m_RepPeriod = 0;
m_RepPeriodIsSet = false;
m_GuamiIsSet = false;
m_ServiveName = "";
m_ServiveNameIsSet = false;
m_SupportedFeatures = "";
m_SupportedFeaturesIsSet = false;
}
NsmfEventExposure::~NsmfEventExposure()
{
}
void NsmfEventExposure::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const NsmfEventExposure& o)
{
j = nlohmann::json();
if(o.supiIsSet())
j["supi"] = o.m_Supi;
if(o.gpsiIsSet())
j["gpsi"] = o.m_Gpsi;
if(o.anyUeIndIsSet())
j["anyUeInd"] = o.m_AnyUeInd;
if(o.groupIdIsSet())
j["groupId"] = o.m_GroupId;
if(o.pduSeIdIsSet())
j["pduSeId"] = o.m_PduSeId;
if(o.subIdIsSet())
j["subId"] = o.m_SubId;
j["notifId"] = o.m_NotifId;
j["notifUri"] = o.m_NotifUri;
if(o.altNotifIpv4AddrsIsSet() || !o.m_AltNotifIpv4Addrs.empty())
j["altNotifIpv4Addrs"] = o.m_AltNotifIpv4Addrs;
if(o.altNotifIpv6AddrsIsSet() || !o.m_AltNotifIpv6Addrs.empty())
j["altNotifIpv6Addrs"] = o.m_AltNotifIpv6Addrs;
j["eventSubs"] = o.m_EventSubs;
if(o.immeRepIsSet())
j["ImmeRep"] = o.m_ImmeRep;
if(o.notifMethodIsSet())
j["notifMethod"] = o.m_NotifMethod;
if(o.maxReportNbrIsSet())
j["maxReportNbr"] = o.m_MaxReportNbr;
if(o.expiryIsSet())
j["expiry"] = o.m_Expiry;
if(o.repPeriodIsSet())
j["repPeriod"] = o.m_RepPeriod;
if(o.guamiIsSet())
j["guami"] = o.m_Guami;
if(o.serviveNameIsSet())
j["serviveName"] = o.m_ServiveName;
if(o.supportedFeaturesIsSet())
j["supportedFeatures"] = o.m_SupportedFeatures;
}
void from_json(const nlohmann::json& j, NsmfEventExposure& o)
{
if(j.find("supi") != j.end())
{
j.at("supi").get_to(o.m_Supi);
o.m_SupiIsSet = true;
}
if(j.find("gpsi") != j.end())
{
j.at("gpsi").get_to(o.m_Gpsi);
o.m_GpsiIsSet = true;
}
if(j.find("anyUeInd") != j.end())
{
j.at("anyUeInd").get_to(o.m_AnyUeInd);
o.m_AnyUeIndIsSet = true;
}
if(j.find("groupId") != j.end())
{
j.at("groupId").get_to(o.m_GroupId);
o.m_GroupIdIsSet = true;
}
if(j.find("pduSeId") != j.end())
{
j.at("pduSeId").get_to(o.m_PduSeId);
o.m_PduSeIdIsSet = true;
}
if(j.find("subId") != j.end())
{
j.at("subId").get_to(o.m_SubId);
o.m_SubIdIsSet = true;
}
j.at("notifId").get_to(o.m_NotifId);
j.at("notifUri").get_to(o.m_NotifUri);
if(j.find("altNotifIpv4Addrs") != j.end())
{
j.at("altNotifIpv4Addrs").get_to(o.m_AltNotifIpv4Addrs);
o.m_AltNotifIpv4AddrsIsSet = true;
}
if(j.find("altNotifIpv6Addrs") != j.end())
{
j.at("altNotifIpv6Addrs").get_to(o.m_AltNotifIpv6Addrs);
o.m_AltNotifIpv6AddrsIsSet = true;
}
j.at("eventSubs").get_to(o.m_EventSubs);
if(j.find("ImmeRep") != j.end())
{
j.at("ImmeRep").get_to(o.m_ImmeRep);
o.m_ImmeRepIsSet = true;
}
if(j.find("notifMethod") != j.end())
{
j.at("notifMethod").get_to(o.m_NotifMethod);
o.m_NotifMethodIsSet = true;
}
if(j.find("maxReportNbr") != j.end())
{
j.at("maxReportNbr").get_to(o.m_MaxReportNbr);
o.m_MaxReportNbrIsSet = true;
}
if(j.find("expiry") != j.end())
{
j.at("expiry").get_to(o.m_Expiry);
o.m_ExpiryIsSet = true;
}
if(j.find("repPeriod") != j.end())
{
j.at("repPeriod").get_to(o.m_RepPeriod);
o.m_RepPeriodIsSet = true;
}
if(j.find("guami") != j.end())
{
j.at("guami").get_to(o.m_Guami);
o.m_GuamiIsSet = true;
}
if(j.find("serviveName") != j.end())
{
j.at("serviveName").get_to(o.m_ServiveName);
o.m_ServiveNameIsSet = true;
}
if(j.find("supportedFeatures") != j.end())
{
j.at("supportedFeatures").get_to(o.m_SupportedFeatures);
o.m_SupportedFeaturesIsSet = true;
}
}
std::string NsmfEventExposure::getSupi() const
{
return m_Supi;
}
void NsmfEventExposure::setSupi(std::string const& value)
{
m_Supi = value;
m_SupiIsSet = true;
}
bool NsmfEventExposure::supiIsSet() const
{
return m_SupiIsSet;
}
void NsmfEventExposure::unsetSupi()
{
m_SupiIsSet = false;
}
std::string NsmfEventExposure::getGpsi() const
{
return m_Gpsi;
}
void NsmfEventExposure::setGpsi(std::string const& value)
{
m_Gpsi = value;
m_GpsiIsSet = true;
}
bool NsmfEventExposure::gpsiIsSet() const
{
return m_GpsiIsSet;
}
void NsmfEventExposure::unsetGpsi()
{
m_GpsiIsSet = false;
}
bool NsmfEventExposure::isAnyUeInd() const
{
return m_AnyUeInd;
}
void NsmfEventExposure::setAnyUeInd(bool const value)
{
m_AnyUeInd = value;
m_AnyUeIndIsSet = true;
}
bool NsmfEventExposure::anyUeIndIsSet() const
{
return m_AnyUeIndIsSet;
}
void NsmfEventExposure::unsetAnyUeInd()
{
m_AnyUeIndIsSet = false;
}
std::string NsmfEventExposure::getGroupId() const
{
return m_GroupId;
}
void NsmfEventExposure::setGroupId(std::string const& value)
{
m_GroupId = value;
m_GroupIdIsSet = true;
}
bool NsmfEventExposure::groupIdIsSet() const
{
return m_GroupIdIsSet;
}
void NsmfEventExposure::unsetGroupId()
{
m_GroupIdIsSet = false;
}
int32_t NsmfEventExposure::getPduSeId() const
{
return m_PduSeId;
}
void NsmfEventExposure::setPduSeId(int32_t const value)
{
m_PduSeId = value;
m_PduSeIdIsSet = true;
}
bool NsmfEventExposure::pduSeIdIsSet() const
{
return m_PduSeIdIsSet;
}
void NsmfEventExposure::unsetPduSeId()
{
m_PduSeIdIsSet = false;
}
std::string NsmfEventExposure::getSubId() const
{
return m_SubId;
}
void NsmfEventExposure::setSubId(std::string const& value)
{
m_SubId = value;
m_SubIdIsSet = true;
}
bool NsmfEventExposure::subIdIsSet() const
{
return m_SubIdIsSet;
}
void NsmfEventExposure::unsetSubId()
{
m_SubIdIsSet = false;
}
std::string NsmfEventExposure::getNotifId() const
{
return m_NotifId;
}
void NsmfEventExposure::setNotifId(std::string const& value)
{
m_NotifId = value;
}
std::string NsmfEventExposure::getNotifUri() const
{
return m_NotifUri;
}
void NsmfEventExposure::setNotifUri(std::string const& value)
{
m_NotifUri = value;
}
std::vector<std::string>& NsmfEventExposure::getAltNotifIpv4Addrs()
{
return m_AltNotifIpv4Addrs;
}
void NsmfEventExposure::setAltNotifIpv4Addrs(std::vector<std::string> const& value)
{
m_AltNotifIpv4Addrs = value;
m_AltNotifIpv4AddrsIsSet = true;
}
bool NsmfEventExposure::altNotifIpv4AddrsIsSet() const
{
return m_AltNotifIpv4AddrsIsSet;
}
void NsmfEventExposure::unsetAltNotifIpv4Addrs()
{
m_AltNotifIpv4AddrsIsSet = false;
}
std::vector<Ipv6Addr>& NsmfEventExposure::getAltNotifIpv6Addrs()
{
return m_AltNotifIpv6Addrs;
}
void NsmfEventExposure::setAltNotifIpv6Addrs(std::vector<Ipv6Addr> const& value)
{
m_AltNotifIpv6Addrs = value;
m_AltNotifIpv6AddrsIsSet = true;
}
bool NsmfEventExposure::altNotifIpv6AddrsIsSet() const
{
return m_AltNotifIpv6AddrsIsSet;
}
void NsmfEventExposure::unsetAltNotifIpv6Addrs()
{
m_AltNotifIpv6AddrsIsSet = false;
}
std::vector<EventSubscription>& NsmfEventExposure::getEventSubs()
{
return m_EventSubs;
}
void NsmfEventExposure::setEventSubs(std::vector<EventSubscription> const& value)
{
m_EventSubs = value;
}
bool NsmfEventExposure::isImmeRep() const
{
return m_ImmeRep;
}
void NsmfEventExposure::setImmeRep(bool const value)
{
m_ImmeRep = value;
m_ImmeRepIsSet = true;
}
bool NsmfEventExposure::immeRepIsSet() const
{
return m_ImmeRepIsSet;
}
void NsmfEventExposure::unsetImmeRep()
{
m_ImmeRepIsSet = false;
}
NotificationMethod NsmfEventExposure::getNotifMethod() const
{
return m_NotifMethod;
}
void NsmfEventExposure::setNotifMethod(NotificationMethod const& value)
{
m_NotifMethod = value;
m_NotifMethodIsSet = true;
}
bool NsmfEventExposure::notifMethodIsSet() const
{
return m_NotifMethodIsSet;
}
void NsmfEventExposure::unsetNotifMethod()
{
m_NotifMethodIsSet = false;
}
int32_t NsmfEventExposure::getMaxReportNbr() const
{
return m_MaxReportNbr;
}
void NsmfEventExposure::setMaxReportNbr(int32_t const value)
{
m_MaxReportNbr = value;
m_MaxReportNbrIsSet = true;
}
bool NsmfEventExposure::maxReportNbrIsSet() const
{
return m_MaxReportNbrIsSet;
}
void NsmfEventExposure::unsetMaxReportNbr()
{
m_MaxReportNbrIsSet = false;
}
std::string NsmfEventExposure::getExpiry() const
{
return m_Expiry;
}
void NsmfEventExposure::setExpiry(std::string const& value)
{
m_Expiry = value;
m_ExpiryIsSet = true;
}
bool NsmfEventExposure::expiryIsSet() const
{
return m_ExpiryIsSet;
}
void NsmfEventExposure::unsetExpiry()
{
m_ExpiryIsSet = false;
}
int32_t NsmfEventExposure::getRepPeriod() const
{
return m_RepPeriod;
}
void NsmfEventExposure::setRepPeriod(int32_t const value)
{
m_RepPeriod = value;
m_RepPeriodIsSet = true;
}
bool NsmfEventExposure::repPeriodIsSet() const
{
return m_RepPeriodIsSet;
}
void NsmfEventExposure::unsetRepPeriod()
{
m_RepPeriodIsSet = false;
}
Guami NsmfEventExposure::getGuami() const
{
return m_Guami;
}
void NsmfEventExposure::setGuami(Guami const& value)
{
m_Guami = value;
m_GuamiIsSet = true;
}
bool NsmfEventExposure::guamiIsSet() const
{
return m_GuamiIsSet;
}
void NsmfEventExposure::unsetGuami()
{
m_GuamiIsSet = false;
}
std::string NsmfEventExposure::getServiveName() const
{
return m_ServiveName;
}
void NsmfEventExposure::setServiveName(std::string const& value)
{
m_ServiveName = value;
m_ServiveNameIsSet = true;
}
bool NsmfEventExposure::serviveNameIsSet() const
{
return m_ServiveNameIsSet;
}
void NsmfEventExposure::unsetServiveName()
{
m_ServiveNameIsSet = false;
}
std::string NsmfEventExposure::getSupportedFeatures() const
{
return m_SupportedFeatures;
}
void NsmfEventExposure::setSupportedFeatures(std::string const& value)
{
m_SupportedFeatures = value;
m_SupportedFeaturesIsSet = true;
}
bool NsmfEventExposure::supportedFeaturesIsSet() const
{
return m_SupportedFeaturesIsSet;
}
void NsmfEventExposure::unsetSupportedFeatures()
{
m_SupportedFeaturesIsSet = false;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* NsmfEventExposure.h
*
*
*/
#ifndef NsmfEventExposure_H_
#define NsmfEventExposure_H_
#include "EventSubscription.h"
#include "NotificationMethod.h"
#include <string>
#include "Ipv6Addr.h"
#include <vector>
#include "Guami.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class NsmfEventExposure
{
public:
NsmfEventExposure();
virtual ~NsmfEventExposure();
void validate();
/////////////////////////////////////////////
/// NsmfEventExposure members
/// <summary>
///
/// </summary>
std::string getSupi() const;
void setSupi(std::string const& value);
bool supiIsSet() const;
void unsetSupi();
/// <summary>
///
/// </summary>
std::string getGpsi() const;
void setGpsi(std::string const& value);
bool gpsiIsSet() const;
void unsetGpsi();
/// <summary>
/// Any UE indication. This IE shall be present if the event subscription is applicable to any UE. Default value \&quot;FALSE\&quot; is used, if not present.
/// </summary>
bool isAnyUeInd() const;
void setAnyUeInd(bool const value);
bool anyUeIndIsSet() const;
void unsetAnyUeInd();
/// <summary>
///
/// </summary>
std::string getGroupId() const;
void setGroupId(std::string const& value);
bool groupIdIsSet() const;
void unsetGroupId();
/// <summary>
///
/// </summary>
int32_t getPduSeId() const;
void setPduSeId(int32_t const value);
bool pduSeIdIsSet() const;
void unsetPduSeId();
/// <summary>
/// Identifies an Individual SMF Notification Subscription. To enable that the value is used as part of a URI, the string shall only contain characters allowed according to the \&quot;lower-with-hyphen\&quot; naming convention defined in 3GPP TS 29.501 [2]. In an OpenAPI [10] schema, the format shall be designated as \&quot;SubId\&quot;.
/// </summary>
std::string getSubId() const;
void setSubId(std::string const& value);
bool subIdIsSet() const;
void unsetSubId();
/// <summary>
/// Notification Correlation ID assigned by the NF service consumer.
/// </summary>
std::string getNotifId() const;
void setNotifId(std::string const& value);
/// <summary>
///
/// </summary>
std::string getNotifUri() const;
void setNotifUri(std::string const& value);
/// <summary>
/// Alternate or backup IPv4 Addess(es) where to send Notifications.
/// </summary>
std::vector<std::string>& getAltNotifIpv4Addrs();
void setAltNotifIpv4Addrs(std::vector<std::string> const& value);
bool altNotifIpv4AddrsIsSet() const;
void unsetAltNotifIpv4Addrs();
/// <summary>
/// Alternate or backup IPv6 Addess(es) where to send Notifications.
/// </summary>
std::vector<Ipv6Addr>& getAltNotifIpv6Addrs();
void setAltNotifIpv6Addrs(std::vector<Ipv6Addr> const& value);
bool altNotifIpv6AddrsIsSet() const;
void unsetAltNotifIpv6Addrs();
/// <summary>
/// Subscribed events
/// </summary>
std::vector<EventSubscription>& getEventSubs();
void setEventSubs(std::vector<EventSubscription> const& value);
/// <summary>
///
/// </summary>
bool isImmeRep() const;
void setImmeRep(bool const value);
bool immeRepIsSet() const;
void unsetImmeRep();
/// <summary>
///
/// </summary>
NotificationMethod getNotifMethod() const;
void setNotifMethod(NotificationMethod const& value);
bool notifMethodIsSet() const;
void unsetNotifMethod();
/// <summary>
///
/// </summary>
int32_t getMaxReportNbr() const;
void setMaxReportNbr(int32_t const value);
bool maxReportNbrIsSet() const;
void unsetMaxReportNbr();
/// <summary>
///
/// </summary>
std::string getExpiry() const;
void setExpiry(std::string const& value);
bool expiryIsSet() const;
void unsetExpiry();
/// <summary>
///
/// </summary>
int32_t getRepPeriod() const;
void setRepPeriod(int32_t const value);
bool repPeriodIsSet() const;
void unsetRepPeriod();
/// <summary>
///
/// </summary>
Guami getGuami() const;
void setGuami(Guami const& value);
bool guamiIsSet() const;
void unsetGuami();
/// <summary>
/// If the NF service consumer is an AMF, it should provide the name of a service produced by the AMF that makes use of notifications about subscribed events.
/// </summary>
std::string getServiveName() const;
void setServiveName(std::string const& value);
bool serviveNameIsSet() const;
void unsetServiveName();
/// <summary>
///
/// </summary>
std::string getSupportedFeatures() const;
void setSupportedFeatures(std::string const& value);
bool supportedFeaturesIsSet() const;
void unsetSupportedFeatures();
friend void to_json(nlohmann::json& j, const NsmfEventExposure& o);
friend void from_json(const nlohmann::json& j, NsmfEventExposure& o);
protected:
std::string m_Supi;
bool m_SupiIsSet;
std::string m_Gpsi;
bool m_GpsiIsSet;
bool m_AnyUeInd;
bool m_AnyUeIndIsSet;
std::string m_GroupId;
bool m_GroupIdIsSet;
int32_t m_PduSeId;
bool m_PduSeIdIsSet;
std::string m_SubId;
bool m_SubIdIsSet;
std::string m_NotifId;
std::string m_NotifUri;
std::vector<std::string> m_AltNotifIpv4Addrs;
bool m_AltNotifIpv4AddrsIsSet;
std::vector<Ipv6Addr> m_AltNotifIpv6Addrs;
bool m_AltNotifIpv6AddrsIsSet;
std::vector<EventSubscription> m_EventSubs;
bool m_ImmeRep;
bool m_ImmeRepIsSet;
NotificationMethod m_NotifMethod;
bool m_NotifMethodIsSet;
int32_t m_MaxReportNbr;
bool m_MaxReportNbrIsSet;
std::string m_Expiry;
bool m_ExpiryIsSet;
int32_t m_RepPeriod;
bool m_RepPeriodIsSet;
Guami m_Guami;
bool m_GuamiIsSet;
std::string m_ServiveName;
bool m_ServiveNameIsSet;
std::string m_SupportedFeatures;
bool m_SupportedFeaturesIsSet;
};
}
}
}
#endif /* NsmfEventExposure_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "NsmfEventExposureNotification.h"
namespace oai {
namespace smf_server {
namespace model {
NsmfEventExposureNotification::NsmfEventExposureNotification()
{
m_NotifId = "";
}
NsmfEventExposureNotification::~NsmfEventExposureNotification()
{
}
void NsmfEventExposureNotification::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const NsmfEventExposureNotification& o)
{
j = nlohmann::json();
j["notifId"] = o.m_NotifId;
j["eventNotifs"] = o.m_EventNotifs;
}
void from_json(const nlohmann::json& j, NsmfEventExposureNotification& o)
{
j.at("notifId").get_to(o.m_NotifId);
j.at("eventNotifs").get_to(o.m_EventNotifs);
}
std::string NsmfEventExposureNotification::getNotifId() const
{
return m_NotifId;
}
void NsmfEventExposureNotification::setNotifId(std::string const& value)
{
m_NotifId = value;
}
std::vector<EventNotification>& NsmfEventExposureNotification::getEventNotifs()
{
return m_EventNotifs;
}
void NsmfEventExposureNotification::setEventNotifs(std::vector<EventNotification> const& value)
{
m_EventNotifs = value;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* NsmfEventExposureNotification.h
*
*
*/
#ifndef NsmfEventExposureNotification_H_
#define NsmfEventExposureNotification_H_
#include <string>
#include <vector>
#include "EventNotification.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class NsmfEventExposureNotification
{
public:
NsmfEventExposureNotification();
virtual ~NsmfEventExposureNotification();
void validate();
/////////////////////////////////////////////
/// NsmfEventExposureNotification members
/// <summary>
/// Notification correlation ID
/// </summary>
std::string getNotifId() const;
void setNotifId(std::string const& value);
/// <summary>
/// Notifications about Individual Events
/// </summary>
std::vector<EventNotification>& getEventNotifs();
void setEventNotifs(std::vector<EventNotification> const& value);
friend void to_json(nlohmann::json& j, const NsmfEventExposureNotification& o);
friend void from_json(const nlohmann::json& j, NsmfEventExposureNotification& o);
protected:
std::string m_NotifId;
std::vector<EventNotification> m_EventNotifs;
};
}
}
}
#endif /* NsmfEventExposureNotification_H_ */
......@@ -61,7 +61,7 @@ void to_json(nlohmann::json& j, const ProblemDetails& o)
j["instance"] = o.m_Instance;
if(o.causeIsSet())
j["cause"] = o.m_Cause;
if(o.invalidParamsIsSet())
if(o.invalidParamsIsSet() || !o.m_InvalidParams.empty())
j["invalidParams"] = o.m_InvalidParams;
if(o.supportedFeaturesIsSet())
j["supportedFeatures"] = o.m_SupportedFeatures;
......@@ -217,6 +217,11 @@ std::vector<InvalidParam>& ProblemDetails::getInvalidParams()
{
return m_InvalidParams;
}
void ProblemDetails::setInvalidParams(std::vector<InvalidParam> const& value)
{
m_InvalidParams = value;
m_InvalidParamsIsSet = true;
}
bool ProblemDetails::invalidParamsIsSet() const
{
return m_InvalidParamsIsSet;
......
......@@ -88,6 +88,7 @@ public:
///
/// </summary>
std::vector<InvalidParam>& getInvalidParams();
void setInvalidParams(std::vector<InvalidParam> const& value);
bool invalidParamsIsSet() const;
void unsetInvalidParams();
/// <summary>
......
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "RouteInformation.h"
namespace oai {
namespace smf_server {
namespace model {
RouteInformation::RouteInformation()
{
m_Ipv4Addr = "";
m_Ipv4AddrIsSet = false;
m_Ipv6AddrIsSet = false;
m_PortNumber = 0;
}
RouteInformation::~RouteInformation()
{
}
void RouteInformation::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const RouteInformation& o)
{
j = nlohmann::json();
if(o.ipv4AddrIsSet())
j["ipv4Addr"] = o.m_Ipv4Addr;
if(o.ipv6AddrIsSet())
j["ipv6Addr"] = o.m_Ipv6Addr;
j["portNumber"] = o.m_PortNumber;
}
void from_json(const nlohmann::json& j, RouteInformation& o)
{
if(j.find("ipv4Addr") != j.end())
{
j.at("ipv4Addr").get_to(o.m_Ipv4Addr);
o.m_Ipv4AddrIsSet = true;
}
if(j.find("ipv6Addr") != j.end())
{
j.at("ipv6Addr").get_to(o.m_Ipv6Addr);
o.m_Ipv6AddrIsSet = true;
}
j.at("portNumber").get_to(o.m_PortNumber);
}
std::string RouteInformation::getIpv4Addr() const
{
return m_Ipv4Addr;
}
void RouteInformation::setIpv4Addr(std::string const& value)
{
m_Ipv4Addr = value;
m_Ipv4AddrIsSet = true;
}
bool RouteInformation::ipv4AddrIsSet() const
{
return m_Ipv4AddrIsSet;
}
void RouteInformation::unsetIpv4Addr()
{
m_Ipv4AddrIsSet = false;
}
Ipv6Addr RouteInformation::getIpv6Addr() const
{
return m_Ipv6Addr;
}
void RouteInformation::setIpv6Addr(Ipv6Addr const& value)
{
m_Ipv6Addr = value;
m_Ipv6AddrIsSet = true;
}
bool RouteInformation::ipv6AddrIsSet() const
{
return m_Ipv6AddrIsSet;
}
void RouteInformation::unsetIpv6Addr()
{
m_Ipv6AddrIsSet = false;
}
int32_t RouteInformation::getPortNumber() const
{
return m_PortNumber;
}
void RouteInformation::setPortNumber(int32_t const value)
{
m_PortNumber = value;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* RouteInformation.h
*
*
*/
#ifndef RouteInformation_H_
#define RouteInformation_H_
#include <string>
#include "Ipv6Addr.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class RouteInformation
{
public:
RouteInformation();
virtual ~RouteInformation();
void validate();
/////////////////////////////////////////////
/// RouteInformation members
/// <summary>
///
/// </summary>
std::string getIpv4Addr() const;
void setIpv4Addr(std::string const& value);
bool ipv4AddrIsSet() const;
void unsetIpv4Addr();
/// <summary>
///
/// </summary>
Ipv6Addr getIpv6Addr() const;
void setIpv6Addr(Ipv6Addr const& value);
bool ipv6AddrIsSet() const;
void unsetIpv6Addr();
/// <summary>
///
/// </summary>
int32_t getPortNumber() const;
void setPortNumber(int32_t const value);
friend void to_json(nlohmann::json& j, const RouteInformation& o);
friend void from_json(const nlohmann::json& j, RouteInformation& o);
protected:
std::string m_Ipv4Addr;
bool m_Ipv4AddrIsSet;
Ipv6Addr m_Ipv6Addr;
bool m_Ipv6AddrIsSet;
int32_t m_PortNumber;
};
}
}
}
#endif /* RouteInformation_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "RouteToLocation.h"
namespace oai {
namespace smf_server {
namespace model {
RouteToLocation::RouteToLocation()
{
m_Dnai = "";
m_RouteInfoIsSet = false;
m_RouteProfId = "";
m_RouteProfIdIsSet = false;
}
RouteToLocation::~RouteToLocation()
{
}
void RouteToLocation::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const RouteToLocation& o)
{
j = nlohmann::json();
j["dnai"] = o.m_Dnai;
if(o.routeInfoIsSet())
j["routeInfo"] = o.m_RouteInfo;
if(o.routeProfIdIsSet())
j["routeProfId"] = o.m_RouteProfId;
}
void from_json(const nlohmann::json& j, RouteToLocation& o)
{
j.at("dnai").get_to(o.m_Dnai);
if(j.find("routeInfo") != j.end())
{
j.at("routeInfo").get_to(o.m_RouteInfo);
o.m_RouteInfoIsSet = true;
}
if(j.find("routeProfId") != j.end())
{
j.at("routeProfId").get_to(o.m_RouteProfId);
o.m_RouteProfIdIsSet = true;
}
}
std::string RouteToLocation::getDnai() const
{
return m_Dnai;
}
void RouteToLocation::setDnai(std::string const& value)
{
m_Dnai = value;
}
RouteInformation RouteToLocation::getRouteInfo() const
{
return m_RouteInfo;
}
void RouteToLocation::setRouteInfo(RouteInformation const& value)
{
m_RouteInfo = value;
m_RouteInfoIsSet = true;
}
bool RouteToLocation::routeInfoIsSet() const
{
return m_RouteInfoIsSet;
}
void RouteToLocation::unsetRouteInfo()
{
m_RouteInfoIsSet = false;
}
std::string RouteToLocation::getRouteProfId() const
{
return m_RouteProfId;
}
void RouteToLocation::setRouteProfId(std::string const& value)
{
m_RouteProfId = value;
m_RouteProfIdIsSet = true;
}
bool RouteToLocation::routeProfIdIsSet() const
{
return m_RouteProfIdIsSet;
}
void RouteToLocation::unsetRouteProfId()
{
m_RouteProfIdIsSet = false;
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* RouteToLocation.h
*
*
*/
#ifndef RouteToLocation_H_
#define RouteToLocation_H_
#include <string>
#include "RouteInformation.h"
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
///
/// </summary>
class RouteToLocation
{
public:
RouteToLocation();
virtual ~RouteToLocation();
void validate();
/////////////////////////////////////////////
/// RouteToLocation members
/// <summary>
///
/// </summary>
std::string getDnai() const;
void setDnai(std::string const& value);
/// <summary>
///
/// </summary>
RouteInformation getRouteInfo() const;
void setRouteInfo(RouteInformation const& value);
bool routeInfoIsSet() const;
void unsetRouteInfo();
/// <summary>
///
/// </summary>
std::string getRouteProfId() const;
void setRouteProfId(std::string const& value);
bool routeProfIdIsSet() const;
void unsetRouteProfId();
friend void to_json(nlohmann::json& j, const RouteToLocation& o);
friend void from_json(const nlohmann::json& j, RouteToLocation& o);
protected:
std::string m_Dnai;
RouteInformation m_RouteInfo;
bool m_RouteInfoIsSet;
std::string m_RouteProfId;
bool m_RouteProfIdIsSet;
};
}
}
}
#endif /* RouteToLocation_H_ */
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "SmfEvent.h"
namespace oai {
namespace smf_server {
namespace model {
SmfEvent::SmfEvent()
{
}
SmfEvent::~SmfEvent()
{
}
void SmfEvent::validate()
{
// TODO: implement validation
}
void to_json(nlohmann::json& j, const SmfEvent& o)
{
j = nlohmann::json();
}
void from_json(const nlohmann::json& j, SmfEvent& o)
{
}
}
}
}
/**
* Nsmf_EventExposure
* Session Management Event Exposure Service. © 2019, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). All rights reserved.
*
* The version of the OpenAPI document: 1.1.0.alpha-1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* SmfEvent.h
*
* Possible values are - AC_TY_CH: Access Type Change - UP_PATH_CH: UP Path Change - PDU_SES_REL: PDU Session Release - PLMN_CH: PLMN Change - UE_IP_CH: UE IP address change - DDDS: Downlink data delivery status
*/
#ifndef SmfEvent_H_
#define SmfEvent_H_
#include <nlohmann/json.hpp>
namespace oai {
namespace smf_server {
namespace model {
/// <summary>
/// Possible values are - AC_TY_CH: Access Type Change - UP_PATH_CH: UP Path Change - PDU_SES_REL: PDU Session Release - PLMN_CH: PLMN Change - UE_IP_CH: UE IP address change - DDDS: Downlink data delivery status
/// </summary>
class SmfEvent
{
public:
SmfEvent();
virtual ~SmfEvent();
void validate();
/////////////////////////////////////////////
/// SmfEvent members
friend void to_json(nlohmann::json& j, const SmfEvent& o);
friend void from_json(const nlohmann::json& j, SmfEvent& o);
protected:
};
}
}
}
#endif /* SmfEvent_H_ */
......@@ -82,6 +82,8 @@ void SMFApiServer::init(size_t thr) {
m_individualSMContextApiImpl->init();
m_pduSessionsCollectionApiImpl->init();
m_smContextsCollectionApiImpl->init();
m_individualSubscriptionDocumentApiImpl->init();
m_subscriptionsCollectionApiImpl->init();
}
void SMFApiServer::start() {
......
......@@ -47,6 +47,9 @@
#include "IndividualSMContextApiImpl.h"
#include "PDUSessionsCollectionApiImpl.h"
#include "SMContextsCollectionApiImpl.h"
#include "IndividualSubscriptionDocumentApiImpl.h"
#include "SubscriptionsCollectionApiImpl.h"
#include "smf_app.hpp"
using namespace oai::smf_server::api;
......@@ -66,6 +69,12 @@ class SMFApiServer {
m_smContextsCollectionApiImpl =
std::make_shared<SMContextsCollectionApiImpl>(m_router, smf_app_inst,
m_address);
m_individualSubscriptionDocumentApiImpl = std::make_shared
< IndividualSubscriptionDocumentApiImpl
> (m_router, smf_app_inst, m_address);
m_subscriptionsCollectionApiImpl = std::make_shared
< SubscriptionsCollectionApiImpl > (m_router, smf_app_inst, m_address);
}
void init(size_t thr = 1);
void start();
......@@ -78,6 +87,8 @@ class SMFApiServer {
std::shared_ptr<IndividualSMContextApiImpl> m_individualSMContextApiImpl;
std::shared_ptr<PDUSessionsCollectionApiImpl> m_pduSessionsCollectionApiImpl;
std::shared_ptr<SMContextsCollectionApiImpl> m_smContextsCollectionApiImpl;
std::shared_ptr<IndividualSubscriptionDocumentApiImpl> m_individualSubscriptionDocumentApiImpl;
std::shared_ptr<SubscriptionsCollectionApiImpl> m_subscriptionsCollectionApiImpl;
std::string m_address;
};
......
......@@ -392,6 +392,8 @@ void smf_http2_server::create_sm_contexts_handler(
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);
std::string json_format;
sm_context_response.get_json_format(json_format);
//Add header
header_map h;
......@@ -404,7 +406,7 @@ void smf_http2_server::create_sm_contexts_handler(
sm_context_response.get_smf_context_uri().c_str() });
}
//content-type header
h.emplace("content-type", header_value {"application/json"});
h.emplace("content-type", header_value {json_format});
response.write_head(sm_context_response.get_http_code(), h);
response.end(json_data.dump().c_str());
......@@ -506,7 +508,9 @@ void smf_http2_server::update_sm_context_handler(
mime_parser parser = { };
std::string body = { };
header_map h = { };
std::string json_format;
sm_context_response.get_json_format(json_format);
sm_context_response.get_json_data(json_data);
Logger::smf_api_server().debug("Json data %s", json_data.dump().c_str());
......@@ -515,7 +519,8 @@ void smf_http2_server::update_sm_context_handler(
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());
sm_context_response.get_n2_sm_information(),
json_format);
h.emplace(
"content-type",
header_value { "multipart/related; boundary="
......@@ -524,7 +529,8 @@ void smf_http2_server::update_sm_context_handler(
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);
multipart_related_content_part_e::NAS,
json_format);
h.emplace(
"content-type",
header_value { "multipart/related; boundary="
......@@ -533,13 +539,14 @@ void smf_http2_server::update_sm_context_handler(
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);
multipart_related_content_part_e::NGAP,
json_format);
h.emplace(
"content-type",
header_value { "multipart/related; boundary="
+ std::string(CURL_MIME_BOUNDARY) });
} else {
h.emplace("content-type", header_value { "application/json" });
h.emplace("content-type", header_value { json_format });
body = json_data.dump().c_str();
}
......
/*
* 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_3GPP_29_508_SMF_SEEN
#define FILE_3GPP_29_508_SMF_SEEN
#include "smf.h"
typedef enum smf_event_e {
SMF_EVENT_AC_TY_CH = 1,
SMF_EVENT_UP_PATH_CH = 2,
SMF_EVENT_PDU_SES_REL = 3,
SMF_EVENT_PLMN_CH = 4,
SMF_EVENT_UE_IP_CH = 5,
SMF_EVENT_DDDS = 6
} smf_event_t;
static const std::vector<std::string> smf_event_e2str = { "SMF_EVENT_UNKNOWN", "Access Type Change",
"UP Path Change", "PDU Session Release", "PLMN Change", "UE IP address change", "Downlink data delivery status"};
enum class notification_method_e {
PERIODIC = 1,
ONE_TIME = 2,
ON_EVENT_DETECTION = 3
};
static const std::vector<std::string> notification_method_e2str = { "NOTIFICATION_METHOD_UNKNOWN", "PERIODIC",
"ONE_TIME", "ON_EVENT_DETECTION"};
enum class dnai_change_type_e {
EARLY = 1,
EARLY_LATE = 2,
LATE = 3
};
enum class ddd_status_e {
BUFFERED = 1,
TRANSMITTED = 2,
DISCARDED = 3
};
typedef struct event_subscription_s {
smf_event_t smf_event;
dnai_change_type_e dnai_change_type;
//DddTrafficDescriptor
std::vector<ddd_status_e> ddd_status;
} event_subscription_t;
#endif
......@@ -63,6 +63,13 @@ typedef uint32_t scid_t;
#define INVALID_SCID ((scid_t)0x00000000)
#define UNASSIGNED_SCID ((scid_t)0x00000000)
// Event Subscription IDs)
typedef uint32_t evsub_id_t;
#define EVSUB_ID_FMT "0x%" PRIx32
#define EVSUB_ID_SCAN_FMT SCNx32
#define INVALID_EVSUB_ID ((evsub_id_t)0x00000000)
#define UNASSIGNED_EVSUB_ID ((evsub_id_t)0x00000000)
//------------------------------------------------------------------------------
// IMSI
typedef uint64_t imsi64_t;
......
......@@ -466,4 +466,90 @@ class itti_n11_session_report_request : public itti_n11_msg {
};
//-----------------------------------------------------------------------------
class itti_n11_notify_sm_context_status : public itti_n11_msg {
public:
itti_n11_notify_sm_context_status(const task_id_t orig, const task_id_t dest)
:
itti_n11_msg(N11_SESSION_NOTIFY_SM_CONTEXT_STATUS, orig, dest),
scid(0),
sm_context_status(),
amf_status_uri(),
http_version() {
}
itti_n11_notify_sm_context_status(
const itti_n11_notify_sm_context_status &i)
:
itti_n11_msg(i),
scid(i.scid),
sm_context_status(i.sm_context_status),
amf_status_uri (i.amf_status_uri),
http_version(i.http_version) {
}
itti_n11_notify_sm_context_status(
const itti_n11_notify_sm_context_status &i, const task_id_t orig,
const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
scid(i.scid),
sm_context_status(i.sm_context_status),
amf_status_uri(i.amf_status_uri),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "N11_SESSION_NOTIFY_SM_CONTEXT_STATUS";
}
;
void set_scid(scid_t id) {
scid = id;
}
;
void set_sm_context_status(std::string status) {
sm_context_status = status;
}
;
scid_t scid; //SM Context ID
std::string sm_context_status;
std::string amf_status_uri;
uint8_t http_version;
};
//-----------------------------------------------------------------------------
class itti_n11_notify_subscribed_event : public itti_n11_msg {
public:
itti_n11_notify_subscribed_event(const task_id_t orig, const task_id_t dest)
:
itti_n11_msg(N11_NOTIFY_SUBSCRIBED_EVENT, orig, dest),
notif_id(),
http_version() {
}
itti_n11_notify_subscribed_event(
const itti_n11_notify_subscribed_event &i)
:
itti_n11_msg(i),
notif_id(i.notif_id),
http_version(i.http_version) {
}
itti_n11_notify_subscribed_event(
const itti_n11_notify_subscribed_event &i, const task_id_t orig,
const task_id_t dest)
:
itti_n11_msg(i, orig, dest),
notif_id(i.notif_id),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "N11_NOTIFY_SUBSCRIBED_EVENT";
}
;
std::string notif_id;
std::vector<smf::event_notification> event_notifs;
uint8_t http_version;
};
#endif /* ITTI_MSG_N11_HPP_INCLUDED_ */
/*
* 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
*/
/*
* itti_msg_sbi.hpp
*
* Created on:
* Author:
*/
#ifndef ITTI_MSG_SBI_HPP_INCLUDED_
#define ITTI_MSG_SBI_HPP_INCLUDED_
#include "itti_msg.hpp"
#include "smf_msg.hpp"
#include "pistache/http.h"
class itti_sbi_msg : public itti_msg {
public:
itti_sbi_msg(const itti_msg_type_t msg_type, const task_id_t orig,
const task_id_t dest)
:
itti_msg(msg_type, orig, dest) {
}
itti_sbi_msg(const itti_sbi_msg &i)
:
itti_msg(i) {
}
itti_sbi_msg(const itti_sbi_msg &i, const task_id_t orig,
const task_id_t dest)
:
itti_sbi_msg(i) {
origin = orig;
destination = dest;
}
};
//-----------------------------------------------------------------------------
class itti_sbi_event_exposure_request : public itti_sbi_msg {
public:
itti_sbi_event_exposure_request(const task_id_t orig, const task_id_t dest)
:
itti_sbi_msg(SBI_EVENT_EXPOSURE_REQUEST, orig, dest),
event_exposure(),
http_version(1) {
}
itti_sbi_event_exposure_request(
const itti_sbi_event_exposure_request &i)
:
itti_sbi_msg(i),
event_exposure(i.event_exposure),
http_version(1) {
}
itti_sbi_event_exposure_request(
const itti_sbi_event_exposure_request &i, const task_id_t orig,
const task_id_t dest)
:
itti_sbi_msg(i, orig, dest),
event_exposure(i.event_exposure),
http_version(i.http_version) {
}
const char* get_msg_name() {
return "SBI_EVENT_EXPOSURE_REQUEST";
}
;
smf::event_exposure_msg event_exposure;
uint8_t http_version;
};
#endif /* ITTI_MSG_SBI_HPP_INCLUDED_ */
......@@ -154,6 +154,16 @@ static const std::vector<std::string> session_management_procedures_type_e2str =
};
enum class sm_context_status_e {
SM_CONTEXT_STATUS_ACTIVE = 0,
SM_CONTEXT_STATUS_RELEASED = 1
};
static const std::vector<std::string> sm_context_status_e2str =
{ "ACTIVE",
"RELEASED"
};
typedef struct qos_profile_gbr_s {
gfbr_t gfbr; //Guaranteed Flow Bit Rate
mfbr_t mfbr; // Maximum Flow Bit Rate
......@@ -208,4 +218,6 @@ constexpr uint64_t SECONDS_SINCE_FIRST_EPOCH = 2208988800;
#define TEID_GRE_KEY_LENGTH 4
#endif
......@@ -103,7 +103,8 @@ 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) {
const std::string &n2_message,
std::string json_format) {
//TODO: provide Content-Ids as function parameters
......@@ -113,7 +114,7 @@ void mime_parser::create_multipart_related_content(std::string &body,
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
body.append("Content-Type: "+ json_format + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
......@@ -135,7 +136,8 @@ void mime_parser::create_multipart_related_content(std::string &body,
//------------------------------------------------------------------------------
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) {
const std::string &message, const multipart_related_content_part_e content_type,
std::string json_format) {
//TODO: provide Content-Id as function parameters
//format string as hex
......@@ -143,7 +145,7 @@ void mime_parser::create_multipart_related_content(
std::string CRLF = "\r\n";
body.append("--" + boundary + CRLF);
body.append("Content-Type: application/json" + CRLF);
body.append("Content-Type: " + json_format + CRLF);
body.append(CRLF);
body.append(json_part + CRLF);
......
......@@ -82,7 +82,8 @@ class mime_parser {
const std::string &json_part,
const std::string boundary,
const std::string &n1_message,
const std::string &n2_message);
const std::string &n2_message,
std::string json_format="application/json");
/*
* Create HTTP body content for multipart/related message
......@@ -96,7 +97,8 @@ class mime_parser {
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);
const multipart_related_content_part_e content_type,
std::string json_format="application/json");
private:
std::vector<mime_part> mime_parts;
......
......@@ -114,7 +114,10 @@ typedef enum {
N11_SESSION_RELEASE_SM_CONTEXT_REQUEST,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE,
N11_SESSION_REPORT_RESPONSE,
N11_SESSION_NOTIFY_SM_CONTEXT_STATUS,
N11_NOTIFY_SUBSCRIBED_EVENT,
NX_TRIGGER_SESSION_MODIFICATION,
SBI_EVENT_EXPOSURE_REQUEST,
UDP_INIT,
UDP_DATA_REQ,
UDP_DATA_IND,
......
......@@ -229,7 +229,9 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const pfcp_heartbeat_
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -254,7 +256,10 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const pfcp_associatio
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -279,7 +284,10 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const pfcp_associatio
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
////------------------------------------------------------------------------------
......@@ -356,7 +364,9 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -382,7 +392,9 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -408,7 +420,9 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
////------------------------------------------------------------------------------
......@@ -460,7 +474,9 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......@@ -486,7 +502,9 @@ uint32_t pfcp_l4_stack::send_request(const endpoint& dest, const uint64_t seid,
pending_procedures.insert(std::pair<uint32_t, pfcp_procedure>(msg.get_sequence_number(), proc));
trxn_id2seq_num.insert(std::pair<uint64_t, uint32_t>(proc.trxn_id, msg.get_sequence_number()));
udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
//TTN: temporary fix to be able to work with UPF from dsTester (should be removed later)
//udp_s_allocated.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
udp_s_8805.async_send_to(reinterpret_cast<const char*>(bstream.c_str()), bstream.length(), dest);
return msg.get_sequence_number();
}
//------------------------------------------------------------------------------
......
......@@ -58,6 +58,8 @@ add_library (SMF STATIC
smf_n4.cpp
smf_n10.cpp
smf_n11.cpp
smf_event.cpp
smf_subscription.cpp
smf_msg.cpp
)
......@@ -49,6 +49,7 @@
#include "smf_n4.hpp"
#include "smf_n10.hpp"
#include "smf_n11.hpp"
#include "smf_event.hpp"
#include "pfcp.hpp"
#include "itti_msg_nx.hpp"
#include "SmContextCreatedData.h"
......@@ -126,6 +127,16 @@ scid_t smf_app::generate_smf_context_ref() {
return sm_context_ref_generator.get_uid();
}
//------------------------------------------------------------------------------
void smf_app::generate_ev_subscription_id(std::string &sub_id) {
sub_id = std::to_string(evsub_id_generator.get_uid());
}
//------------------------------------------------------------------------------
evsub_id_t smf_app::generate_ev_subscription_id() {
return evsub_id_generator.get_uid();
}
//------------------------------------------------------------------------------
bool smf_app::is_seid_n4_exist(const uint64_t &seid) const {
return bool { set_seid_n4.count(seid) > 0 };
......@@ -547,7 +558,6 @@ void smf_app::handle_pdu_session_create_sm_context_request(
oai::smf_server::model::ProblemDetails problem_details = { };
oai::smf_server::model::RefToBinaryData refToBinaryData = { };
std::string n1_sm_message, n1_sm_message_hex;
smf_n1 smf_n1_inst = { };
nas_message_t decoded_nas_msg = { };
cause_value_5gsm_e cause_n1 = { cause_value_5gsm_e::CAUSE_0_UNKNOWN };
pdu_session_type_t pdu_session_type = { .pdu_session_type =
......@@ -556,7 +566,7 @@ 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();
int decoder_rc = smf_n1_inst.decode_n1_sm_container(decoded_nas_msg,
int decoder_rc = smf_n1::get_instance().decode_n1_sm_container(decoded_nas_msg,
n1_sm_msg);
//Failed to decode, send reply to AMF with PDU Session Establishment Reject
......@@ -567,7 +577,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, 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);
......@@ -623,7 +633,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(smreq->req,
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(smreq->req,
n1_sm_message, cause_n1)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
......@@ -674,7 +684,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject including cause "#81 Invalid PTI value" (section 7.3.1 @3GPP TS 24.501)
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, 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);
......@@ -714,7 +724,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//(24.501 (section 7.4)) implementation dependent->do similar to UE: response with a 5GSM STATUS message including cause "#98 message type not compatible with protocol state."
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req,
n1_sm_message,
cause_value_5gsm_e::CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)) {
......@@ -754,7 +764,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, 24.501 cause "#27 Missing or unknown DNN"
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, 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);
......@@ -770,23 +780,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
return;
}
//Step 4. Verify the session is already existed
if (is_scid_2_smf_context(supi64, dnn, snssai, pdu_session_id)) {
//TODO: should delete the local context (including and any associated resources in the UPF and PCF) and create a new one
Logger::smf_app().warn(
"PDU Session already existed (SUPI " SUPI_64_FMT ", DNN %s, NSSAI (sst %d, sd %s), PDU Session ID %d)",
supi64, dnn.c_str(), snssai.sST, snssai.sD.c_str(), pdu_session_id);
//TODO: temporary disable this action to test with AMF
/*
//trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE, smreq->pid,
N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
return;
*/
}
//Step 5. create a context for this supi if not existed, otherwise update
//Step 4. create a context for this supi if not existed, otherwise update
std::shared_ptr<smf_context> sc = { };
if (is_supi_2_smf_context(supi64)) {
Logger::smf_app().debug("Update SMF context with SUPI " SUPI_64_FMT "",
......@@ -802,7 +796,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
set_supi_2_smf_context(supi64, sc);
}
//Step 6. Create/update context with dnn information
//Step 5. Create/update context with dnn information
std::shared_ptr<dnn_context> sd = { };
if (!sc.get()->find_dnn_context(snssai, dnn, sd)) {
......@@ -818,6 +812,16 @@ void smf_app::handle_pdu_session_create_sm_context_request(
}
}
//Step 6. if colliding with an existing SM context (session is already existed and request type is INITIAL_REQUEST)
//Delete the local context (including and any associated resources in the UPF and PCF) and create a new one
if (is_scid_2_smf_context(supi64, dnn, snssai, pdu_session_id) && (request_type.compare("INITIAL_REQUEST") == 0)) {
//remove smf_pdu_session (including all flows associated to this session)
sd.get()->remove_pdu_session(pdu_session_id);
Logger::smf_app().warn(
"PDU Session already existed (SUPI " SUPI_64_FMT ", DNN %s, NSSAI (sst %d, sd %s), PDU Session ID %d)",
supi64, dnn.c_str(), snssai.sST, snssai.sD.c_str(), pdu_session_id);
}
//Step 7. retrieve Session Management Subscription data from UDM if not available (step 4, section 4.3.2 3GPP TS 23.502)
std::string dnn_selection_mode = smreq->req.get_dnn_selection_mode();
//if the Session Management Subscription data is not available, get from configuration file or UDM
......@@ -846,7 +850,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, with cause "29 User authentication or authorization failed"
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req,
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED)) {
......@@ -1123,6 +1127,36 @@ void smf_app::trigger_pdu_session_modification(
sc.get()->handle_pdu_session_modification_network_requested(itti_msg);
}
//------------------------------------------------------------------------------
evsub_id_t smf_app::handle_event_exposure_subscription(
std::shared_ptr<itti_sbi_event_exposure_request> msg) {
Logger::smf_app().info(
"Handle an Event Exposure Subscription Request from a NF (HTTP version %d)",
msg->http_version);
// Generate a subscription ID Id and store the corresponding information in a map (subscription id, info)
evsub_id_t evsub_id = generate_ev_subscription_id();
//std::string evsubid_str = "SubId" + std::to_string(evsub_id);
std::shared_ptr<smf_subscription> ss = std::shared_ptr<smf_subscription>(
new smf_subscription());
ss.get()->sub_id = evsub_id;
if (msg->event_exposure.is_supi_is_set()){
supi64_t supi64 = smf_supi_to_u64(msg->event_exposure.get_supi());
ss.get()->supi = supi64;
}
ss.get()->notif_id = msg->event_exposure.get_notif_id();
ss.get()->notif_uri = msg->event_exposure.get_notif_uri();
std::vector<event_subscription_t> event_subscriptions = msg->event_exposure.get_event_subs();
//store subscription
for (auto i: event_subscriptions) {
ss.get()->ev_type = i.smf_event;
add_event_subscription(evsub_id, i.smf_event, ss);
}
}
//------------------------------------------------------------------------------
bool smf_app::is_supi_2_smf_context(const supi64_t &supi) const {
std::shared_lock lock(m_supi2smf_context);
......@@ -1189,6 +1223,13 @@ bool smf_app::scid_2_smf_context(const scid_t &scid,
return false;
}
//------------------------------------------------------------------------------
//void smf_app::set_evsubid_2_smf_subscription(const evsub_id_t &id,
// std::shared_ptr<smf_subscription> ss) {
// std::unique_lock lock(m_evsubid2smf_context);
// evsub_id2smf_subscription[id] = ss;
//}
//------------------------------------------------------------------------------
bool smf_app::use_local_configuration_subscription_data(
const std::string &dnn_selection_mode) {
......@@ -1497,6 +1538,7 @@ void smf_app::trigger_http_response(
nlohmann::json json_data = { };
to_json(json_data, smContextCreateError);
sm_context_response.set_json_data(json_data);
sm_context_response.set_json_format("application/problem+json");
sm_context_response.set_n1_sm_message(n1_sm_msg);
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
......@@ -1524,6 +1566,7 @@ void smf_app::trigger_http_response(
nlohmann::json json_data = { };
to_json(json_data, smContextUpdateError);
sm_context_response.set_json_data(json_data);
sm_context_response.set_json_format("application/problem+json");
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
......@@ -1552,6 +1595,7 @@ void smf_app::trigger_http_response(
nlohmann::json json_data = { };
to_json(json_data, smContextUpdateError);
sm_context_response.set_json_data(json_data);
sm_context_response.set_json_format("application/problem+json");
sm_context_response.set_n1_sm_message(n1_sm_msg);
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
......@@ -1628,5 +1672,41 @@ void smf_app::trigger_http_response(const uint32_t &http_code,
//TODO:
}
}
}
//---------------------------------------------------------------------------------------------
void smf_app::add_event_subscription(evsub_id_t sub_id, smf_event_t ev, std::shared_ptr<smf_subscription> ss) {
Logger::smf_app().debug("Add an Event subscription (Sub ID %d, Event %d)", sub_id, (uint8_t) ev);
std::unique_lock lock(m_smf_event_subscriptions);
smf_event_subscriptions.emplace(std::make_pair(sub_id,ev), ss);
}
//---------------------------------------------------------------------------------------------
void smf_app::get_ee_subscriptions(smf_event_t ev, std::vector<std::shared_ptr<smf_subscription>> &subscriptions) {
for (auto const& i : smf_event_subscriptions) {
if ((uint8_t)std::get<1> (i.first) == (uint8_t) ev){
Logger::smf_app().debug("Found an event subscription (Event ID %d, Event %d)", (uint8_t) std::get<0>(i.first), (uint8_t) ev);
subscriptions.push_back(i.second);
}
}
}
//---------------------------------------------------------------------------------------------
void smf_app::get_ee_subscriptions(evsub_id_t sub_id, std::vector<std::shared_ptr<smf_subscription>> &subscriptions) {
for (auto const& i : smf_event_subscriptions) {
if (i.first.first == sub_id){
subscriptions.push_back(i.second);
}
}
}
//---------------------------------------------------------------------------------------------
void smf_app::get_ee_subscriptions(smf_event_t ev, supi64_t supi, pdu_session_id_t pdu_session_id, std::vector<std::shared_ptr<smf_subscription>> &subscriptions) {
for (auto const& i : smf_event_subscriptions) {
if ((i.first.second == ev) && (i.second->supi == supi) && (i.second->pdu_session_id == pdu_session_id)){
subscriptions.push_back(i.second);
}
}
}
......@@ -45,7 +45,9 @@
#include "3gpp_29.502.h"
#include "itti_msg_n4.hpp"
#include "itti_msg_n11.hpp"
#include "itti_msg_sbi.hpp"
#include "smf_context.hpp"
#include "smf_subscription.hpp"
#include "smf_pco.hpp"
#include "smf_msg.hpp"
#include "SmContextCreateData.h"
......@@ -89,12 +91,14 @@ class smf_context_ref {
nssai = { };
dnn = "";
pdu_session_id = 0;
amf_status_uri = "";
}
supi_t supi;
std::string dnn;
pdu_session_id_t pdu_session_id;
snssai_t nssai;
std::string amf_status_uri;
};
class smf_app {
......@@ -114,9 +118,14 @@ class smf_app {
mutable std::shared_mutex m_supi2smf_context;
util::uint_generator<uint32_t> sm_context_ref_generator;
std::map<scid_t, std::shared_ptr<smf_context_ref>> scid2smf_context;
util::uint_generator<uint32_t> evsub_id_generator;
std::map<std::pair<evsub_id_t, smf_event_t>, std::shared_ptr<smf_subscription>> smf_event_subscriptions;
mutable std::shared_mutex m_scid2smf_context;
mutable std::shared_mutex m_smf_event_subscriptions;
//Store promise IDs for Create/Update session
mutable std::shared_mutex m_sm_context_create_promises;
mutable std::shared_mutex m_sm_context_update_promises;
......@@ -129,6 +138,7 @@ class smf_app {
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
* @param [const smf_config &cfg] cfg
......@@ -370,6 +380,21 @@ class smf_app {
*/
scid_t generate_smf_context_ref();
/*
* Generate an Event Exposure Subscription ID in a form of string
* @param [std::string &] sub_id: Store the generated reference
* @return void
*/
void generate_ev_subscription_id(std::string &sub_id);
/*
* Generate an Event Exposure Subscription ID
* @param [void]
* @return the generated reference
*/
evsub_id_t generate_ev_subscription_id();
/*
* Set the association betwen a SMF Context Reference and a SMF Context
* @param [const scid_t &] id: SMF Context Reference Id
......@@ -437,6 +462,13 @@ class smf_app {
void handle_pdu_session_release_sm_context_request(
std::shared_ptr<itti_n11_release_sm_context_request> smreq);
/*
* Handle Event Exposure Msg from AMF
* @param [std::shared_ptr<itti_sbi_event_exposure_request>&] Request message
* @return [evsub_id_t] ID of the created subscription
*/
evsub_id_t handle_event_exposure_subscription(
std::shared_ptr<itti_sbi_event_exposure_request> msg);
/*
* Trigger pdu session modification
* @param [const supi_t &] supi
......@@ -650,6 +682,42 @@ class smf_app {
*/
void trigger_http_response(const uint32_t &http_code, uint32_t &promise_id,
uint8_t msg_type);
/*
* Add an Event Subscription to the list
* @param [const evsub_id_t&] sub_id: Subscription ID
* @param [smf_event_t] ev: Event type
* @param [std::shared_ptr<smf_subscription>] ss: a shared pointer stored information of the subscription
* @return void
*/
void add_event_subscription(evsub_id_t sub_id, smf_event_t ev, std::shared_ptr<smf_subscription> ss);
/*
* Get a list of subscription associated with a particular event
* @param [smf_event_t] ev: Event type
* @param [std::vector<std::shared_ptr<smf_subscription>>&] subscriptions: store the list of the subscription associated with this event type
* @return void
*/
void get_ee_subscriptions(smf_event_t ev, std::vector<std::shared_ptr<smf_subscription>> &subscriptions);
/*
* Get a list of subscription associated with a particular event
* @param [evsub_id_t] sub_id: Subscription ID
* @param [std::vector<std::shared_ptr<smf_subscription>>&] subscriptions: store the list of the subscription associated with this event type
* @return void
*/
void get_ee_subscriptions(evsub_id_t sub_id, std::vector<std::shared_ptr<smf_subscription>> &subscriptions);
/*
* Get a list of subscription associated with a particular event
* @param [smf_event_t] ev: Event type
* @param [supi64_t] supi: SUPI
* @param [pdu_session_id_t] pdu_session_id: PDU Session ID
* @param [std::vector<std::shared_ptr<smf_subscription>>&] subscriptions: store the list of the subscription associated with this event type
* @return void
*/
void get_ee_subscriptions(smf_event_t ev, supi64_t supi, pdu_session_id_t pdu_session_id, std::vector<std::shared_ptr<smf_subscription>> &subscriptions);
};
}
#include "smf_config.hpp"
......
......@@ -46,6 +46,7 @@
#include "3gpp_24.501.h"
#include "SmContextCreatedData.h"
#include "smf_pfcp_association.hpp"
#include "smf_event.hpp"
extern "C" {
#include "Ngap_PDUSessionResourceSetupResponseTransfer.h"
......@@ -171,12 +172,12 @@ void smf_pdu_session::get_paa(paa_t &paa) {
void smf_pdu_session::add_qos_flow(const smf_qos_flow &flow) {
if ((flow.qfi.qfi >= QOS_FLOW_IDENTIFIER_FIRST )
and (flow.qfi.qfi <= QOS_FLOW_IDENTIFIER_LAST )) {
Logger::smf_app().trace("QoS Flow (flow Id %d) has been added successfully",
flow.qfi.qfi);
std::unique_lock lock(m_pdu_session_mutex);
qos_flows.erase(flow.qfi.qfi);
qos_flows.insert(
std::pair<uint8_t, smf_qos_flow>((uint8_t) flow.qfi.qfi, flow));
Logger::smf_app().trace("QoS Flow (flow Id %d) has been added successfully",
flow.qfi.qfi);
} else {
Logger::smf_app().error("Failed to add QoS flow (flow Id %d), invalid QFI",
flow.qfi.qfi);
......@@ -186,7 +187,7 @@ void smf_pdu_session::add_qos_flow(const smf_qos_flow &flow) {
//------------------------------------------------------------------------------
bool smf_pdu_session::get_qos_flow(const pfcp::pdr_id_t &pdr_id,
smf_qos_flow &q) {
//std::shared_lock lock(m_pdu_session_mutex);
std::shared_lock lock(m_pdu_session_mutex);
for (auto it : qos_flows) {
if (it.second.pdr_id_ul.rule_id == pdr_id.rule_id) {
q = it.second;
......@@ -203,7 +204,7 @@ bool smf_pdu_session::get_qos_flow(const pfcp::pdr_id_t &pdr_id,
//------------------------------------------------------------------------------
bool smf_pdu_session::get_qos_flow(const pfcp::far_id_t &far_id,
smf_qos_flow &q) {
//std::shared_lock lock(m_pdu_session_mutex);
std::shared_lock lock(m_pdu_session_mutex);
for (auto it : qos_flows) {
if ((it.second.far_id_ul.first)
&& (it.second.far_id_ul.second.far_id == far_id.far_id)) {
......@@ -221,7 +222,7 @@ bool smf_pdu_session::get_qos_flow(const pfcp::far_id_t &far_id,
//------------------------------------------------------------------------------
bool smf_pdu_session::get_qos_flow(const pfcp::qfi_t &qfi, smf_qos_flow &q) {
//std::shared_lock lock(m_pdu_session_mutex);
std::shared_lock lock(m_pdu_session_mutex);
for (auto it : qos_flows) {
if (it.second.qfi == qfi) {
q = it.second;
......@@ -244,6 +245,7 @@ bool smf_pdu_session::get_default_qos_flow(smf_qos_flow &flow) {
//------------------------------------------------------------------------------
void smf_pdu_session::get_qos_flows(std::vector<smf_qos_flow> &flows) {
std::shared_lock lock(m_pdu_session_mutex);
flows.clear();
for (auto it : qos_flows) {
......@@ -267,20 +269,30 @@ bool smf_pdu_session::find_qos_flow(const pfcp::pdr_id_t &pdr_id,
//------------------------------------------------------------------------------
void smf_pdu_session::remove_qos_flow(const pfcp::qfi_t &qfi) {
smf_qos_flow &flow = qos_flows[qfi.qfi];
std::unique_lock lock(m_pdu_session_mutex);
smf_qos_flow &flow = qos_flows[qfi.qfi];
flow.deallocate_ressources();
qos_flows.erase(qfi.qfi);
}
//------------------------------------------------------------------------------
void smf_pdu_session::remove_qos_flow(smf_qos_flow &flow) {
pfcp::qfi_t qfi = { .qfi = flow.qfi.qfi };
std::unique_lock lock(m_pdu_session_mutex);
pfcp::qfi_t qfi = { .qfi = flow.qfi.qfi };
flow.deallocate_ressources();
qos_flows.erase(qfi.qfi);
}
//------------------------------------------------------------------------------
void smf_pdu_session::remove_qos_flows() {
std::unique_lock lock(m_pdu_session_mutex);
for (std::map<uint8_t, smf_qos_flow>::iterator it = qos_flows.begin();
it != qos_flows.end(); ++it) {
it->second.deallocate_ressources();
}
qos_flows.clear();
}
//------------------------------------------------------------------------------
void smf_pdu_session::deallocate_ressources(const std::string &dnn) {
......@@ -383,11 +395,13 @@ void smf_pdu_session::set_pdu_session_status(
Logger::smf_app().info(
"Set PDU Session Status to %s",
pdu_session_status_e2str[static_cast<int>(status)].c_str());
std::unique_lock lock(m_pdu_session_mutex);
pdu_session_status = status;
}
//------------------------------------------------------------------------------
pdu_session_status_e smf_pdu_session::get_pdu_session_status() const {
std::shared_lock lock(m_pdu_session_mutex);
return pdu_session_status;
}
......@@ -395,11 +409,13 @@ pdu_session_status_e smf_pdu_session::get_pdu_session_status() const {
void smf_pdu_session::set_upCnx_state(const upCnx_state_e &state) {
Logger::smf_app().info("Set upCnxState to %s",
upCnx_state_e2str[static_cast<int>(state)].c_str());
std::unique_lock lock(m_pdu_session_mutex);
upCnx_state = state;
}
//------------------------------------------------------------------------------
upCnx_state_e smf_pdu_session::get_upCnx_state() const {
std::shared_lock lock(m_pdu_session_mutex);
return upCnx_state;
}
......@@ -457,13 +473,15 @@ bool smf_pdu_session::get_qos_rule(const uint8_t rule_id,
//------------------------------------------------------------------------------
void smf_pdu_session::update_qos_rule(const QOSRulesIE &qos_rule) {
std::unique_lock lock(m_pdu_session_mutex, std::defer_lock); // Do not lock it first
Logger::smf_app().info("Update QoS Rule with Rule Id %d",
(uint8_t) qos_rule.qosruleidentifer);
uint8_t rule_id = qos_rule.qosruleidentifer;
if ((rule_id >= QOS_RULE_IDENTIFIER_FIRST )
and (rule_id <= QOS_RULE_IDENTIFIER_LAST )) {
std::unique_lock lock(m_pdu_session_mutex);
if (qos_rules.count(rule_id) > 0) {
lock.lock(); // Lock it here
qos_rules.erase(rule_id);
qos_rules.insert(std::pair<uint8_t, QOSRulesIE>(rule_id, qos_rule));
//marked to be synchronised with UE
......@@ -482,11 +500,11 @@ void smf_pdu_session::update_qos_rule(const QOSRulesIE &qos_rule) {
//------------------------------------------------------------------------------
void smf_pdu_session::mark_qos_rule_to_be_synchronised(const uint8_t rule_id) {
std::unique_lock lock(m_pdu_session_mutex, std::defer_lock); // Do not lock it first
if ((rule_id >= QOS_RULE_IDENTIFIER_FIRST )
and (rule_id <= QOS_RULE_IDENTIFIER_LAST )) {
std::unique_lock lock(m_pdu_session_mutex);
if (qos_rules.count(rule_id) > 0) {
lock.lock(); // Lock it here
qos_rules_to_be_synchronised.push_back(rule_id);
Logger::smf_app().trace(
"smf_pdu_session::mark_qos_rule_to_be_synchronised(%d) success",
......@@ -506,17 +524,18 @@ void smf_pdu_session::mark_qos_rule_to_be_synchronised(const uint8_t rule_id) {
//------------------------------------------------------------------------------
void smf_pdu_session::add_qos_rule(const QOSRulesIE &qos_rule) {
std::unique_lock lock(m_pdu_session_mutex, std::defer_lock); // Do not lock it first
Logger::smf_app().info("Add QoS Rule with Rule Id %d",
(uint8_t) qos_rule.qosruleidentifer);
uint8_t rule_id = qos_rule.qosruleidentifer;
if ((rule_id >= QOS_RULE_IDENTIFIER_FIRST )
and (rule_id <= QOS_RULE_IDENTIFIER_LAST )) {
std::unique_lock lock(m_pdu_session_mutex);
if (qos_rules.count(rule_id) > 0) {
Logger::smf_app().error("Failed to add rule (Id %d), rule existed",
rule_id);
} else {
lock.lock(); // Lock it here
qos_rules.insert(std::pair<uint8_t, QOSRulesIE>(rule_id, qos_rule));
Logger::smf_app().trace("Rule (Id %d) has been added successfully",
rule_id);
......@@ -532,7 +551,7 @@ void smf_pdu_session::add_qos_rule(const QOSRulesIE &qos_rule) {
void session_management_subscription::insert_dnn_configuration(
const std::string &dnn,
std::shared_ptr<dnn_configuration_t> &dnn_configuration) {
std::unique_lock lock(m_dnn_configuration_mutex);
std::unique_lock lock(m_mutex);
dnn_configurations.insert(
std::pair<std::string, std::shared_ptr<dnn_configuration_t>>(
dnn, dnn_configuration));
......@@ -543,7 +562,7 @@ void session_management_subscription::find_dnn_configuration(
const std::string &dnn,
std::shared_ptr<dnn_configuration_t> &dnn_configuration) const {
Logger::smf_app().info("Find DNN configuration with DNN %s", dnn.c_str());
std::shared_lock lock(m_dnn_configuration_mutex);
std::shared_lock lock(m_mutex);
if (dnn_configurations.count(dnn) > 0) {
dnn_configuration = dnn_configurations.at(dnn);
}
......@@ -552,7 +571,7 @@ void session_management_subscription::find_dnn_configuration(
//------------------------------------------------------------------------------
bool session_management_subscription::dnn_configuration(
const std::string &dnn) const {
std::shared_lock lock(m_dnn_configuration_mutex);
std::shared_lock lock(m_mutex);
if (dnn_configurations.count(dnn) > 0) {
return true;
} else {
......@@ -746,9 +765,8 @@ void smf_context::handle_itti_msg(
// Create N2 SM Information: PDU Session Resource Setup Request Transfer IE
//N2 SM Information
smf_n2 smf_n2_inst = { };
std::string n2_sm_info, n2_sm_info_hex;
smf_n2_inst.create_n2_pdu_session_resource_setup_request_transfer(
smf_n2::get_instance().create_n2_pdu_session_resource_setup_request_transfer(
session_report_msg, n2_sm_info_type_e::PDU_RES_SETUP_REQ,
n2_sm_info);
......@@ -1149,7 +1167,6 @@ void smf_context::handle_pdu_session_create_sm_context_request(
oai::smf_server::model::ProblemDetails problem_details = { };
oai::smf_server::model::RefToBinaryData refToBinaryData = { };
std::string n1_sm_message, n1_sm_msg_hex;
smf_n1 smf_n1_inst = { };
bool request_accepted = true;
//Step 1. get necessary information
......@@ -1170,7 +1187,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req,
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED)) {
......@@ -1243,15 +1260,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sp.get()->amf_id = smreq->req.get_serving_nf_id(); //amf id
sd->insert_pdu_session(sp);
} else {
Logger::smf_app().debug("PDU session is already existed!");
//TODO: temporary disable this action to test with AMF
/*
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE, smreq->pid,
N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
return;
*/
Logger::smf_app().warn("PDU session is already existed!");
}
//TODO: if "Integrity Protection is required", check UE Integrity Protection Maximum Data Rate
......@@ -1346,7 +1355,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, 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);
......@@ -1375,7 +1384,18 @@ void smf_context::handle_pdu_session_create_sm_context_request(
//TODO:
}
//Step 5 (4.3.2.2.1 TS 23.502): Trigger SMF APP to send response to SMF-HTTP-API-SERVER
//Store AMF callback URI and subscribe to the status notification: AMF will be notified when SM context changes
std::shared_ptr<smf_context_ref> scf = { };
if (smf_app_inst->is_scid_2_smf_context(smreq->scid)) {
scf = smf_app_inst->scid_2_smf_context(smreq->scid);
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!", smreq->scid);
//TODO: return;
}
scf.get()->amf_status_uri = smreq->req.get_sm_context_status_uri();
//Trigger SMF APP to send response to SMF-HTTP-API-SERVER (Step 5, 4.3.2.2.1 TS 23.502)
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 =
......@@ -1463,7 +1483,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (sm_context_resp->res.get_cause() == NO_RESOURCES_AVAILABLE) {
cause_n1 = cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES;
}
smf_n1_inst.create_n1_pdu_session_establishment_reject(sm_context_resp_pending->res,
smf_n1::get_instance().create_n1_pdu_session_establishment_reject(sm_context_resp_pending->res,
n1_sm_message, cause_n1);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
sm_context_resp_pending->res.set_n1_sm_message(n1_sm_msg_hex);
......@@ -1512,8 +1532,6 @@ void smf_context::handle_pdu_session_update_sm_context_request(
"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 smf_n1_inst = { };
smf_n2 smf_n2_inst = { };
oai::smf_server::model::SmContextUpdateError smContextUpdateError = { };
oai::smf_server::model::SmContextUpdatedData smContextUpdatedData = { };
oai::smf_server::model::ProblemDetails problem_details = { };
......@@ -1575,7 +1593,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
n1_sm_msg = sm_context_req_msg.get_n1_sm_message();
memset(&decoded_nas_msg, 0, sizeof(nas_message_t));
int decoder_rc = smf_n1_inst.decode_n1_sm_container(decoded_nas_msg,
int decoder_rc = smf_n1::get_instance().decode_n1_sm_container(decoded_nas_msg,
n1_sm_msg);
if (decoder_rc != RETURNok) {
//error, send reply to AMF with error code!!
......@@ -1803,10 +1821,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
std::string n1_sm_msg_to_be_created, n1_sm_msg_hex_to_be_created;
std::string n2_sm_info_to_be_created, n2_sm_info_hex_to_be_created;
//N1 SM (PDU Session Modification Command)
if (not smf_n1_inst.create_n1_pdu_session_modification_command(
if (not smf_n1::get_instance().create_n1_pdu_session_modification_command(
n11_sm_context_resp->res, n1_sm_msg_to_be_created, cause_value_5gsm_e::CAUSE_0_UNKNOWN) or //TODO: need cause?
//N2 SM (PDU Session Resource Modify Request Transfer IE)
not smf_n2_inst.create_n2_pdu_session_resource_modify_request_transfer(
not smf_n2::get_instance().create_n2_pdu_session_resource_modify_request_transfer(
n11_sm_context_resp->res, n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info_to_be_created)) {
smf_app_inst->trigger_http_response(
......@@ -1967,7 +1985,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
if (smf_n1_inst.create_n1_pdu_session_release_reject(
if (smf_n1::get_instance().create_n1_pdu_session_release_reject(
sm_context_req_msg, 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);
......@@ -2057,6 +2075,20 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//don't need to create a procedure to update UPF
//TODO: SMF invokes Nsmf_PDUSession_SMContextStatusNotify to notify AMF that the SM context for this PDU Session is released
scid_t scid = { };
try {
scid = std::stoi(smreq->scid);
} catch (const std::exception &err) {
Logger::smf_app().warn(
"Received a PDU Session Update SM Context Request, couldn't retrieve the corresponding SMF context, ignore message!");
//TODO: return;
}
smf_event::get_instance().trigger_sm_context_status_notification(scid, static_cast<uint32_t>(sm_context_status_e::SM_CONTEXT_STATUS_RELEASED), smreq->http_version);
//Get SUPI
supi64_t supi64 = smf_supi_to_u64(sm_context_req_msg.get_supi());
//Trigger PDU Session Release event notification
smf_event::get_instance().trigger_ee_pdu_session_release(supi64, sm_context_req_msg.get_pdu_session_id(), smreq->http_version);
//TODO: if dynamic PCC applied, SMF invokes an SM Policy Association Termination
//TODO: SMF unsubscribes from Session Management Subscription data changes notification from UDM by invoking Numd_SDM_Unsubscribe
if (sd.get()->get_number_pdu_sessions() == 0) {
......@@ -2118,7 +2150,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Ngap_PDUSessionResourceSetupResponseTransfer
std::shared_ptr<Ngap_PDUSessionResourceSetupResponseTransfer_t> decoded_msg =
std::make_shared<Ngap_PDUSessionResourceSetupResponseTransfer_t>();
int decode_status = smf_n2_inst.decode_n2_sm_information(
int decode_status = smf_n2::get_instance().decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
//error, send error to AMF
......@@ -2131,7 +2163,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//24.501: response with a 5GSM STATUS message including cause "#95 Semantically incorrect message"
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
sm_context_req_msg, 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); //TODO: need N1SM?
......@@ -2197,7 +2229,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Ngap_PDUSessionResourceSetupUnsuccessfulTransfer
std::shared_ptr<Ngap_PDUSessionResourceSetupUnsuccessfulTransfer_t> decoded_msg =
std::make_shared<Ngap_PDUSessionResourceSetupUnsuccessfulTransfer_t>();
int decode_status = smf_n2_inst.decode_n2_sm_information(
int decode_status = smf_n2::get_instance().decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
......@@ -2221,7 +2253,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, 24.501 cause "#26 Insufficient resources"
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
smreq->req, 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);
......@@ -2249,7 +2281,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Ngap_PDUSessionResourceModifyResponseTransfer
std::shared_ptr<Ngap_PDUSessionResourceModifyResponseTransfer_t> decoded_msg =
std::make_shared<Ngap_PDUSessionResourceModifyResponseTransfer_t>();
int decode_status = smf_n2_inst.decode_n2_sm_information(
int decode_status = smf_n2::get_instance().decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
......@@ -2321,7 +2353,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//Ngap_PDUSessionResourceReleaseResponseTransfer
std::shared_ptr<Ngap_PDUSessionResourceReleaseResponseTransfer_t> decoded_msg =
std::make_shared<Ngap_PDUSessionResourceReleaseResponseTransfer_t>();
int decode_status = smf_n2_inst.decode_n2_sm_information(
int decode_status = smf_n2::get_instance().decode_n2_sm_information(
decoded_msg, n2_sm_information);
if (decode_status == RETURNerror) {
Logger::smf_app().warn(
......@@ -2379,7 +2411,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
// Create N2 SM Information: PDU Session Resource Setup Request Transfer IE
//N2 SM Information
smf_n2_inst.create_n2_pdu_session_resource_setup_request_transfer(
smf_n2::get_instance().create_n2_pdu_session_resource_setup_request_transfer(
sm_context_resp_pending->res, n2_sm_info_type_e::PDU_RES_SETUP_REQ,
n2_sm_info);
......@@ -2454,7 +2486,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
if (smf_n1_inst.create_n1_pdu_session_establishment_reject(
if (smf_n1::get_instance().create_n1_pdu_session_establishment_reject(
sm_context_req_msg, 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);
......@@ -2586,8 +2618,6 @@ void smf_context::handle_pdu_session_modification_network_requested(
Logger::smf_app().info(
"Handle a PDU Session Modification Request (SMF-Requested)");
smf_n1 smf_n1_inst = { };
smf_n2 smf_n2_inst = { };
oai::smf_server::model::SmContextUpdateError smContextUpdateError = { };
oai::smf_server::model::SmContextUpdatedData smContextUpdatedData = { };
oai::smf_server::model::ProblemDetails problem_details = { };
......@@ -2642,14 +2672,14 @@ void smf_context::handle_pdu_session_modification_network_requested(
//TODO: handle encode N1, N2 failure
//N1: PDU_SESSION_MODIFICATION_COMMAND
smf_n1_inst.create_n1_pdu_session_modification_command(itti_msg->msg,
smf_n1::get_instance().create_n1_pdu_session_modification_command(itti_msg->msg,
n1_sm_msg,
cause_value_5gsm_e::CAUSE_0_UNKNOWN);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
itti_msg->msg.set_n1_sm_message(n1_sm_msg_hex);
//N2: PDU Session Resource Modify Response Transfer
smf_n2_inst.create_n2_pdu_session_resource_modify_request_transfer(itti_msg->msg,
smf_n2::get_instance().create_n2_pdu_session_resource_modify_request_transfer(itti_msg->msg,
n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info);
......@@ -2835,6 +2865,38 @@ bool smf_context::find_pdu_session(const pfcp::pdr_id_t &pdr_id,
return false;
}
//---------------------------------------------------------------------------------------------
void smf_context::send_sm_context_status_notification(scid_t scid,
uint32_t status, uint8_t http_version) {
Logger::smf_app().debug("Send request to N11 to triger SM Context Status Notification, SMF Context ID " SCID_FMT " ", scid);
std::shared_ptr<smf_context_ref> scf = { };
if (smf_app_inst->is_scid_2_smf_context(scid)) {
scf = smf_app_inst->scid_2_smf_context(scid);
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!", scid);
//TODO:
return;
}
//Send request to N11 to trigger the notification
Logger::smf_app().debug(
"Send ITTI msg to SMF N11 to trigger the status notification");
std::shared_ptr<itti_n11_notify_sm_context_status> itti_msg = std::make_shared
< itti_n11_notify_sm_context_status > (TASK_SMF_APP, TASK_SMF_N11);
itti_msg->scid = scid;
itti_msg->sm_context_status = sm_context_status_e2str[status];
itti_msg->amf_status_uri = scf.get()->amf_status_uri;
itti_msg->http_version = http_version;
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_N11",
itti_msg->get_msg_name());
}
}
//------------------------------------------------------------------------------
bool dnn_context::find_pdu_session(
const uint32_t pdu_session_id,
......@@ -2856,6 +2918,19 @@ void dnn_context::insert_pdu_session(std::shared_ptr<smf_pdu_session> &sp) {
pdu_sessions.push_back(sp);
}
//------------------------------------------------------------------------------
bool dnn_context::remove_pdu_session(const uint32_t pdu_session_id) {
std::unique_lock lock(m_context);
for (auto it = pdu_sessions.begin(); it != pdu_sessions.end(); ++it) {
if (pdu_session_id == (*it).get()->pdu_session_id) {
(*it).get()->remove_qos_flows();
(*it).get()->clear();
pdu_sessions.erase(it);
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
size_t dnn_context::get_number_pdu_sessions() const {
std::shared_lock lock(m_context);
......
......@@ -233,6 +233,12 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
*/
void remove_qos_flow(smf_qos_flow &flow);
/*
* Remove all QoS flow associated with this PDU Session
* @return void
*/
void remove_qos_flows();
/*
* Set current status of PDU Session
* @param [const pdu_session_status_e &] status: status to be set
......@@ -428,7 +434,7 @@ 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
// Shared lock
mutable std::shared_mutex m_pdu_session_mutex;
};
......@@ -439,7 +445,7 @@ class session_management_subscription {
:
single_nssai(snssai),
dnn_configurations(),
m_dnn_configuration_mutex() {
m_mutex() {
}
/*
......@@ -472,8 +478,9 @@ class session_management_subscription {
private:
snssai_t single_nssai;
std::map<std::string, std::shared_ptr<dnn_configuration_t>> dnn_configurations; //dnn <->dnn_configuration
// Recursive lock
mutable std::shared_mutex m_dnn_configuration_mutex;
// Shared lock
mutable std::shared_mutex m_mutex;
};
/*
......@@ -516,6 +523,14 @@ class dnn_context {
*/
void insert_pdu_session(std::shared_ptr<smf_pdu_session> &sp);
/*
* Delete a PDU Session identified by its ID
* @param [const uint32_t] pdu_session_id
* @return bool: return true if the pdu session is deleted, otherwise, return false
*/
bool remove_pdu_session(const uint32_t pdu_session_id);
/*
* Get number of pdu sessions associated with this context (dnn and Nssai)
* @param void
......@@ -808,6 +823,15 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
std::shared_ptr<dnn_context> &sd,
std::shared_ptr<smf_pdu_session> &sp);
/*
* Send ITTI msg to N11 to trigger the SM Context Status Notification to AMF
* @param [scid_t] scid: SMF Context ID
* @param [uint32_t] status: Updated status
* @param [uint8_t] http_version: HTTP version
* @return void
*/
void send_sm_context_status_notification(scid_t scid, uint32_t status, uint8_t http_version);
private:
std::vector<std::shared_ptr<dnn_context>> dnns;
std::vector<std::shared_ptr<smf_procedure>> pending_procedures;
......
/*
* 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
*/
/*! \file smf_event.cpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2019
\email: tien-thinh.nguyen@eurecom.fr
*/
#include "smf_event.hpp"
#include "smf_subscription.hpp"
#include "smf_app.hpp"
#include "itti.hpp"
using namespace smf;
extern smf::smf_app *smf_app_inst;
extern itti_mw *itti_inst;
smf_event::smf_event() {
//bind signal to slot type
bind();
}
//------------------------------------------------------------------------------
void smf_event::bind() {
//by default, subscribe to the events
subscribe_sm_context_status_notification(
boost::bind(&smf_event::send_sm_context_status_notification, this, _1, _1,
_1));
subscribe_ee_pdu_session_release(
boost::bind(&smf_event::send_ee_pdu_session_release, this, _1, _1, _1));
}
//------------------------------------------------------------------------------
boost::signals2::connection smf_event::subscribe_sm_context_status_notification(
const sm_context_status_sig_t::slot_type &context_status_st) {
return sm_context_status_sig.connect(context_status_st);
}
//------------------------------------------------------------------------------
void smf_event::trigger_sm_context_status_notification(scid_t scid,
uint8_t status,
uint8_t http_version) {
sm_context_status_sig(scid, status, http_version);
}
//------------------------------------------------------------------------------
void smf_event::send_sm_context_status_notification(scid_t scid,
uint8_t status,
uint8_t http_version) {
Logger::smf_app().debug("Send request to N11 to triger SM Context Status Notification to AMF, SMF Context ID " SCID_FMT " ", scid);
std::shared_ptr<smf_context_ref> scf = { };
if (smf_app_inst->is_scid_2_smf_context(scid)) {
scf = smf_app_inst->scid_2_smf_context(scid);
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!", scid);
//TODO:
return;
}
//Send request to N11 to trigger the notification
Logger::smf_app().debug(
"Send ITTI msg to SMF N11 to trigger the status notification");
std::shared_ptr<itti_n11_notify_sm_context_status> itti_msg = std::make_shared
< itti_n11_notify_sm_context_status > (TASK_SMF_APP, TASK_SMF_N11);
itti_msg->scid = scid;
itti_msg->sm_context_status = sm_context_status_e2str[status];
itti_msg->amf_status_uri = scf.get()->amf_status_uri;
itti_msg->http_version = http_version;
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_N11",
itti_msg->get_msg_name());
}
}
//------------------------------------------------------------------------------
boost::signals2::connection smf_event::subscribe_ee_pdu_session_release(
const ee_pdu_session_release_sig_t::slot_type &pdu_session_release_st) {
return pdu_session_release_sig.connect(pdu_session_release_st);
}
//------------------------------------------------------------------------------
void smf_event::trigger_ee_pdu_session_release(supi64_t supi,
pdu_session_id_t pdu_session_id,
uint8_t http_version) {
Logger::smf_app().debug("Trigger PDU Session Release event (Event Exposure) notification");
pdu_session_release_sig(supi, pdu_session_id, http_version);
}
//------------------------------------------------------------------------------
void smf_event::send_ee_pdu_session_release(supi64_t supi,
pdu_session_id_t pdu_session_id,
uint8_t http_version) {
Logger::smf_app().debug("Send request to N11 to triger PDU Session Release Notification (Event Exposure), SUPI " SUPI_64_FMT " , PDU Session ID %d, HTTP version %d", supi, pdu_session_id, http_version);
std::vector < std::shared_ptr < smf_subscription >> subscriptions = {};
smf_app_inst->get_ee_subscriptions(smf_event_t::SMF_EVENT_PDU_SES_REL, subscriptions);
if (subscriptions.size() > 0) {
//Send request to N11 to trigger the notification to the subscribed event
Logger::smf_app().debug(
"Send ITTI msg to SMF N11 to trigger the event notification");
std::shared_ptr<itti_n11_notify_subscribed_event> itti_msg = std::make_shared
< itti_n11_notify_subscribed_event > (TASK_SMF_APP, TASK_SMF_N11);
for (auto i: subscriptions) {
event_notification ev_notif = { };
ev_notif.set_supi(supi);
ev_notif.set_pdu_session_id(pdu_session_id);
ev_notif.set_smf_event(smf_event_t::SMF_EVENT_PDU_SES_REL);
ev_notif.set_supi(supi);
ev_notif.set_notif_uri(i.get()->notif_uri);
ev_notif.set_notif_id(i.get()->notif_id);
itti_msg->event_notifs.push_back(ev_notif);
}
itti_msg->http_version = http_version;
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_N11",
itti_msg->get_msg_name());
}
} else {
Logger::smf_app().debug("No subscription available for this event");
}
}
/*
* 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
*/
/*! \file smf_event.hpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2019
\email: tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_SMF_EVENT_HPP_SEEN
#define FILE_SMF_EVENT_HPP_SEEN
#include <boost/signals2.hpp>
#include "smf.h"
#include "3gpp_24.007.h"
namespace smf {
typedef boost::signals2::signal<void(scid_t, uint8_t, uint8_t)> sm_context_status_sig_t; //SCID, PDU Session Status, HTTP version
//For Event Exposure
typedef boost::signals2::signal<void(supi64_t, pdu_session_id_t, uint8_t)> ee_pdu_session_release_sig_t; //SUPI, PDU SessionID, HTTP version
//typedef boost::signals2::signal<void(uint32_t, uint32_t)> ee_ue_ip_address_change_sig_t; //UI IP Address, UE ID
//TODO:
//Access Type Change
//UP Path Change
//PLMN Change
//Downlink data delivery status
class smf_event {
public:
smf_event();
smf_event(smf_event const&) = delete;
void operator=(smf_event const&) = delete;
static smf_event& get_instance() {
static smf_event instance;
return instance;
}
/*
* Bind the signals to corresponding slot for each event
* @return void
*/
void bind();
/*
* Subscribe to SM Context Status Notification signal
* @param [const sm_context_status_sig_t::slot_type&] context_status_st: slot_type parameter
* @return boost::signals2::connection: the connection between the signal and the slot
*/
boost::signals2::connection subscribe_sm_context_status_notification(const sm_context_status_sig_t::slot_type& context_status_st);
/*
* Subscribe to Event Exposure Event: PDU Session Release
* @param [const ee_pdu_session_release_sig_t::slot_type&] pdu_session_release_st: slot_type parameter
* @return boost::signals2::connection: the connection between the signal and the slot
*/
boost::signals2::connection subscribe_ee_pdu_session_release(const ee_pdu_session_release_sig_t::slot_type& pdu_session_release_st);
/*
* Trigger the signal to send SM Context Status Notification to AMF
* @param [scid_t] scid: SMF Context ID
* @param [uint8_t] status: Updated status
* @param [uint8_t] http_version: HTTP version
* @return void
*/
void trigger_sm_context_status_notification(scid_t scid, uint8_t status, uint8_t http_version);
/*
* Send SM Context Status Notification to AMF
* @param [scid_t] scid: SMF Context ID
* @param [uint8_t] status: Updated status
* @param [uint8_t] http_version: HTTP version
* @return void
*/
void send_sm_context_status_notification(scid_t scid, uint8_t status, uint8_t http_version) ;
/*
* Trigger the signal to send PDU Session Release notification to subscribed NFs
* @param [supi64_t] supi: UE SUPI
* @param [pdu_session_id_t] pdu_session_id: PDU Session ID
* @param [uint8_t] http_version: HTTP version
* @return void
*/
void trigger_ee_pdu_session_release(supi64_t supi, pdu_session_id_t pdu_session_id, uint8_t http_version);
/*
* Send PDU Session Release notification to subscribed NFs
* @param [supi64_t] supi: UE SUPI
* @param [pdu_session_id_t] pdu_session_id: PDU Session ID
* @param [uint8_t] http_version: HTTP version
* @return void
*/
void send_ee_pdu_session_release(supi64_t supi, pdu_session_id_t pdu_session_id, uint8_t http_version) ;
private:
sm_context_status_sig_t sm_context_status_sig; //Signal for SM Context status update
ee_pdu_session_release_sig_t pdu_session_release_sig; //Signal for PDU session release event
bool pdu_session_release_sig_is_connected;
};
}
#endif /* FILE_SMF_EVENT_HPP_SEEN */
......@@ -280,6 +280,17 @@ void pdu_session_sm_context_response::get_json_data(nlohmann::json &data) const
data = m_json_data;
}
//-----------------------------------------------------------------------------
void pdu_session_sm_context_response::set_json_format(const std::string &format) {
m_json_format = format;
}
//-----------------------------------------------------------------------------
void pdu_session_sm_context_response::get_json_format(std::string &format) const {
format = m_json_format;
}
/*
* class: PDU Session Create SM Context Request
*/
......@@ -316,6 +327,17 @@ std::string pdu_session_create_sm_context_request::get_dnn_selection_mode() cons
return m_dnn_selection_mode;
}
//-----------------------------------------------------------------------------
void pdu_session_create_sm_context_request::set_sm_context_status_uri(
const std::string &value) {
m_sm_context_status_uri = value;
}
//-----------------------------------------------------------------------------
std::string pdu_session_create_sm_context_request::get_sm_context_status_uri() const {
return m_sm_context_status_uri;
}
/*
* class: PDU Session Create SM Context Response
*/
......@@ -569,6 +591,16 @@ void pdu_session_modification_network_requested::get_json_data(nlohmann::json &d
data = m_json_data;
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::set_json_format(const std::string &format) {
m_json_format = format;
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::get_json_format(std::string &format) const {
format = m_json_format;
}
//-----------------------------------------------------------------------------
void pdu_session_modification_network_requested::add_qos_flow_context_updated(
const qos_flow_context_updated &flow) {
......@@ -672,3 +704,197 @@ seid_t pdu_session_report_response::get_seid() const {
uint64_t pdu_session_report_response::get_trxn_id() const {
return trxn_id;
}
/*
* class: Event Exposure
*/
//-----------------------------------------------------------------------------
supi_t event_exposure_msg::get_supi() const {
return m_supi;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_supi(const supi_t &value) {
m_supi = value;
m_supi_is_set = true;
}
//-----------------------------------------------------------------------------
bool event_exposure_msg::is_supi_is_set() const {
return m_supi_is_set;
}
//-----------------------------------------------------------------------------
std::string event_exposure_msg::get_supi_prefix() const {
return m_supi_prefix;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_supi_prefix(const std::string &prefix) {
m_supi_prefix = prefix;
}
//-----------------------------------------------------------------------------
pdu_session_id_t event_exposure_msg::get_pdu_session_id() const {
return m_pdu_session_id;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_pdu_session_id(
const pdu_session_id_t value) {
m_pdu_session_id = value;
m_psi_is_set = true;
}
//-----------------------------------------------------------------------------
bool event_exposure_msg::is_psi_is_set() const {
return m_psi_is_set;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_sub_id(std::string const &value) {
m_sub_id = value;
m_sub_id_is_set = true;
}
//-----------------------------------------------------------------------------
std::string event_exposure_msg::get_sub_id() const {
return m_sub_id;
}
//-----------------------------------------------------------------------------
bool event_exposure_msg::is_sub_id_is_set() const {
return m_sub_id_is_set;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_notif_uri(std::string const &value){
m_notif_uri = value;
}
//-----------------------------------------------------------------------------
std::string event_exposure_msg::get_notif_uri() const {
return m_notif_uri;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_notif_id(std::string const &value) {
m_notif_id = value;
}
//-----------------------------------------------------------------------------
std::string event_exposure_msg::get_notif_id() const {
return m_notif_id;
}
//-----------------------------------------------------------------------------
std::vector<event_subscription_t> event_exposure_msg::get_event_subs() const {
return m_event_subs;
}
//-----------------------------------------------------------------------------
void event_exposure_msg::set_event_subs(std::vector<event_subscription_t> const &value) {
m_event_subs.clear();
for (auto it: value) {
m_event_subs.push_back(it);
}
}
/*
* class: Event Notification
*/
//-----------------------------------------------------------------------------
void event_notification::set_smf_event(const smf_event_t &ev) {
m_event = ev;
}
//-----------------------------------------------------------------------------
smf_event_t event_notification::get_smf_event() const {
return m_event;
}
//-----------------------------------------------------------------------------
supi64_t event_notification::get_supi() const {
return m_supi;
}
//-----------------------------------------------------------------------------
void event_notification::set_supi(const supi64_t &value) {
m_supi = value;
m_supi_is_set = true;
}
//-----------------------------------------------------------------------------
bool event_notification::is_supi_is_set() const {
return m_supi_is_set;
}
//-----------------------------------------------------------------------------
void event_notification::set_ad_ipv4_addr(std::string const &value) {
m_ad_ipv4_addr = value;
m_ad_ipv4_addr_is_set = true;
}
//-----------------------------------------------------------------------------
std::string event_notification::get_ad_ipv4_addr() const {
return m_ad_ipv4_addr;
}
//-----------------------------------------------------------------------------
bool event_notification::is_ad_ipv4_addr_is_set() const {
return m_ad_ipv4_addr_is_set;
}
//-----------------------------------------------------------------------------
void event_notification::set_re_ipv4_addr(std::string const &value) {
m_re_ipv4_addr = value;
m_re_ipv4_addr_is_set = true;
}
//-----------------------------------------------------------------------------
std::string event_notification::get_re_ipv4_addr() const {
return m_re_ipv4_addr;
}
//-----------------------------------------------------------------------------
bool event_notification::is_re_ipv4_addr_is_set() const {
return m_re_ipv4_addr_is_set;
}
//-----------------------------------------------------------------------------
void event_notification::set_pdu_session_id(const pdu_session_id_t value) {
m_pdu_session_id = value;
m_psi_is_set = true;
}
//-----------------------------------------------------------------------------
pdu_session_id_t event_notification::get_pdu_session_id() const {
return m_pdu_session_id;
}
//-----------------------------------------------------------------------------
bool event_notification::is_psi_is_set() const {
return m_psi_is_set;
}
//-----------------------------------------------------------------------------
void event_notification::set_notif_uri(std::string const &value){
m_notif_uri = value;
}
//-----------------------------------------------------------------------------
std::string event_notification::get_notif_uri() const {
return m_notif_uri;
}
//-----------------------------------------------------------------------------
void event_notification::set_notif_id(std::string const &value) {
m_notif_id = value;
}
//-----------------------------------------------------------------------------
std::string event_notification::get_notif_id() const {
return m_notif_id;
}
......@@ -36,6 +36,7 @@
#include "3gpp_24.007.h"
#include "3gpp_24.501.h"
#include "3gpp_29.571.h"
#include "3gpp_29.508.h"
#include "Guami.h"
#include "RefToBinaryData.h"
#include "NgRanTargetId.h"
......@@ -226,6 +227,7 @@ class pdu_session_sm_context_response : public pdu_session_msg {
pdu_session_msg(msg_type) {
m_cause = 0;
m_http_code = 0;
m_json_format = "application/json";
}
pdu_session_sm_context_response(pdu_session_msg_type_t msg_type, supi_t supi,
pdu_session_id_t pdi, std::string dnn,
......@@ -234,6 +236,7 @@ class pdu_session_sm_context_response : public pdu_session_msg {
pdu_session_msg(msg_type, supi, pdi, dnn, snssai) {
m_cause = 0;
m_http_code = 0;
m_json_format = "application/json";
}
void set_cause(const uint8_t cause);
......@@ -242,10 +245,13 @@ class pdu_session_sm_context_response : public pdu_session_msg {
uint32_t get_http_code() const;
void set_json_data(const nlohmann::json &data);
void get_json_data(nlohmann::json &data) const;
void set_json_format(const std::string &format);
void get_json_format(std::string &format) const;
private:
uint8_t m_cause;
nlohmann::json m_json_data;
std::string m_json_format;
uint32_t m_http_code;
};
......@@ -272,6 +278,8 @@ class pdu_session_create_sm_context_request :
void set_request_type(const std::string &value);
void set_dnn_selection_mode(const std::string &value);
std::string get_dnn_selection_mode() const;
void set_sm_context_status_uri(const std::string &value);
std::string get_sm_context_status_uri() const;
private:
bool m_unauthenticated_supi;
......@@ -281,6 +289,7 @@ class pdu_session_create_sm_context_request :
std::string m_presence_in_ladn;
std::string m_an_type;
std::string m_dnn_selection_mode; //SelMode
std::string m_sm_context_status_uri;
};
//---------------------------------------------------------------------------------------
......@@ -412,6 +421,15 @@ class pdu_session_release_sm_context_request : public pdu_session_msg {
}
;
private:
//From smContextReleaseData
// cause:
// ngApCause:
// 5gMmCauseValue:
// ueLocation:
//ueTimeZone:
//addUeLocation:
//vsmfReleaseOnly:
//ismfReleaseOnly:
};
//---------------------------------------------------------------------------------------
......@@ -442,6 +460,8 @@ class pdu_session_modification_network_requested :
pdu_session_modification_network_requested()
:
pdu_session_sm_context_request(PDU_SESSION_MODIFICATION_SMF_REQUESTED) {
m_json_data = {};
m_json_format = "application/json";
}
void set_amf_url(const std::string &value);
......@@ -451,6 +471,8 @@ class pdu_session_modification_network_requested :
void get_qfis(std::vector<pfcp::qfi_t> &q);
void set_json_data(const nlohmann::json &data);
void get_json_data(nlohmann::json &data) const;
void set_json_format(const std::string &format);
void get_json_format(std::string &format) 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);
......@@ -460,6 +482,7 @@ class pdu_session_modification_network_requested :
std::vector<pfcp::qfi_t> qfis;
std::map<uint8_t, qos_flow_context_updated> qos_flow_context_updateds;
nlohmann::json m_json_data;
std::string m_json_format;
};
//---------------------------------------------------------------------------------------
......@@ -491,6 +514,157 @@ class pdu_session_report_response : public pdu_session_sm_context_response {
seid_t seid;
uint64_t trxn_id;
};
class event_exposure_msg {
public:
supi_t get_supi() const;
void set_supi(const supi_t &value);
bool is_supi_is_set() const;
std::string get_supi_prefix() const;
void set_supi_prefix(const std::string &value);
void set_pdu_session_id(const pdu_session_id_t value);
pdu_session_id_t get_pdu_session_id() const;
bool is_psi_is_set() const;
void set_sub_id(std::string const &value);
std::string get_sub_id() const;
bool is_sub_id_is_set() const;
void set_notif_uri(std::string const &value);
std::string get_notif_uri() const;
void set_notif_id(std::string const &value);
std::string get_notif_id() const;
std::vector<event_subscription_t> get_event_subs() const;
void set_event_subs(std::vector<event_subscription_t> const &value);
private:
supi_t m_supi;
bool m_supi_is_set;
std::string m_supi_prefix;
pdu_session_id_t m_pdu_session_id; //m_PduSeId;
bool m_psi_is_set;
std::string m_sub_id; //m_SubId;
bool m_sub_id_is_set;
std::string m_notif_uri; //m_NotifUri;
std::string m_notif_id; //m_NotifId;
std::vector<event_subscription_t> m_event_subs; //m_EventSubs;
//NotificationMethod m_NotifMethod;
//bool m_NotifMethodIsSet;
//int32_t m_MaxReportNbr;
//bool m_MaxReportNbrIsSet;
//std::string m_Expiry;
//bool m_ExpiryIsSet;
//int32_t m_RepPeriod;
//bool m_RepPeriodIsSet;
//Guami m_Guami;
//bool m_GuamiIsSet;
//std::string m_ServiveName;
//bool m_ServiveNameIsSet;
//std::vector<std::string> m_AltNotifIpv4Addrs;
//bool m_AltNotifIpv4AddrsIsSet;
//std::vector<Ipv6Addr> m_AltNotifIpv6Addrs;
//bool m_AltNotifIpv6AddrsIsSet;
// bool m_AnyUeInd;
// bool m_AnyUeIndIsSet;
//std::string m_Gpsi;
//bool m_GpsiIsSet;
//std::string m_GroupId;
//bool m_GroupIdIsSet;
//bool m_ImmeRep;
//bool m_ImmeRepIsSet;
//std::string m_SupportedFeatures;
//bool m_SupportedFeaturesIsSet;
};
class event_notification {
public:
void set_smf_event(const smf_event_t &ev);
smf_event_t get_smf_event() const;
void set_supi(const supi64_t &supi);
supi64_t get_supi() const;
bool is_supi_is_set() const;
//m_AdIpv4Addr
void set_ad_ipv4_addr(std::string const &value);
std::string get_ad_ipv4_addr() const;
bool is_ad_ipv4_addr_is_set() const;
//m_ReIpv4Addr
void set_re_ipv4_addr(std::string const &value);
std::string get_re_ipv4_addr() const;
bool is_re_ipv4_addr_is_set() const;
void set_pdu_session_id(const pdu_session_id_t value);
pdu_session_id_t get_pdu_session_id() const;
bool is_psi_is_set() const;
void set_notif_uri(std::string const &value);
std::string get_notif_uri() const;
void set_notif_id(std::string const &value);
std::string get_notif_id() const;
private:
std::string m_notif_uri; //m_NotifUri;
std::string m_notif_id; //m_NotifId;
smf_event_t m_event; //SmfEvent
//std::string m_TimeStamp;
supi64_t m_supi;
bool m_supi_is_set;
//for a UE IP address change
std::string m_ad_ipv4_addr; //m_AdIpv4Addr
bool m_ad_ipv4_addr_is_set; //m_AdIpv4AddrIsSet;
std::string m_re_ipv4_addr; //m_ReIpv4Addr;
bool m_re_ipv4_addr_is_set; //m_ReIpv4AddrIsSet;
//for a PLMN Change
//PlmnId m_PlmnId;
//bool m_PlmnIdIsSet;
//for an access type change
//AccessType m_AccType;
//bool m_AccTypeIsSet;
//for a PDU Session Release
pdu_session_id_t m_pdu_session_id; //m_PduSeId;
bool m_psi_is_set;
//std::string m_Gpsi;
//bool m_GpsiIsSet;
//std::string m_SourceDnai;
//bool m_SourceDnaiIsSet;
//std::string m_TargetDnai;
//bool m_TargetDnaiIsSet;
//DnaiChangeType m_DnaiChgType;
//bool m_DnaiChgTypeIsSet;
//std::string m_TargetUeIpv4Addr;
//bool m_TargetUeIpv4AddrIsSet;
//std::string m_SourceUeIpv4Addr;
//bool m_SourceUeIpv4AddrIsSet;
//Ipv6Prefix m_SourceUeIpv6Prefix;
//bool m_SourceUeIpv6PrefixIsSet;
//Ipv6Prefix m_TargetUeIpv6Prefix;
//bool m_TargetUeIpv6PrefixIsSet;
//RouteToLocation m_SourceTraRouting;
//bool m_SourceTraRoutingIsSet;
//RouteToLocation m_TargetTraRouting;
//bool m_TargetTraRoutingIsSet;
//std::string m_UeMac;
//bool m_UeMacIsSet;
//Ipv6Prefix m_AdIpv6Prefix;
//bool m_AdIpv6PrefixIsSet;
//Ipv6Prefix m_ReIpv6Prefix;
//bool m_ReIpv6PrefixIsSet;
//DddStatus m_DddStatus;
//bool m_DddStatusIsSet;
//std::string m_MaxWaitTime;
//bool m_MaxWaitTimeIsSet;
};
}
#endif
......@@ -53,6 +53,12 @@ class smf_n1 {
smf_n1(smf_n1 const&) = delete;
void operator=(smf_n1 const&) = delete;
public:
static smf_n1& get_instance() {
static smf_n1 instance;
return instance;
}
/*
* Create N1 SM Container: PDU Session Establishment Accept
* @param [pdu_session_create_sm_context_response] sm_context_res: include necessary information for encoding NGAP msg
......
......@@ -94,6 +94,19 @@ void smf_n11_task(void *args_p) {
std::static_pointer_cast<itti_n11_session_report_request>(
shared_msg));
break;
case N11_SESSION_NOTIFY_SM_CONTEXT_STATUS:
smf_n11_inst->send_sm_context_status_notification(
std::static_pointer_cast<itti_n11_notify_sm_context_status>(
shared_msg));
break;
case N11_NOTIFY_SUBSCRIBED_EVENT:
smf_n11_inst->notify_subscribed_event(
std::static_pointer_cast<itti_n11_notify_subscribed_event>(
shared_msg));
break;
case TERMINATE:
if (itti_msg_terminate *terminate =
dynamic_cast<itti_msg_terminate*>(msg)) {
......@@ -437,3 +450,185 @@ void smf_n11::send_n1n2_message_transfer_request(
curl_global_cleanup();
free_wrapper((void**) &data);
}
//------------------------------------------------------------------------------
void smf_n11::send_sm_context_status_notification(
std::shared_ptr<itti_n11_notify_sm_context_status> sm_context_status) {
Logger::smf_n11().debug("Send SM Context Status Notification to AMF(HTTP version %d)", sm_context_status->http_version);
Logger::smf_n11().debug("AMF URI: %s", sm_context_status->amf_status_uri.c_str());
nlohmann::json json_data = { };
//Fill the json part
json_data["statusInfo"]["resourceStatus"] = sm_context_status->sm_context_status;
std::string body = json_data.dump();
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl = curl_easy_init();
if (curl) {
CURLcode res = { };
struct curl_slist *headers = nullptr;
//headers = curl_slist_append(headers, "charsets: utf-8");
headers = curl_slist_append(headers, "content-type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, sm_context_status->amf_status_uri.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, AMF_CURL_TIMEOUT_MS);
if (sm_context_status->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());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
res = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
Logger::smf_n11().debug("Response from AMF, Http Code: %d", httpCode);
//TODO: in case of "307 temporary redirect"
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
//-----------------------------------------------------------------------------------------------------
void smf_n11::notify_subscribed_event(
std::shared_ptr<itti_n11_notify_subscribed_event> msg) {
Logger::smf_n11().debug("Send notification for the subscribed event to the subscription");
int still_running = 0, numfds = 0, res = 0;
CURLMsg *curl_msg = nullptr;
CURL *curl = nullptr;
CURLcode return_code = {};
int http_status_code = 0, msgs_left = 0;
CURLM* m_curl_multi = nullptr;
char *url = nullptr;
std::unique_ptr<std::string> httpData(new std::string());
std::string data;
//init curl
curl_global_init(CURL_GLOBAL_ALL);
m_curl_multi = curl_multi_init();
//init header
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
std::vector<std::string> bodys = {}; //store body for all the request
for (auto i: msg->event_notifs) {
//Fill the json part
nlohmann::json json_data = {};
json_data["notifId"] = i.get_notif_id();
auto event_notifs = nlohmann::json::array();
nlohmann::json event_notif = {};
event_notif["event"] = i.get_smf_event();
event_notif["pduSeId"] = i.get_pdu_session_id();
event_notif["supi"] = std::to_string(i.get_supi());
//timestamp
std::time_t time_epoch_ntp = std::time(nullptr);
uint64_t tv_ntp = time_epoch_ntp + SECONDS_SINCE_FIRST_EPOCH;
event_notif["timeStamp"] = std::to_string(tv_ntp);
event_notifs.push_back(event_notif);
json_data["eventNotifs"] = event_notifs;
std::string body = json_data.dump();
bodys.push_back(body);
}
int index = 0;
//create and add an easy handle to a multi curl request
for (auto i: msg->event_notifs) {
CURL *curl = curl_easy_init();
if (curl){
std::string url = i.get_notif_uri() ;
Logger::smf_n11().debug("Send notification to NF with URI: %s", url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str() );
curl_easy_setopt(curl, CURLOPT_HTTPPOST,1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData.get());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, bodys.at(index).length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, bodys.at(index).c_str());
}
curl_multi_add_handle(m_curl_multi, curl);
index++;
}
curl_multi_perform(m_curl_multi, &still_running);
//block until activity is detected on at least one of the handles or MAX_WAIT_MSECS has passed.
do {
res = curl_multi_wait(m_curl_multi, NULL, 0, 1000, &numfds);
if(res != CURLM_OK) {
Logger::smf_n11().debug("curl_multi_wait() returned %d!", res);
}
curl_multi_perform(m_curl_multi, &still_running);
} while(still_running);
//process multiple curl
//read the messages
while ((curl_msg = curl_multi_info_read(m_curl_multi, &msgs_left))) {
if (curl_msg->msg == CURLMSG_DONE) {
curl = curl_msg->easy_handle;
return_code = curl_msg->data.result;
res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
if(return_code != CURLE_OK) {
Logger::smf_n11().debug("CURL error code %d!", curl_msg->data.result);
continue;
}
// Get HTTP status code
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status_code);
Logger::smf_n11().debug("HTTP status code %d!", http_status_code);
//remove this handle from the multi session and end this handle
curl_multi_remove_handle(m_curl_multi, curl);
curl_easy_cleanup(curl);
} else {
Logger::smf_n11().debug("Error after curl_multi_info_read(), CURLMsg %s", curl_msg->msg);
}
}
}
//-----------------------------------------------------------------------------------------------------
CURL * smf_n11::curl_create_handle (event_notification &ev_notif, std::string *httpData){
//create handle for a curl request
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charsets: utf-8");
CURL *curl = curl_easy_init();
if (curl){
std::string url = ev_notif.get_notif_uri() ;
Logger::smf_n11().debug("Send notification to NF with URI: %s", url);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str() );
//curl_easy_setopt(curl, CURLOPT_PRIVATE, str);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(curl, CURLOPT_HTTPGET,1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 100L);
// Hook up data handling function.
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, httpData);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
}
return curl;
}
......@@ -33,6 +33,7 @@
#include <map>
#include "smf.h"
#include <curl/curl.h>
#include "3gpp_29.503.h"
#include "smf_context.hpp"
#include "SmContextCreatedData.h"
......@@ -75,6 +76,30 @@ class smf_n11 {
void send_n1n2_message_transfer_request(
std::shared_ptr<itti_n11_session_report_request> report_msg);
/*
* Send SM Context Status Notification to AMF
* @param [std::shared_ptr<itti_n11_notify_sm_context_status>] sm_context_status: Content of message to be sent
* @return void
*/
void send_sm_context_status_notification(
std::shared_ptr<itti_n11_notify_sm_context_status> sm_context_status);
/*
* Send Notification for the associated event to the subscribers
* @param [std::shared_ptr<itti_n11_notify_subscribed_event>] msg: Content of message to be sent
* @return void
*/
void notify_subscribed_event(
std::shared_ptr<itti_n11_notify_subscribed_event> msg);
/*
* Create Curl handle for multi curl
* @param [event_notification&] ev_notif: content of the event notification
* @param [std::string *] data: data
* @return pointer to the created curl
*/
CURL * curl_create_handle (event_notification &ev_notif, std::string *data);
};
}
#endif /* FILE_SMF_N11_HPP_SEEN */
......@@ -58,6 +58,12 @@ class smf_n2 {
smf_n2(smf_n2 const&) = delete;
void operator=(smf_n2 const&) = delete;
public:
static smf_n2& get_instance() {
static smf_n2 instance;
return instance;
}
/*
* Create N2 SM Information: PDU Session Resource Setup Request Transfer
* This IE is included in N1N2MessageTransfer Request (Accept, PDU Session Establishment procedure - UE initiated)
......
......@@ -351,8 +351,6 @@ void session_create_sm_context_procedure::handle_itti_msg(
//fill content for N1N2MessageTransfer (including N1, N2 SM)
// Create N1 SM container & N2 SM Information
smf_n1 smf_n1_inst = { };
smf_n2 smf_n2_inst = { };
std::string n1_sm_msg, n1_sm_msg_hex;
std::string n2_sm_info, n2_sm_info_hex;
......@@ -368,7 +366,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED;
}
smf_n1_inst.create_n1_pdu_session_establishment_reject(n11_triggered_pending->res,
smf_n1::get_instance().create_n1_pdu_session_establishment_reject(n11_triggered_pending->res,
n1_sm_msg, cause_n1);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex);
......@@ -385,12 +383,12 @@ void session_create_sm_context_procedure::handle_itti_msg(
cause_value_5gsm_e::CAUSE_50_PDU_SESSION_TYPE_IPV4_ONLY_ALLOWED;
}
smf_n1_inst.create_n1_pdu_session_establishment_accept(n11_triggered_pending->res,
smf_n1::get_instance().create_n1_pdu_session_establishment_accept(n11_triggered_pending->res,
n1_sm_msg, cause_n1);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex);
//N2 SM Information (Step 11, section 4.3.2.2.1 @ 3GPP TS 23.502): PDUSessionRessourceSetupRequestTransfer IE
smf_n2_inst.create_n2_pdu_session_resource_setup_request_transfer(
smf_n2::get_instance().create_n2_pdu_session_resource_setup_request_transfer(
n11_triggered_pending->res, n2_sm_info_type_e::PDU_RES_SETUP_REQ,
n2_sm_info);
......@@ -844,8 +842,6 @@ void session_update_sm_context_procedure::handle_itti_msg(
itti_n4_session_modification_response &resp,
std::shared_ptr<smf::smf_context> sc) {
smf_n1 smf_n1_inst = { };
smf_n2 smf_n2_inst = { };
std::string n1_sm_msg, n1_sm_msg_hex;
std::string n2_sm_info, n2_sm_info_hex;
......@@ -1022,12 +1018,12 @@ void session_update_sm_context_procedure::handle_itti_msg(
//FOR TESTING PURPOSE
case session_management_procedures_type_e::PDU_SESSION_TEST: {
//N1 SM
smf_n1_inst.create_n1_pdu_session_modification_request(
smf_n1::get_instance().create_n1_pdu_session_modification_request(
n11_triggered_pending->res, n1_sm_msg, cause_value_5gsm_e::CAUSE_0_UNKNOWN);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
n11_triggered_pending->res.set_n1_sm_message(n1_sm_msg_hex);
//N2 SM Information
smf_n2_inst.create_n2_pdu_session_resource_modify_response_transfer(
smf_n2::get_instance().create_n2_pdu_session_resource_modify_response_transfer(
n11_triggered_pending->res, n2_sm_info_type_e::PDU_RES_MOD_RSP,
n2_sm_info);
smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex);
......@@ -1062,7 +1058,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
// Create N2 SM Information: PDU Session Resource Setup Request Transfer IE
//N2 SM Information
smf_n2_inst.create_n2_pdu_session_resource_setup_request_transfer(
smf_n2::get_instance().create_n2_pdu_session_resource_setup_request_transfer(
n11_triggered_pending->res, n2_sm_info_type_e::PDU_RES_SETUP_REQ,
n2_sm_info);
......@@ -1123,7 +1119,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
Logger::smf_app().info("PDU Session Release UE-initiated (Step 1))");
//N1 SM
smf_n1_inst.create_n1_pdu_session_release_command(
smf_n1::get_instance().create_n1_pdu_session_release_command(
n11_triggered_pending->res, n1_sm_msg,
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES); //TODO: check Cause
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
......@@ -1132,7 +1128,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
//include N2 SM Resource Release Request only when User Plane connection is activated
if (sps->get_upCnx_state() == upCnx_state_e::UPCNX_STATE_ACTIVATED) {
//N2 SM Information
smf_n2_inst.create_n2_pdu_session_resource_release_command_transfer(
smf_n2::get_instance().create_n2_pdu_session_resource_release_command_transfer(
n11_triggered_pending->res, n2_sm_info_type_e::PDU_RES_REL_CMD,
n2_sm_info);
smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex);
......
/*
* 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
*/
/*! \file smf_subscription.cpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email: tien-thinh.nguyen@eurecom.fr
*/
#include "smf_subscription.hpp"
#include "smf_app.hpp"
#include "itti.hpp"
#include "common_defs.h"
#include "itti_msg_sbi.hpp"
using namespace smf;
extern smf::smf_app *smf_app_inst;
extern itti_mw *itti_inst;
/*
* 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
*/
/*! \file smf_subscription.hpp
\brief
\author Tien-Thinh NGUYEN
\company Eurecom
\date 2020
\email: tien-thinh.nguyen@eurecom.fr
*/
#ifndef FILE_SMF_SUBSCRIPTION_HPP_SEEN
#define FILE_SMF_SUBSCRIPTION_HPP_SEEN
#include <map>
#include <shared_mutex>
#include <memory>
#include <utility>
#include <vector>
#include "3gpp_24.007.h"
#include "3gpp_29.508.h"
#include "common_root_types.h"
#include "itti.hpp"
namespace smf {
/*
* Manage the Subscription Info
*/
class smf_subscription {
public:
smf_subscription() {
}
public:
evsub_id_t sub_id;
smf_event_t ev_type;
supi64_t supi;
std::string notif_id;
std::string notif_uri;
pdu_session_id_t pdu_session_id;
//mutable std::shared_mutex m_context;
};
}
#endif
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