Commit 835e4465 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Add Event Exposure - PDU Session Release

parent a276d415
......@@ -12,6 +12,14 @@
#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 {
......@@ -27,10 +35,78 @@ SubscriptionsCollectionApiImpl::SubscriptionsCollectionApiImpl(
m_address(address) {
}
void SubscriptionsCollectionApiImpl::create_individual_subcription(const NsmfEventExposure &nsmfEventExposure, Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("SubscriptionsCollectionApiImpl::create_individual_subcription...");
response.send(Pistache::Http::Code::Not_Implemented,
"create_individual_subcription API has not been implemented yet!\n");
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());
}
}
......
......@@ -50,6 +50,10 @@ public:
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();
}
};
}
......
/*
* 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;
......
......@@ -516,4 +516,40 @@ class itti_n11_notify_sm_context_status : public itti_n11_msg {
};
//-----------------------------------------------------------------------------
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_ */
......@@ -115,7 +115,9 @@ typedef enum {
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,
......
......@@ -59,6 +59,7 @@ add_library (SMF STATIC
smf_n10.cpp
smf_n11.cpp
smf_event.cpp
smf_subscription.cpp
smf_msg.cpp
)
......@@ -128,6 +128,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 };
......@@ -1120,6 +1130,37 @@ 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 an AMF (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);
}
//smf_event_inst->subscribe_sm_context_status_notification(boost::bind(&smf_context::send_sm_context_status_notification, this, _1, _1, _1));
}
//------------------------------------------------------------------------------
bool smf_app::is_supi_2_smf_context(const supi64_t &supi) const {
std::shared_lock lock(m_supi2smf_context);
......@@ -1186,6 +1227,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) {
......@@ -1629,3 +1677,38 @@ void smf_app::trigger_http_response(const uint32_t &http_code,
}
}
}
//---------------------------------------------------------------------------------------------
void smf_app::add_event_subscription(evsub_id_t sub_id, smf_event_t ev, std::shared_ptr<smf_subscription> ss) {
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 (i.first.second == 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::shared_ptr<smf_subscription> subscription) {
for (auto const& i : smf_event_subscriptions) {
if ((i.first.second == ev) && (i.second->supi == supi) && (i.second->pdu_session_id == pdu_session_id)){
subscription = 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"
......@@ -116,10 +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;
......@@ -132,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
......@@ -373,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
......@@ -440,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
......@@ -653,6 +682,29 @@ 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: list of the subscription associated with this event type
* @return vector
*/
void get_ee_subscriptions(smf_event_t ev, std::vector<std::shared_ptr<smf_subscription>> subscriptions);
void get_ee_subscriptions(evsub_id_t sub_id, std::vector<std::shared_ptr<smf_subscription>> subscriptions);
void get_ee_subscriptions(smf_event_t ev, supi64_t supi, pdu_session_id_t pdu_session_id, std::shared_ptr<smf_subscription> subscription);
};
}
#include "smf_config.hpp"
......
......@@ -1397,7 +1397,9 @@ void smf_context::handle_pdu_session_create_sm_context_request(
//TODO: return;
}
scf.get()->amf_status_uri = smreq->req.get_sm_context_status_uri();
smf_event_inst->subscribe_sm_context_status_notification(boost::bind(&smf_context::send_sm_context_status_notification, this, _1, _1, _1));
//smf_event_inst->subscribe_sm_context_status_notification(boost::bind(&smf_context::send_sm_context_status_notification, this, _1, _1, _1));
//smf_event_inst->subscribe_sm_context_status_notification(boost::bind(&smf_subscription_management::send_sm_context_status_notification, smf_subscription_management_inst, _1, _1, _1));
//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(
......@@ -2090,6 +2092,10 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//TODO: return;
}
smf_event_inst->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_inst->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
......
......@@ -28,23 +28,114 @@
*/
#include "smf_event.hpp"
#include "smf_subscription.hpp"
#include "smf_app.hpp"
#include "itti.hpp"
using namespace smf;
extern smf_event *smf_event_inst;
extern smf::smf_app *smf_app_inst;
extern itti_mw *itti_inst;
//------------------------------------------------------------------------------
smf_event::smf_event() {
//by default, subscribe to the events
smf_event_inst->subscribe_sm_context_status_notification(
boost::bind(&smf_event::send_sm_context_status_notification, this, _1, _1,
_1));
smf_event_inst->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) {
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, uint32_t status, uint8_t http_version) {
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, 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) {
sm_context_status_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, 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;
std::shared_ptr<smf_subscription> subscription;
smf_app_inst->get_ee_subscriptions(smf_event_t::SMF_EVENT_PDU_SES_REL, supi,
pdu_session_id, subscription);
//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);
event_notification ev_notif = { };
ev_notif.set_pdu_session_id(pdu_session_id);
itti_msg->notif_id = std::to_string(subscription->sub_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());
}
}
......@@ -33,10 +33,19 @@
#include <boost/signals2.hpp>
#include "smf.h"
#include "3gpp_24.007.h"
namespace smf {
typedef boost::signals2::signal<void(scid_t, uint32_t, uint8_t)> sm_context_status_sig_t;
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 {
......@@ -52,17 +61,52 @@ class smf_event {
*/
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 [uint32_t] status: Updated status
* @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 trigger_sm_context_status_notification(scid_t scid, uint32_t status, uint8_t http_version);
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;
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
};
}
......
......@@ -704,3 +704,177 @@ 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;
}
//-----------------------------------------------------------------------------
supi_t event_notification::get_supi() const {
return m_supi;
}
//-----------------------------------------------------------------------------
void event_notification::set_supi(const supi_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;
}
......@@ -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"
......@@ -513,6 +514,149 @@ 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 supi_t &supi);
supi_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;
private:
smf_event_t m_event; //SmfEvent
//std::string m_TimeStamp;
supi_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
/*
* 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