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

Merge branch 'improve_smf_context_handling' into 'develop'

Improve smf context handling

See merge request oai/cn5g/oai-cn5g-smf!98
parents a809cd94 42e55035
......@@ -45,7 +45,7 @@ Based on document **3GPP TS 23.501 v16.0.0 (Section 6.2.2)**.
| 2 | UE IP address allocation & management​ | :heavy_check_mark: | IP Address pool is controlled by SMF |
| 3 | DHCPv4 (server and client) and DHCPv6 (server and client) function | :x: | |
| 4 | Respond to ARP requests and/or IPv6 Neighbour Solicitation requests | :x: | |
| 5 | Selection of UPF function​ | :heavy_check_mark: | Local configuration in SMF |
| 5 | Selection of UPF function​ | :heavy_check_mark: | Local configuration/UPF discovery via NRF |
| 6 | Configures traffic steering at UPF | :x: | |
| 7 | Termination of interfaces towards PCFs | :x: | |
| 8 | Lawful intercept | :x: | |
......
......@@ -1067,6 +1067,19 @@ struct node_id_s {
return false;
}
};
node_id_s& operator=(const struct node_id_s& i) {
node_id_type = i.node_id_type;
fqdn = i.fqdn;
u1.ipv4_address.s_addr = i.u1.ipv4_address.s_addr;
u1.ipv6_address.s6_addr32[0] = i.u1.ipv6_address.s6_addr32[0];
u1.ipv6_address.s6_addr32[1] = i.u1.ipv6_address.s6_addr32[1];
u1.ipv6_address.s6_addr32[2] = i.u1.ipv6_address.s6_addr32[2];
u1.ipv6_address.s6_addr32[3] = i.u1.ipv6_address.s6_addr32[3];
return *this;
}
std::string toString() const {
if (NODE_ID_TYPE_FQDN == this->node_id_type) {
return fqdn;
......
......@@ -73,6 +73,19 @@ typedef struct s_nssai // section 28.4, TS23.003
}
}
s_nssai& operator=(const struct s_nssai& s) {
sST = s.sST;
sD = s.sD;
return *this;
}
std::string toString() const {
std::string s = {};
s.append("SST=").append(std::to_string(sST));
s.append(", SD=").append(sD);
return s;
}
} snssai_t;
typedef uint8_t pdu_session_id;
......
......@@ -483,10 +483,8 @@ void smf_app::handle_itti_msg(itti_n4_session_deletion_response& smresp) {
std::shared_ptr<smf_context> pc = {};
if (seid_2_smf_context(smresp.seid, pc)) {
pc.get()->handle_itti_msg(smresp);
if (pc->get_number_dnn_contexts() == 0) {
delete_smf_context(pc);
}
// TODO: Delete SM Context if there's no PDU Session associated with this
// context
} else {
Logger::smf_app().debug(
"Received N4 Session Deletion Response seid" TEID_FMT
......@@ -514,13 +512,27 @@ void smf_app::handle_itti_msg(std::shared_ptr<itti_n4_node_failure> snf) {
pfcp::node_id_t node_id = snf->node_id;
for (auto it : scid2smf_context) {
if (it.second->upf_node_id == node_id) {
supi64_t supi64 = smf_supi_to_u64(it.second->supi);
Logger::smf_app().debug(
"Remove the associated PDU session (SUPI " SUPI_64_FMT
", PDU Sessin Id %d)",
supi64, it.second->pdu_session_id);
// TODO: remove the session
std::shared_ptr<smf_context> sc = {};
supi64_t supi64 = smf_supi_to_u64(it.second->supi);
if (is_supi_2_smf_context(supi64)) {
sc = supi_2_smf_context(supi64);
}
if (sc.get() == nullptr) {
Logger::smf_app().debug("No SMF Context found");
return;
}
std::map<pdu_session_id_t, std::shared_ptr<smf_pdu_session>> sessions;
sc.get()->get_pdu_sessions(sessions);
for (auto s : sessions) {
pfcp::node_id_t n = s.second->get_upf_node_id();
if (n == node_id) {
Logger::smf_app().debug(
"Remove the associated PDU session (SUPI " SUPI_64_FMT
", PDU Sessin Id %d)",
supi64, it.first);
// TODO: remove the session
}
}
}
}
......@@ -578,8 +590,8 @@ void smf_app::handle_itti_msg(
// Get UPF node
std::shared_ptr<smf_context_ref> scf = {};
if (smf_app_inst->is_scid_2_smf_context(m.scid)) {
scf = scid_2_smf_context(m.scid);
up_node_id = scf.get()->upf_node_id;
scf = scid_2_smf_context(m.scid);
// up_node_id = scf.get()->upf_node_id;
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!",
......@@ -587,6 +599,29 @@ void smf_app::handle_itti_msg(
return;
}
std::shared_ptr<smf_context> sc = {};
supi64_t supi64 = smf_supi_to_u64(scf.get()->supi);
if (is_supi_2_smf_context(supi64)) {
Logger::smf_app().debug(
"Update SMF context with SUPI " SUPI_64_FMT "", supi64);
sc = supi_2_smf_context(supi64);
}
if (sc.get() == nullptr) {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!",
m.scid);
return;
}
std::shared_ptr<smf_pdu_session> sp = {};
if (!sc.get()->find_pdu_session(scf.get()->pdu_session_id, sp)) {
Logger::smf_app().warn("PDU session context does not exist!");
return;
}
sp.get()->get_upf_node_id(up_node_id);
std::shared_ptr<itti_n4_session_failure_indication>
itti_n4_failure_indication =
std::make_shared<itti_n4_session_failure_indication>(
......@@ -910,37 +945,20 @@ void smf_app::handle_pdu_session_create_sm_context_request(
sc.get()->set_plmn(smreq->req.get_plmn()); // PLMN
}
// Step 5. Create/update context with dnn information
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(snssai, dnn, sd)) {
if (nullptr == sd.get()) {
// Create a new one and insert to the list
Logger::smf_app().debug(
"Create a DNN context and add to the SMF context");
sd = std::shared_ptr<dnn_context>(new dnn_context(dnn));
sd.get()->in_use = true;
sd.get()->dnn_in_use = dnn;
sd.get()->nssai = snssai;
sc.get()->insert_dnn(sd);
}
}
// Step 6. If colliding with an existing SM context (session is already
// Step 5. 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) &&
if (is_scid_2_smf_context(supi64, 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);
sc.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);
"PDU Session already existed (SUPI " SUPI_64_FMT ", PDU Session ID %d)",
supi64, pdu_session_id);
}
// Step 7. Retrieve Session Management Subscription data from UDM if not
// Step 6. 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
......@@ -1000,13 +1018,11 @@ void smf_app::handle_pdu_session_create_sm_context_request(
}
// Step 8. Generate a SMF context Id and store the corresponding information
// in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id))
// in a map (SM_Context_ID, (supi, pdu_session_id))
scid_t scid = generate_smf_context_ref();
std::shared_ptr<smf_context_ref> scf =
std::shared_ptr<smf_context_ref>(new smf_context_ref());
scf.get()->supi = supi;
scf.get()->dnn = dnn;
scf.get()->nssai = snssai;
scf.get()->pdu_session_id = pdu_session_id;
set_scid_2_smf_context(scid, scf);
smreq->set_scid(scid);
......@@ -1026,7 +1042,7 @@ void smf_app::handle_pdu_session_update_sm_context_request(
"version %d)",
smreq->http_version);
// Step 1. Get SUPI, DNN, NSSAI, PDU Session ID from sm_context
// Step 1. Get SUPI, PDU Session ID from sm_context
// SM Context ID - uint32_t in our case
scid_t scid = {};
try {
......@@ -1057,13 +1073,7 @@ void smf_app::handle_pdu_session_update_sm_context_request(
return;
}
// Step 2. Store SUPI, DNN, NSSAI in itti_n11_update_sm_context_request to be
// processed later on
supi64_t supi64 = smf_supi_to_u64(scf.get()->supi);
smreq->req.set_supi(scf.get()->supi);
smreq->req.set_dnn(scf.get()->dnn);
smreq->req.set_snssai(scf.get()->nssai);
smreq->req.set_pdu_session_id(scf.get()->pdu_session_id);
// Step 3. Find the smf context
std::shared_ptr<smf_context> sc = {};
......@@ -1085,28 +1095,33 @@ void smf_app::handle_pdu_session_update_sm_context_request(
return;
}
// Step 4. get dnn context
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
Logger::smf_app().warn(
"Received PDU Session Update SM Context Request, couldn't retrieve "
"the corresponding SMF context, ignore message!");
// Trigger to send reply to AMF
trigger_update_context_error_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND, smreq->pid);
return;
}
// Get PDU Session
std::shared_ptr<smf_pdu_session> sp = {};
if (!sc.get()->find_pdu_session(scf.get()->pdu_session_id, sp)) {
Logger::smf_app().warn(
"Received PDU Session Update SM Context Request, couldn't retrieve "
"the corresponding SMF context, ignore message!");
// Trigger to send reply to AMF
trigger_update_context_error_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND, smreq->pid);
return;
}
// Step 4. Store SUPI, DNN, NSSAI in itti_n11_update_sm_context_request to be
// processed later on
smreq->req.set_supi(scf.get()->supi);
smreq->req.set_pdu_session_id(scf.get()->pdu_session_id);
smreq->req.set_dnn(sp.get()->get_dnn());
smreq->req.set_snssai(sp.get()->get_snssai());
// Step 5. Verify AMF??
// Step 6. Update targetServingNfId if available (for N2 Handover with AMF
// change)
if (smreq.get()->req.target_serving_nf_id_is_set()) {
scf.get()->target_amf = smreq.get()->req.get_target_serving_nf_id();
std::string target_amf = smreq.get()->req.get_target_serving_nf_id();
sc.get()->set_target_amf(target_amf);
}
// Step 7. Handle the message in smf_context
......@@ -1126,7 +1141,7 @@ void smf_app::handle_pdu_session_release_sm_context_request(
Logger::smf_app().info(
"Handle a PDU Session Release SM Context Request from an AMF");
// Step 1. get supi, dnn, nssai, pdu_session id from sm_context
// Step 1. Get SUPI, PDU Session ID from sm_context
// SM Context ID - uint32_t in our case
scid_t scid = {};
try {
......@@ -1156,12 +1171,10 @@ void smf_app::handle_pdu_session_release_sm_context_request(
return;
}
// Step 2. store supi, dnn, nssai in itti_n11_update_sm_context_request to be
// processed later on
// Step 2. store SUPI, PDU Session ID in itti_n11_update_sm_context_request to
// be processed later on
supi64_t supi64 = smf_supi_to_u64(scf.get()->supi);
smreq->req.set_supi(scf.get()->supi);
smreq->req.set_dnn(scf.get()->dnn);
smreq->req.set_snssai(scf.get()->nssai);
smreq->req.set_pdu_session_id(scf.get()->pdu_session_id);
// Step 2. find the smf context
......@@ -1183,24 +1196,23 @@ void smf_app::handle_pdu_session_release_sm_context_request(
return;
}
// get dnn context
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
// Error, DNN context doesn't exist, send PDUSession_SMUpdateContext
// Response to AMF
Logger::smf_app().warn(
"Received PDU Session Release SM Context Request, couldn't retrieve "
"the corresponding SMF context, ignore message!");
// trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND, smreq->pid,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
// Find PDU Session Context
std::shared_ptr<smf_pdu_session> sp = {};
if (!sc.get()->find_pdu_session(scf.get()->pdu_session_id, sp)) {
Logger::smf_app().warn(
"Received PDU Session Release SM Context Request, couldn't retrieve "
"the corresponding SMF context, ignore message!");
// trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND, smreq->pid,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
// Store DNN, SNSSSAI
smreq->req.set_dnn(sp.get()->get_dnn());
smreq->req.set_snssai(sp.get()->get_snssai());
// Step 3. handle the message in smf_context
sc.get()->handle_pdu_session_release_sm_context_request(smreq);
}
......@@ -1231,7 +1243,7 @@ void smf_app::trigger_pdu_session_modification(
itti_msg->msg.add_qfi(qfi);
supi64_t supi64 = smf_supi_to_u64(supi);
// Step 2. find the smf context
// Step 2. find the SMF Context
std::shared_ptr<smf_context> sc = {};
if (is_supi_2_smf_context(supi64)) {
......@@ -1452,14 +1464,11 @@ bool smf_app::is_scid_2_smf_context(const scid_t& scid) const {
//------------------------------------------------------------------------------
bool smf_app::is_scid_2_smf_context(
const supi64_t& supi, const std::string& dnn, const snssai_t& snssai,
const pdu_session_id_t& pid) const {
const supi64_t& supi, const pdu_session_id_t& pid) const {
std::shared_lock lock(m_scid2smf_context);
for (auto it : scid2smf_context) {
supi64_t supi64 = smf_supi_to_u64(it.second->supi);
if ((supi64 == supi) and (it.second->dnn.compare(dnn) == 0) and
(it.second->nssai == snssai) and (it.second->pdu_session_id == pid))
return true;
if ((supi64 == supi) and (it.second->pdu_session_id == pid)) return true;
}
return false;
}
......@@ -1500,7 +1509,7 @@ void smf_app::update_pdu_session_status(
const scid_t& scid, const pdu_session_status_e& status) {
Logger::smf_app().info("Update PDU Session Status");
// get the smf context
// get the SMF Context
std::shared_ptr<smf_context_ref> scf = {};
if (is_scid_2_smf_context(scid)) {
......@@ -1527,23 +1536,15 @@ void smf_app::update_pdu_session_status(
supi64);
}
// get dnn context
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
Logger::smf_app().warn(
"Could not retrieve the corresponding DNN context!");
}
}
// get smd_pdu_session
// Get PDU Session
std::shared_ptr<smf_pdu_session> sp = {};
bool find_pdn = sd.get()->find_pdu_session(pdu_session_id, sp);
if (nullptr == sp.get()) {
if (!sc.get()->find_pdu_session(pdu_session_id, sp)) {
Logger::smf_app().warn(
"Could not retrieve the corresponding SMF PDU Session context!");
return;
}
sp.get()->set_pdu_session_status(status);
Logger::smf_app().info(
"Set PDU Session Status to %s",
......@@ -1582,23 +1583,14 @@ void smf_app::update_pdu_session_upCnx_state(
supi64);
}
// get dnn context
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
Logger::smf_app().warn(
"Could not retrieve the corresponding DNN context!");
}
}
// get smd_pdu_session
// get PDU Session
std::shared_ptr<smf_pdu_session> sp = {};
bool find_pdn = sd.get()->find_pdu_session(pdu_session_id, sp);
if (nullptr == sp.get()) {
if (!sc.get()->find_pdu_session(pdu_session_id, sp)) {
Logger::smf_app().warn(
"Could not retrieve the corresponding SMF PDU Session context!");
return;
}
sp.get()->set_upCnx_state(state);
Logger::smf_app().info(
"Set PDU Session UpCnxState to %s",
......
......@@ -80,23 +80,11 @@ class smf_context_ref {
void clear() {
supi = {};
nssai = {};
dnn = {};
pdu_session_id = 0;
amf_status_uri = {};
amf_addr = {};
upf_node_id = {};
target_amf = "";
}
supi_t supi;
std::string dnn;
pdu_session_id_t pdu_session_id;
snssai_t nssai;
std::string amf_status_uri;
std::string amf_addr;
std::string target_amf; // targetServingNfId
pfcp::node_id_t upf_node_id;
};
class smf_app {
......@@ -212,7 +200,6 @@ class smf_app {
void operator=(smf_app const&) = delete;
void test_dns();
/*
* Set the association between Seid and SM Context
* @param [const seid_t &] seid: SessionID
......@@ -453,17 +440,14 @@ class smf_app {
bool is_scid_2_smf_context(const scid_t& scid) const;
/*
* Verify whether a SMF Context Reference with a given ID exist
* Verify whether a SMF Context Reference exist
* @param [const supi64_t &] supi64: Supi64
* @param [const std::string &] dnn: DNN
* @param [const snssai_t &] snssai: S-NSSAI
* @param [const pdu_session_id_t &] pid: PDU Session ID
*
* @return bool: True if a SMF Context Reference exist, otherwise return false
* @return bool: True if SMF Context Reference found, otherwise return false
*/
bool is_scid_2_smf_context(
const supi64_t& supi, const std::string& dnn, const snssai_t& snssai,
const pdu_session_id_t& pid) const;
const supi64_t& supi, const pdu_session_id_t& pid) const;
/*
* Find SMF Context Reference by its ID
......
......@@ -344,11 +344,13 @@ class smf_config {
}
sbi_http2_port = 8080;
sbi_api_version = "v1";
http_version = 1;
use_local_subscription_info = false;
register_nrf = false;
discover_upf = false;
use_fqdn_dns = false;
use_nwi = false;
};
~smf_config();
void lock() { m_rw_lock.lock(); };
......
......@@ -87,28 +87,28 @@ void smf_qos_flow::mark_as_released() {
std::string smf_qos_flow::toString() const {
std::string s = {};
s.append("QoS Flow:\n");
s.append("\tQFI:\t\t\t\t")
s.append("\t\tQFI:\t\t")
.append(std::to_string((uint8_t) qfi.qfi))
.append("\n");
s.append("\tUL FTEID:\t\t").append(ul_fteid.toString()).append("\n");
s.append("\tDL FTEID:\t\t").append(dl_fteid.toString()).append("\n");
s.append("\tPDR ID UL:\t\t\t")
s.append("\t\tUL FTEID:\t").append(ul_fteid.toString()).append("\n");
s.append("\t\tDL FTEID:\t").append(dl_fteid.toString()).append("\n");
s.append("\t\tPDR ID UL:\t")
.append(std::to_string(pdr_id_ul.rule_id))
.append("\n");
s.append("\tPDR ID DL:\t\t\t")
s.append("\t\tPDR ID DL:\t")
.append(std::to_string(pdr_id_dl.rule_id))
.append("\n");
s.append("\tPrecedence:\t\t\t")
s.append("\t\tPrecedence:\t")
.append(std::to_string(precedence.precedence))
.append("\n");
if (far_id_ul.first) {
s.append("\tFAR ID UL:\t\t\t")
s.append("\t\tFAR ID UL:\t")
.append(std::to_string(far_id_ul.second.far_id))
.append("\n");
}
if (far_id_dl.first) {
s.append("\tFAR ID DL:\t\t\t")
s.append("\t\tFAR ID DL:\t")
.append(std::to_string(far_id_dl.second.far_id))
.append("\n");
}
......@@ -352,7 +352,7 @@ void smf_pdu_session::set_seid(const uint64_t& s) {
}
//------------------------------------------------------------------------------
// TODO check if urr_id should be uniq in the UPF or in the context of a pdn
// TODO check if urr_id should be unique in the UPF or in the context of a pdn
// connection
void smf_pdu_session::generate_urr_id(pfcp::urr_id_t& urr_id) {
urr_id.urr_id = urr_id_generator.get_uid();
......@@ -376,14 +376,14 @@ void smf_pdu_session::release_far_id(const pfcp::far_id_t& far_id) {
}
//------------------------------------------------------------------------------
// TODO check if prd_id should be uniq in the UPF or in the context of a pdn
// TODO check if prd_id should be unique in the UPF or in the context of a pdn
// connection
void smf_pdu_session::generate_pdr_id(pfcp::pdr_id_t& pdr_id) {
pdr_id.rule_id = pdr_id_generator.get_uid();
}
//------------------------------------------------------------------------------
// TODO check if prd_id should be uniq in the UPF or in the context of a pdn
// TODO check if prd_id should be unique in the UPF or in the context of a pdn
// connection
void smf_pdu_session::release_pdr_id(const pfcp::pdr_id_t& pdr_id) {
pdr_id_generator.free_uid(pdr_id.rule_id);
......@@ -404,30 +404,39 @@ std::string smf_pdu_session::toString() const {
std::string s = {};
smf_qos_flow flow = {};
s.append("PDN CONNECTION:\n");
s.append("\tPDN type:\t\t\t")
.append(pdu_session_type.toString())
.append("\n");
bool is_released = false;
if (pdu_session_status == pdu_session_status_e::PDU_SESSION_INACTIVE)
is_released = true;
if (!is_released) {
s.append("\tPDU Session ID:\t\t")
.append(std::to_string((uint8_t) pdu_session_id))
.append("\n");
s.append("\tDNN:\t\t\t").append(dnn).append("\n");
s.append("\tSNSSAI:\t\t\t").append(snssai.toString()).append("\n");
s.append("\tPDN type:\t\t")
.append(pdu_session_type.toString())
.append("\n");
}
if (ipv4)
s.append("\tPAA IPv4:\t\t\t")
s.append("\tPAA IPv4:\t\t")
.append(conv::toString(ipv4_address))
.append("\n");
if (ipv6)
s.append("\tPAA IPv6:\t\t\t")
s.append("\tPAA IPv6:\t\t")
.append(conv::toString(ipv6_address))
.append("\n");
if (default_qfi.qfi) {
s.append("\tDefault QFI:\t\t\t")
s.append("\tDefault QFI:\t\t")
.append(std::to_string(default_qfi.qfi))
.append("\n");
} else {
s.append("\tDefault QFI:\t\t\t").append("No QFI available").append("\n");
s.append("\tDefault QFI:\t\t").append("No QFI available").append("\n");
}
if (!is_released) {
s.append("\tSEID:\t\t\t").append(std::to_string(seid)).append("\n");
}
s.append("\tSEID:\t\t\t\t").append(std::to_string(seid)).append("\n");
if (default_qfi.qfi) {
s.append("Default ");
s.append("\tDefault ");
for (auto it : qos_flows) {
if (it.second.qfi == default_qfi.qfi) {
s.append(it.second.toString());
......@@ -618,19 +627,34 @@ void smf_pdu_session::add_qos_rule(const QOSRulesIE& qos_rule) {
}
}
//------------------------------------------------------------------------------
void smf_pdu_session::set_amf_addr(const std::string& addr) {
amf_addr = addr;
void smf_pdu_session::set_upf_node_id(const pfcp::node_id_t& node_id) {
upf_node_id = node_id;
}
void smf_pdu_session::get_upf_node_id(pfcp::node_id_t& node_id) const {
node_id = upf_node_id;
}
pfcp::node_id_t smf_pdu_session::get_upf_node_id() const {
return upf_node_id;
}
//-----------------------------------------------------------------------------
std::string smf_pdu_session::get_dnn() const {
return dnn;
}
//-----------------------------------------------------------------------------
snssai_t smf_pdu_session::get_snssai() const {
return snssai;
}
//------------------------------------------------------------------------------
void smf_pdu_session::get_amf_addr(std::string& addr) const {
addr = amf_addr;
void smf_pdu_session::set_dnn(const std::string& d) {
dnn = d;
}
//------------------------------------------------------------------------------
std::string smf_pdu_session::get_amf_addr() const {
return amf_addr;
void smf_pdu_session::set_snssai(const snssai_t s) {
snssai = s;
}
//------------------------------------------------------------------------------
......@@ -736,9 +760,7 @@ void smf_context::handle_itti_msg(
" pfcp_tx_id %" PRIX64 ", smf_procedure not found, discarded!",
smresp.seid, smresp.trxn_id);
}
Logger::smf_app().info(
"Handle N4 Session Modification Response with SMF context %s",
toString().c_str());
Logger::smf_app().info("Handle N4 Session Modification Response");
}
//------------------------------------------------------------------------------
......@@ -758,9 +780,7 @@ void smf_context::handle_itti_msg(itti_n4_session_deletion_response& sdresp) {
sdresp.seid, sdresp.trxn_id);
}
Logger::smf_app().info(
"Handle N4 Session Deletion Response with SMF context %s",
toString().c_str());
Logger::smf_app().info("Handle N4 Session Deletion Response");
}
//------------------------------------------------------------------------------
......@@ -775,10 +795,9 @@ void smf_context::handle_itti_msg(
if (req->pfcp_ies.get(data_report)) {
pfcp::pdr_id_t pdr_id;
if (data_report.get(pdr_id)) {
std::shared_ptr<dnn_context> sd = {};
std::shared_ptr<smf_pdu_session> sp = {};
pfcp::qfi_t qfi = {};
if (find_pdu_session(pdr_id, qfi, sd, sp)) {
if (find_pdu_session(pdr_id, qfi, sp)) {
// Step 1. send N4 Data Report Ack to UPF
std::shared_ptr<itti_n4_session_report_response> n4_report_ack =
std::make_shared<itti_n4_session_report_response>(
......@@ -802,23 +821,20 @@ void smf_context::handle_itti_msg(
pdu_session_report_response session_report_msg = {};
// set the required IEs
session_report_msg.set_supi(supi);
session_report_msg.set_snssai(sd.get()->nssai);
session_report_msg.set_dnn(sd.get()->dnn_in_use);
session_report_msg.set_snssai(sp.get()->get_snssai());
session_report_msg.set_dnn(sp.get()->get_dnn());
session_report_msg.set_pdu_session_type(
sp.get()->get_pdu_session_type().pdu_session_type);
// get supi and put into URL
std::string supi_prefix = {};
get_supi_prefix(supi_prefix);
std::string supi_str = supi_prefix + "-" + smf_supi_to_string(supi);
std::string url =
// std::string(inet_ntoa(
// *((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
//":" + std::to_string(smf_cfg.amf_addr.port) +
"http://" + sp.get()->get_amf_addr() + NAMF_COMMUNICATION_BASE +
smf_cfg.amf_addr.api_version +
fmt::format(
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL,
supi_str.c_str());
std::string url = "http://" + get_amf_addr() +
NAMF_COMMUNICATION_BASE +
smf_cfg.amf_addr.api_version +
fmt::format(
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL,
supi_str.c_str());
session_report_msg.set_amf_url(url);
// seid and trxn_id to be used in Failure indication
session_report_msg.set_seid(req->seid);
......@@ -911,11 +927,13 @@ std::string smf_context::toString() const {
std::string s = {};
s.append("\n");
s.append("SMF CONTEXT:\n");
s.append("\tSUPI:\t\t\t\t")
s.append("SUPI:\t\t\t\t")
.append(smf_supi_to_string(supi).c_str())
.append("\n");
for (auto it : dnns) {
s.append(it->toString());
s.append("PDU SESSION:\t\t\t\t").append("\n");
for (auto it : pdu_sessions) {
s.append(it.second->toString());
s.append("\n");
}
return s;
}
......@@ -1295,38 +1313,21 @@ void smf_context::handle_pdu_session_create_sm_context_request(
xgpp_conv::create_sm_context_response_from_ctx_request(
smreq, sm_context_resp_pending);
// Step 3. Find pdu_session
std::shared_ptr<dnn_context> sd = {};
bool find_dnn = find_dnn_context(snssai, dnn, sd);
// Step 3.1. Create DNN context if not exist
// At this step, this context should be existed
if (nullptr == sd.get()) {
Logger::smf_app().debug(
"DNN context (dnn_in_use %s) is not existed yet!", dnn.c_str());
sd = std::shared_ptr<dnn_context>(new dnn_context());
sd.get()->in_use = true;
sd.get()->dnn_in_use = dnn;
sd.get()->nssai = snssai;
insert_dnn(sd);
} else {
sd.get()->dnn_in_use = dnn;
Logger::smf_app().debug(
"DNN context (dnn_in_use %s) is already existed", dnn.c_str());
}
// Update AMF ID
set_amf_addr(smreq->req.get_serving_nf_id()); // amf id
// Step 3.2. Create PDU session if not exist
std::shared_ptr<smf_pdu_session> sp = {};
bool find_pdu = sd.get()->find_pdu_session(pdu_session_id, sp);
bool find_pdu = find_pdu_session(pdu_session_id, sp);
if (nullptr == sp.get()) {
Logger::smf_app().debug("Create a new PDU session");
sp = std::shared_ptr<smf_pdu_session>(new smf_pdu_session());
sp = std::shared_ptr<smf_pdu_session>(new smf_pdu_session(pdu_session_id));
sp.get()->pdu_session_type.pdu_session_type =
smreq->req.get_pdu_session_type();
sp.get()->pdu_session_id = pdu_session_id;
sp.get()->amf_id = smreq->req.get_serving_nf_id(); // amf id
sd->insert_pdu_session(sp);
sp.get()->set_dnn(dnn);
sp.get()->set_snssai(snssai);
add_pdu_session(pdu_session_id, sp);
} else {
Logger::smf_app().warn("PDU session is already existed!");
}
......@@ -1372,7 +1373,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
std::shared_ptr<dnn_configuration_t> sdc = {};
find_dnn_subscription(snssai, ss);
if (nullptr != ss.get()) {
ss.get()->find_dnn_configuration(sd->dnn_in_use, sdc);
ss.get()->find_dnn_configuration(dnn, sdc);
if (nullptr != sdc.get()) {
paa.pdu_session_type.pdu_session_type =
sdc.get()
......@@ -1423,8 +1424,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// TODO: use requested PDU Session Type?
// paa.pdu_session_type.pdu_session_type = PDU_SESSION_TYPE_E_IPV4V6;
if ((not paa_static_ip) || (not paa.is_ip_assigned())) {
bool success =
paa_dynamic::get_instance().get_free_paa(sd->dnn_in_use, paa);
bool success = paa_dynamic::get_instance().get_free_paa(dnn, paa);
if (success) {
set_paa = true;
} else {
......@@ -1453,8 +1453,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
if (!pco_ids.ci_ipv4_address_allocation_via_dhcpv4) {
// use SM NAS signalling
if ((not paa_static_ip) || (not paa.is_ip_assigned())) {
bool success =
paa_dynamic::get_instance().get_free_paa(sd->dnn_in_use, paa);
bool success = paa_dynamic::get_instance().get_free_paa(dnn, paa);
if (success) {
set_paa = true;
} else {
......@@ -1524,16 +1523,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
// 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();
std::string amf_status_uri = smreq->req.get_sm_context_status_uri();
set_amf_status_uri(amf_status_uri);
// Get and Store AMF Addr if available
std::vector<std::string> split_result;
......@@ -1542,8 +1533,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) +
":" + std::to_string(smf_cfg.amf_addr.port);
boost::split(
split_result, scf.get()->amf_status_uri, boost::is_any_of("/"));
boost::split(split_result, amf_status_uri, boost::is_any_of("/"));
if (split_result.size() >= 3) {
std::string addr = split_result[2];
struct in_addr amf_ipv4_addr;
......@@ -1554,8 +1544,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
Logger::smf_api_server().debug("AMF IP Addr %s", amf_addr_str.c_str());
}
}
scf.get()->amf_addr = amf_addr_str;
sp.get()->set_amf_addr(amf_addr_str);
set_amf_addr(amf_addr_str);
// Trigger SMF APP to send response to SMF-HTTP-API-SERVER (Step
// 5, 4.3.2.2.1 TS 23.502)
......@@ -1623,10 +1613,10 @@ void smf_context::handle_pdu_session_create_sm_context_request(
case PDU_SESSION_TYPE_E_IPV4:
case PDU_SESSION_TYPE_E_IPV4V6:
// paa_dynamic::get_instance().release_paa(
// sd->dnn_in_use, free_paa.ipv4_address);
// dnn, free_paa.ipv4_address);
// break;
case PDU_SESSION_TYPE_E_IPV6:
paa_dynamic::get_instance().release_paa(sd->dnn_in_use, free_paa);
paa_dynamic::get_instance().release_paa(dnn, free_paa);
break;
case PDU_SESSION_TYPE_E_UNSTRUCTURED:
case PDU_SESSION_TYPE_E_ETHERNET:
......@@ -1654,7 +1644,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
supi_str = sm_context_resp_pending->res.get_supi_prefix() + "-" +
smf_supi_to_string(supi);
std::string url =
"http://" + sp.get()->get_amf_addr() + NAMF_COMMUNICATION_BASE +
"http://" + get_amf_addr() + NAMF_COMMUNICATION_BASE +
smf_cfg.amf_addr.api_version +
fmt::format(
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL, supi_str.c_str());
......@@ -2029,20 +2019,15 @@ bool smf_context::handle_pdu_session_release_complete(
// changes notification from UDM by invoking Numd_SDM_Unsubscribe
// TODO: should check if sd context exist
std::shared_ptr<dnn_context> sd = {};
find_dnn_context(
sm_context_request.get()->req.get_snssai(),
sm_context_request.get()->req.get_dnn(), sd);
if (sd.get() != nullptr) {
if (sd.get()->get_number_pdu_sessions() == 0) {
Logger::smf_app().debug(
"Unsubscribe from Session Management Subscription data changes "
"notification from UDM");
// TODO: unsubscribes from Session Management Subscription data
// changes notification from UDM
}
if (get_number_pdu_sessions() == 0) {
Logger::smf_app().debug(
"Unsubscribe from Session Management Subscription data changes "
"notification from UDM");
// TODO: unsubscribes from Session Management Subscription data
// changes notification from UDM
}
// TODO: Invoke Nudm_UECM_Deregistration
return true;
}
......@@ -2350,20 +2335,24 @@ bool smf_context::handle_pdu_session_update_sm_context_request(
session_management_procedures_type_e::
PDU_SESSION_ESTABLISHMENT_UE_REQUESTED);
// Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and
// pdu_session must be existed
std::shared_ptr<dnn_context> sd = {};
// Step 1. get SMF PDU session context. At this stage, pdu_session must be
// existed
std::shared_ptr<smf_pdu_session> sp = {};
bool find_dnn = find_dnn_context(
sm_context_req_msg.get_snssai(), sm_context_req_msg.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu =
sd.get()->find_pdu_session(sm_context_req_msg.get_pdu_session_id(), sp);
if (!find_pdu_session(sm_context_req_msg.get_pdu_session_id(), sp)) {
// error
Logger::smf_app().warn("PDU session context does not exist!");
// trigger to send reply to AMF
smf_app_inst->trigger_update_context_error_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND, smreq->pid);
return false;
}
if (!find_dnn or !find_pdu) {
// error, send reply to AMF with error code "Context Not Found"
Logger::smf_app().warn("DNN or PDU session context does not exist!");
std::string dnn = sp.get()->get_dnn();
if ((dnn.compare(sm_context_req_msg.get_dnn()) != 0) or
(!(sp.get()->get_snssai() == sm_context_req_msg.get_snssai()))) {
// error
Logger::smf_n1().warn("DNN/SNSSAI doesn't matched with this session!");
// trigger to send reply to AMF
smf_app_inst->trigger_update_context_error_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND,
......@@ -2486,6 +2475,14 @@ bool smf_context::handle_pdu_session_update_sm_context_request(
// TODO:
return false;
}
// Update PDU session status to PDU_SESSION_INACTIVE
sp.get()->set_pdu_session_status(
pdu_session_status_e::PDU_SESSION_INACTIVE);
// display info
Logger::smf_app().info("SMF context: \n %s", toString().c_str());
// don't need to create a procedure to update UPF
} break;
......@@ -2606,6 +2603,11 @@ bool smf_context::handle_pdu_session_update_sm_context_request(
sm_context_resp_pending->session_procedure_type =
session_management_procedures_type_e::
PDU_SESSION_RELEASE_UE_REQUESTED_STEP2;
// Update PDU session status to PDU_SESSION_INACTIVE
sp.get()->set_pdu_session_status(
pdu_session_status_e::PDU_SESSION_INACTIVE);
// don't need to create a procedure to update UPF
} break;
......@@ -2874,19 +2876,24 @@ void smf_context::handle_pdu_session_release_sm_context_request(
"Handle a PDU Session Release SM Context Request message from AMF");
bool update_upf = false;
// Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and
// pdu_session must be existed
std::shared_ptr<dnn_context> sd = {};
// Step 1. get SMF PDU session context. At this stage, pdu_session must be
// existed
std::shared_ptr<smf_pdu_session> sp = {};
bool find_dnn =
find_dnn_context(smreq->req.get_snssai(), smreq->req.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu = sd.get()->find_pdu_session(smreq->req.get_pdu_session_id(), sp);
if (!find_pdu_session(smreq->req.get_pdu_session_id(), sp)) {
// error
Logger::smf_app().warn("PDU session context does not exist!");
// trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND, smreq->pid,
N11_SESSION_RELEASE_SM_CONTEXT_RESPONSE);
return;
}
if (!find_dnn or !find_pdu) {
// error, send reply to AMF with error code "Context Not Found"
Logger::smf_app().warn("DNN or PDU session context does not exist!");
std::string dnn = sp.get()->get_dnn();
if ((dnn.compare(smreq->req.get_dnn()) != 0) or
(!(sp.get()->get_snssai() == smreq->req.get_snssai()))) {
// error
Logger::smf_n1().warn("DNN/SNSSAI doesn't matched with this session!");
// trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_404_NOT_FOUND, smreq->pid,
......@@ -2931,22 +2938,17 @@ void smf_context::handle_pdu_session_modification_network_requested(
Logger::smf_app().info(
"Handle a PDU Session Modification Request (SMF-Requested)");
std::string n1_sm_msg, n1_sm_msg_hex;
std::string n2_sm_info, n2_sm_info_hex;
std::string n1_sm_msg = {};
std::string n1_sm_msg_hex = {};
std::string n2_sm_info = {};
std::string n2_sm_info_hex = {};
// Step 1. get DNN, SMF PDU session context. At this stage, dnn_context and
// pdu_session must be existed
std::shared_ptr<dnn_context> sd = {};
// Step 1. get SMF PDU session context. At this stage, pdu_session must be
// existed
std::shared_ptr<smf_pdu_session> sp = {};
bool find_dnn =
find_dnn_context(itti_msg->msg.get_snssai(), itti_msg->msg.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu =
sd.get()->find_pdu_session(itti_msg->msg.get_pdu_session_id(), sp);
}
if (!find_dnn or !find_pdu) {
Logger::smf_app().warn("DNN or PDU session context does not exist!");
if (!find_pdu_session(itti_msg->msg.get_pdu_session_id(), sp)) {
Logger::smf_app().warn("PDU session context does not exist!");
return;
}
......@@ -3000,10 +3002,7 @@ void smf_context::handle_pdu_session_modification_network_requested(
std::string supi_str =
itti_msg->msg.get_supi_prefix() + "-" + smf_supi_to_string(supi);
std::string url =
// std::string(inet_ntoa(*((struct in_addr*)
// &smf_cfg.amf_addr.ipv4_addr))) +
//":" + std::to_string(smf_cfg.amf_addr.port) + NAMF_COMMUNICATION_BASE +
"http://" + sp.get()->get_amf_addr() + NAMF_COMMUNICATION_BASE +
"http://" + get_amf_addr() + NAMF_COMMUNICATION_BASE +
smf_cfg.amf_addr.api_version +
fmt::format(
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL, supi_str.c_str());
......@@ -3490,27 +3489,6 @@ bool smf_context::find_dnn_subscription(
return false;
}
//------------------------------------------------------------------------------
bool smf_context::find_dnn_context(
const snssai_t& nssai, const std::string& dnn,
std::shared_ptr<dnn_context>& dnn_context) {
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto it : dnns) {
if ((0 == dnn.compare(it->dnn_in_use)) and
((uint8_t) nssai.sST) == (uint8_t)(it->nssai.sST)) {
dnn_context = it;
return true;
}
}
return false;
}
//------------------------------------------------------------------------------
void smf_context::insert_dnn(std::shared_ptr<dnn_context>& sd) {
std::unique_lock<std::recursive_mutex> lock(m_context);
dnns.push_back(sd);
}
//------------------------------------------------------------------------------
bool smf_context::verify_sm_context_request(
std::shared_ptr<itti_n11_create_sm_context_request> smreq) {
......@@ -3530,11 +3508,6 @@ void smf_context::set_supi(const supi_t& s) {
supi = s;
}
//-----------------------------------------------------------------------------
std::size_t smf_context::get_number_dnn_contexts() const {
return dnns.size();
}
//-----------------------------------------------------------------------------
void smf_context::get_supi_prefix(std::string& prefix) const {
prefix = supi_prefix;
......@@ -3545,25 +3518,91 @@ void smf_context::set_supi_prefix(std::string const& prefix) {
supi_prefix = prefix;
}
//------------------------------------------------------------------------------
bool smf_context::find_pdu_session(
const pdu_session_id_t& psi, std::shared_ptr<smf_pdu_session>& sp) const {
Logger::smf_app().info("Find PDU Session with ID %d", psi);
std::shared_lock lock(m_pdu_sessions_mutex);
if (pdu_sessions.count(psi) > 0) {
sp = pdu_sessions.at(psi);
if (sp) return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool smf_context::find_pdu_session(
const pfcp::pdr_id_t& pdr_id, pfcp::qfi_t& qfi,
std::shared_ptr<dnn_context>& sd, std::shared_ptr<smf_pdu_session>& sp) {
std::unique_lock<std::recursive_mutex> lock(m_context);
for (auto it : dnns) {
for (auto session : it.get()->pdu_sessions) {
smf_qos_flow flow = {};
if (session->find_qos_flow(pdr_id, flow)) {
qfi.qfi = flow.qfi.qfi;
sp = session;
sd = it;
return true;
}
std::shared_ptr<smf_pdu_session>& sp) {
std::shared_lock lock(m_pdu_sessions_mutex);
for (auto it : pdu_sessions) {
smf_qos_flow flow = {};
if (it.second->find_qos_flow(pdr_id, flow)) {
qfi.qfi = flow.qfi.qfi;
sp = it.second;
if (sp) return true;
break;
}
}
return false;
}
//------------------------------------------------------------------------------
bool smf_context::add_pdu_session(
const pdu_session_id_t& psi, const std::shared_ptr<smf_pdu_session>& sp) {
std::unique_lock lock(
m_pdu_sessions_mutex,
std::defer_lock); // Do not lock it first
Logger::smf_app().info("Add PDU Session with Id %d", psi);
if (((uint8_t) psi >= PDU_SESSION_IDENTITY_FIRST) and
((uint8_t) psi <= PDU_SESSION_IDENTITY_LAST)) {
if (pdu_sessions.count(psi) > 0) {
Logger::smf_app().error(
"Failed to add PDU Session (Id %d), existed", psi);
return false;
} else {
lock.lock(); // Lock it here
pdu_sessions.insert(
std::pair<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>(
psi, sp));
Logger::smf_app().debug(
"PDU Session Id (%d) has been added successfully", psi);
return true;
}
} else {
Logger::smf_app().error(
"Failed to add PDU Session (Id %d) failed: invalid Id", psi);
return false;
}
}
//------------------------------------------------------------------------------
bool smf_context::remove_pdu_session(const pdu_session_id_t& psi) {
Logger::smf_app().debug(
"Failed to add PDU Session (Id %d) failed: invalid Id", psi);
std::unique_lock lock(m_pdu_sessions_mutex);
return (pdu_sessions.erase(psi) > 0);
}
//------------------------------------------------------------------------------
size_t smf_context::get_number_pdu_sessions() const {
std::shared_lock lock(m_pdu_sessions_mutex);
return pdu_sessions.size();
}
//------------------------------------------------------------------------------
void smf_context::get_pdu_sessions(
std::map<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>& sessions) {
std::shared_lock lock(m_pdu_sessions_mutex);
for (auto it : pdu_sessions) {
sessions.insert(
std::pair<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>(
it.first, it.second));
}
}
//------------------------------------------------------------------------------
void smf_context::handle_sm_context_status_change(
scid_t scid, const std::string& status, uint8_t http_version) {
......@@ -3581,6 +3620,14 @@ void smf_context::handle_sm_context_status_change(
return;
}
std::shared_ptr<smf_pdu_session> sp = {};
if (!find_pdu_session(scf.get()->pdu_session_id, sp)) {
if (sp.get() == nullptr) {
Logger::smf_n1().warn("PDU session context does not exist!");
return;
}
}
// Send request to N11 to trigger the notification
Logger::smf_app().debug(
"Send ITTI msg to SMF N11 to trigger the status notification");
......@@ -3589,7 +3636,7 @@ void smf_context::handle_sm_context_status_change(
TASK_SMF_APP, TASK_SMF_SBI);
itti_msg->scid = scid;
itti_msg->sm_context_status = status;
itti_msg->amf_status_uri = scf.get()->amf_status_uri;
itti_msg->amf_status_uri = get_amf_status_uri();
itti_msg->http_version = http_version;
int ret = itti_inst->send_msg(itti_msg);
......@@ -3768,22 +3815,9 @@ void smf_context::handle_ue_ip_change(scid_t scid, uint8_t http_version) {
supi64);
}
// get dnn context
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
Logger::smf_app().warn(
"Could not retrieve the corresponding DNN context!");
return;
}
}
// get smf_pdu_session
std::shared_ptr<smf_pdu_session> sp = {};
bool find_pdn = sd.get()->find_pdu_session(pdu_session_id, sp);
if (nullptr == sp.get()) {
if (!find_pdu_session(pdu_session_id, sp)) {
Logger::smf_app().warn(
"Could not retrieve the corresponding SMF PDU Session context!");
return;
......@@ -3889,22 +3923,10 @@ void smf_context::handle_flexcn_event(scid_t scid, uint8_t http_version) {
"Supi " SUPI_64_FMT "!",
supi64);
}
// get dnn context
std::shared_ptr<dnn_context> sd = {};
if (!sc.get()->find_dnn_context(scf.get()->nssai, scf.get()->dnn, sd)) {
if (nullptr == sd.get()) {
Logger::smf_app().warn(
"Could not retrieve the corresponding DNN context!");
return;
}
}
// get smf_pdu_session
std::shared_ptr<smf_pdu_session> sp = {};
bool find_pdn = sd.get()->find_pdu_session(pdu_session_id, sp);
if (nullptr == sp.get()) {
if (!find_pdu_session(pdu_session_id, sp)) {
Logger::smf_app().warn(
"Could not retrieve the corresponding SMF PDU Session context!");
return;
......@@ -3942,8 +3964,9 @@ void smf_context::handle_flexcn_event(scid_t scid, uint8_t http_version) {
// custom json e.g., for FlexCN
nlohmann::json cj = {};
// PLMN
plmn_t plmn = {};
std::string mcc, mnc;
plmn_t plmn = {};
std::string mcc = {};
std::string mnc = {};
sc->get_plmn(plmn);
conv::plmnToMccMnc(plmn, mcc, mnc);
cj["plmn"]["mcc"] = mcc;
......@@ -3960,15 +3983,13 @@ void smf_context::handle_flexcn_event(scid_t scid, uint8_t http_version) {
cj["ue_ipv6_prefix"] = str_addr6;
}
}
// PDU Session Type
cj["pdu_session_type"] = sp->pdu_session_type.toString();
cj["pdu_session_type"] =
sp->pdu_session_type.toString(); // PDU Session Type
// NSSAI
cj["snssai"]["sst"] = scf->nssai.sST;
cj["snssai"]["sd"] = scf->nssai.sD;
// DNN
cj["dnn"] = scf->dnn;
// Serving AMF addr
cj["amf_addr"] = scf->amf_addr;
cj["snssai"]["sst"] = sp->get_snssai().sST;
cj["snssai"]["sd"] = sp->get_snssai().sD;
cj["dnn"] = sp->get_dnn(); // DNN
cj["amf_addr"] = sc->get_amf_addr(); // Serving AMF addr
// QoS flows associated with this session
std::vector<smf_qos_flow> flows = {};
......@@ -3979,7 +4000,7 @@ void smf_context::handle_flexcn_event(scid_t scid, uint8_t http_version) {
for (auto f : flows) {
nlohmann::json tmp = {};
tmp["qfi"] = (uint8_t) f.qfi.qfi;
// UL FTeid IPv4/IPv6 (UPF)
// UL FTEID IPv4/IPv6 (UPF)
if (f.ul_fteid.v4)
tmp["upf_addr"]["ipv4"] = inet_ntoa(f.ul_fteid.ipv4_address);
if (f.ul_fteid.v6) {
......@@ -3990,7 +4011,7 @@ void smf_context::handle_flexcn_event(scid_t scid, uint8_t http_version) {
tmp["upf_addr"]["ipv6"] = str_addr6;
}
}
// DL FTeid Ipv4/v6 (AN)
// DL FTEID Ipv4/v6 (AN)
if (f.dl_fteid.v4)
tmp["an_addr"]["ipv4"] = inet_ntoa(f.dl_fteid.ipv4_address);
if (f.dl_fteid.v6) {
......@@ -4276,72 +4297,49 @@ void smf_context::get_amf_addr(std::string& addr) const {
}
//------------------------------------------------------------------------------
void smf_context::set_plmn(const plmn_t& plmn) {
this->plmn = plmn;
std::string smf_context::get_amf_addr() const {
return amf_addr;
}
//------------------------------------------------------------------------------
void smf_context::get_plmn(plmn_t& plmn) const {
plmn = this->plmn;
void smf_context::set_amf_status_uri(const std::string& status_uri) {
amf_status_uri = status_uri;
}
//------------------------------------------------------------------------------
bool smf_context::check_handover_possibility(
const ng_ran_target_id_t& ran_target_id,
const pdu_session_id_t& pdu_session_id) const {
// TODO:
return true;
void smf_context::get_amf_status_uri(std::string& status_uri) const {
status_uri = amf_status_uri;
}
//------------------------------------------------------------------------------
bool dnn_context::find_pdu_session(
const uint32_t pdu_session_id,
std::shared_ptr<smf_pdu_session>& pdu_session) {
pdu_session = {};
std::shared_lock lock(m_context);
for (auto it : pdu_sessions) {
if (pdu_session_id == it->pdu_session_id) {
pdu_session = it;
return true;
}
}
return false;
std::string smf_context::get_amf_status_uri() const {
return amf_status_uri;
}
//------------------------------------------------------------------------------
void dnn_context::insert_pdu_session(std::shared_ptr<smf_pdu_session>& sp) {
std::unique_lock lock(m_context);
pdu_sessions.push_back(sp);
void smf_context::set_target_amf(const std::string& amf) {
target_amf = amf;
}
void smf_context::get_target_amf(std::string& amf) const {
amf = target_amf;
}
std::string smf_context::get_target_amf() const {
return target_amf;
}
//------------------------------------------------------------------------------
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;
void smf_context::set_plmn(const plmn_t& plmn) {
this->plmn = plmn;
}
//------------------------------------------------------------------------------
size_t dnn_context::get_number_pdu_sessions() const {
std::shared_lock lock(m_context);
return pdu_sessions.size();
void smf_context::get_plmn(plmn_t& plmn) const {
plmn = this->plmn;
}
//------------------------------------------------------------------------------
std::string dnn_context::toString() const {
std::string s = {};
s.append("DNN CONTEXT:\n");
s.append("\tIn use:\t\t\t\t").append(std::to_string(in_use)).append("\n");
s.append("\tDNN:\t\t\t\t").append(dnn_in_use).append("\n");
for (auto it : pdu_sessions) {
s.append(it->toString());
}
return s;
bool smf_context::check_handover_possibility(
const ng_ran_target_id_t& ran_target_id,
const pdu_session_id_t& pdu_session_id) const {
// TODO:
return true;
}
......@@ -113,16 +113,43 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
public:
smf_pdu_session() : m_pdu_session_mutex() { clear(); }
smf_pdu_session(pdu_session_id_t psi)
: pdu_session_id(psi), m_pdu_session_mutex() {
ipv4 = false;
ipv6 = false;
ipv4_address.s_addr = INADDR_ANY;
ipv6_address = in6addr_any;
released = false;
dnn = {};
snssai = {};
pdu_session_type = {};
seid = 0;
up_fseid = {};
qos_flows.clear();
default_qfi.qfi = NO_QOS_FLOW_IDENTIFIER_ASSIGNED;
pdu_session_status = pdu_session_status_e::PDU_SESSION_INACTIVE;
upCnx_state = upCnx_state_e::UPCNX_STATE_DEACTIVATED;
ho_state = ho_state_e::HO_STATE_NONE;
timer_T3590 = ITTI_INVALID_TIMER_ID;
timer_T3591 = ITTI_INVALID_TIMER_ID;
timer_T3592 = ITTI_INVALID_TIMER_ID;
number_of_supported_packet_filters = 0;
maximum_number_of_supported_packet_filters = 0;
}
void clear() {
ipv4 = false;
ipv6 = false;
ipv4_address.s_addr = INADDR_ANY;
ipv6_address = in6addr_any;
released = false;
pdu_session_id = 0;
dnn = {};
snssai = {};
pdu_session_type = {};
seid = 0;
up_fseid = {};
qos_flows.clear();
released = false;
default_qfi.qfi = NO_QOS_FLOW_IDENTIFIER_ASSIGNED;
pdu_session_status = pdu_session_status_e::PDU_SESSION_INACTIVE;
upCnx_state = upCnx_state_e::UPCNX_STATE_DEACTIVATED;
......@@ -418,44 +445,69 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
pdu_session_type_t get_pdu_session_type() const;
/*
* Set AMF Addr of the serving AMF
* @param [const std::string&] addr: AMF Addr in string representation
* Set UPF Node ID of this PDU Session
* @param [const pfcp::node_id_t&] node_id: UPF Node Id
* @return void
*/
void set_amf_addr(const std::string& addr);
void set_upf_node_id(const pfcp::node_id_t& node_id);
/*
* Get AMF Addr of the serving AMF (in string representation)
* @param [const std::string&] addr: store AMF IP Addr
* Get UPF Node ID of this PDU Session
* @param [pfcp::node_id_t&] node_id: UPF Node Id
* @return void
*/
void get_amf_addr(std::string& addr) const;
std::string get_amf_addr() const;
void get_upf_node_id(pfcp::node_id_t& node_id) const;
bool ipv4; // IP Address(es): IPv4 address and/or IPv6 prefix
bool ipv6; // IP Address(es): IPv4 address and/or IPv6 prefix
struct in_addr
ipv4_address; // IP Address(es): IPv4 address and/or IPv6 prefix
struct in6_addr
ipv6_address; // IP Address(es): IPv4 address and/or IPv6 prefix
pdu_session_type_t pdu_session_type; // IPv4, IPv6, IPv4v6 or Non-IP
/*
* Get UPF Node ID of this PDU Session
* @param void
* @return UPF Node Id
*/
pfcp::node_id_t get_upf_node_id() const;
bool released; //(release access bearers request)
/*
* Get DNN associated with this PDU Session
* @param void
* @return std::string: DNN
*/
std::string get_dnn() const;
//----------------------------------------------------------------------------
// PFCP related members
//----------------------------------------------------------------------------
// PFCP Session
uint64_t seid;
pfcp::fseid_t up_fseid;
//
util::uint_generator<uint16_t> pdr_id_generator;
util::uint_generator<uint32_t> far_id_generator;
util::uint_generator<uint32_t> urr_id_generator;
/*
* Set DNN associated with this PDU Session
* @param [const std::string&] d: DNN
* @return void
*/
void set_dnn(const std::string& d);
/*
* Get SNSSAI associated with this PDU Session
* @param void
* @return snssai_t: SNSSAI
*/
snssai_t get_snssai() const;
/*
* Set SNSSAI associated with this PDU Session
* @param [const snssai_t&] s: SNSSAI
* @return void
*/
void set_snssai(const snssai_t s);
public:
bool ipv4; // IPv4 Addr
struct in_addr ipv4_address; // IPv4 Addr
bool ipv6; // IPv6 prefix
struct in6_addr ipv6_address; // IPv6 prefix
pdu_session_type_t pdu_session_type; // IPv4, IPv6, IPv4v6 or Non-IP
bool released; // release session request
uint32_t pdu_session_id;
std::string amf_id;
std::string amf_addr;
std::string dnn; // associated DNN
snssai_t snssai; // associated SNSSAI
pfcp::node_id_t upf_node_id;
pdu_session_status_e pdu_session_status;
upCnx_state_e
upCnx_state; // N3 tunnel status (ACTIVATED, DEACTIVATED, ACTIVATING)
......@@ -478,6 +530,15 @@ class smf_pdu_session : public std::enable_shared_from_this<smf_pdu_session> {
number_of_supported_packet_filters; // number_of_supported_packet_filters
util::uint_generator<uint32_t> qos_rule_id_generator;
// PFCP related members
// PFCP Session
uint64_t seid;
pfcp::fseid_t up_fseid;
//
util::uint_generator<uint16_t> pdr_id_generator;
util::uint_generator<uint32_t> far_id_generator;
util::uint_generator<uint32_t> urr_id_generator;
// Shared lock
mutable std::shared_mutex m_pdu_session_mutex;
};
......@@ -524,78 +585,24 @@ class session_management_subscription {
mutable std::shared_mutex m_mutex;
};
/*
* Manage the DNN context
*/
class dnn_context {
public:
dnn_context() : m_context(), in_use(false), pdu_sessions(), nssai() {}
dnn_context(std::string dnn)
: m_context(), in_use(false), pdu_sessions(), nssai(), dnn_in_use(dnn) {}
dnn_context(dnn_context& b) = delete;
/*
* Find a PDU Session by its ID
* @param [const uint32_t] pdu_session_id
* @param [std::shared_ptr<smf_pdu_session> &] pdu_session
* @return bool: return true if pdu session is found, otherwise, return false
*/
bool find_pdu_session(
const uint32_t pdu_session_id,
std::shared_ptr<smf_pdu_session>& pdu_session);
/*
* Insert a PDU Session into the DNN context
* @param [std::shared_ptr<smf_pdu_session> &] sp: shared pointer to a PDU
* Session
* @return void
*/
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
* @return size_t: number of PDU sessions
*/
size_t get_number_pdu_sessions() const;
/*
* Represent DNN Context as a string object
* @param void
* @return void
*/
std::string toString() const;
bool in_use;
std::string dnn_in_use; // The DNN currently used, as received from the AMF
snssai_t nssai;
std::vector<std::shared_ptr<smf_pdu_session>>
pdu_sessions; // Store all PDU Sessions associated with this DNN context
mutable std::shared_mutex m_context;
};
class smf_context;
class smf_context : public std::enable_shared_from_this<smf_context> {
public:
smf_context()
: m_context(),
m_pdu_sessions_mutex(),
pdu_sessions(),
pending_procedures(),
dnn_subscriptions(),
event_sub(),
plmn() {
supi_prefix = {};
// Subscribe to SM Context Status change (to notify to AMF)
amf_id = {};
amf_addr = {};
amf_status_uri = {};
target_amf = {};
supi_prefix = {};
// Subscribe to SM Context Status Change
sm_context_status_connection =
event_sub.subscribe_sm_context_status(boost::bind(
&smf_context::handle_sm_context_status_change, this, _1, _2, _3));
......@@ -661,9 +668,6 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
*/
void remove_procedure(smf_procedure* proc);
#define IS_FIND_PDN_WITH_LOCAL_TEID true
#define IS_FIND_PDN_WITH_PEER_TEID false
/*
* Handle N4 message (session establishment response) from UPF
* @param [itti_n4_session_establishment_responset&]
......@@ -957,24 +961,6 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
std::shared_ptr<itti_n11_update_sm_context_response>& sm_context_resp,
std::shared_ptr<smf_pdu_session>& sp);
/*
* Find DNN context with name
* @param [const std::string&] dnn
* @param [std::shared_ptr<dnn_context>&] dnn_context dnn context to be found
* @return void
*/
bool find_dnn_context(
const snssai_t& nssai, const std::string& dnn,
std::shared_ptr<dnn_context>& dnn_context);
/*
* Insert a DNN context into SMF context
* @param [std::shared_ptr<dnn_context>&] sd Shared_ptr pointer to a DNN
* context
* @return void
*/
void insert_dnn(std::shared_ptr<dnn_context>& sd);
/*
* Check the validity of the request according to user subscription and local
* policies
......@@ -1060,13 +1046,6 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
*/
supi_t get_supi() const;
/*
* Get the number of dnn contexts
* @param
* @return std::size_t: the number of contexts
*/
std::size_t get_number_dnn_contexts() const;
/*
* Get Supi prefix
* @param [const std::string &] prefix: Supi prefix (e.g., imsi)
......@@ -1125,16 +1104,49 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
const snssai_t& snssai, const std::string& dnn);
/*
* Find the PDU Session, QFI associated with a given PDR_ID
* @param [const pfcp::pdr_id_t &] pdr_id: PDR ID
* @param [pfcp::qfi_t &] qfi: QFI
* @param [std::shared_ptr<dnn_context> &] sd: pointer to the DNN context
* Find the PDU Session with its ID
* @param [const pdu_session_id_t &] psi: PDU Session ID
* @param [std::shared_ptr<smf_pdu_session> &] sp: pointer to the PDU session
* @return bool: return true if found, otherwise return false
*/
bool find_pdu_session(
const pdu_session_id_t& psi, std::shared_ptr<smf_pdu_session>& sp) const;
bool find_pdu_session(
const pfcp::pdr_id_t& pdr_id, pfcp::qfi_t& qfi,
std::shared_ptr<dnn_context>& sd, std::shared_ptr<smf_pdu_session>& sp);
std::shared_ptr<smf_pdu_session>& sp);
/*
* Add a PDU Session to the PDU Session List
* @param [const pdu_session_id_t &] psi: PDU Session ID
* @param [const std::shared_ptr<smf_pdu_session> &] sp: pointer to the PDU
* session
* @return bool: return true if found, otherwise return false
*/
bool add_pdu_session(
const pdu_session_id_t& psi, const std::shared_ptr<smf_pdu_session>& sp);
/*
* Remove a PDU Session from the PDU Session List
* @param [const pdu_session_id_t &] psi: PDU Session ID
* @return bool: return true if success, otherwise return false
*/
bool remove_pdu_session(const pdu_session_id_t& psi);
/*
* Get number of pdu sessions associated with this context
* @param void
* @return size_t: number of PDU sessions
*/
size_t get_number_pdu_sessions() const;
/*
* Get all the PDU Sessions
* @param [std::map<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>&]
* sessions: all PDU sessions
* @return void
*/
void get_pdu_sessions(
std::map<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>& sessions);
/*
* Handle SM Context Status Change (Send notification AMF)
......@@ -1190,11 +1202,60 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
/*
* Get AMF Addr of the serving AMF (in string representation)
* @param [const std::string&] addr: store AMF IP Addr
* @param [std::string&] addr: store AMF IP Addr
* @return void
*/
void get_amf_addr(std::string& addr) const;
/*
* Get AMF Addr of the serving AMF (in string representation)
* @param void
* @return string: AMF IP Addr
*/
std::string get_amf_addr() const;
/*
* Set the URI of AMF for receiving context status update
* @param [const std::string&] status_uri: AMF's URI
* @return void
*/
void set_amf_status_uri(const std::string& status_uri);
/*
* Get the URI of AMF for receiving context status update
* @param [std::string&] status_uri: AMF's URI
* @return void
*/
void get_amf_status_uri(std::string& status_uri) const;
/*
* Get the URI of AMF for receiving context status update
* @param void
* @return string
*/
std::string get_amf_status_uri() const;
/*
* Set target AMF in case of HO
* @param [const std::string&] amf: Target AMF
* @return void
*/
void set_target_amf(const std::string& amf);
/*
* Get target AMF in case of HO
* @param [std::string&] amf: Target AMF
* @return void
*/
void get_target_amf(std::string& amf) const;
/*
* Get target AMF in case of HO
* @param void
* @return std::string
*/
std::string get_target_amf() const;
/*
* Set PLMN
* @param [const plmn_t&] plmn: PLMN
......@@ -1221,17 +1282,23 @@ class smf_context : public std::enable_shared_from_this<smf_context> {
const pdu_session_id_t& pdu_session_id) const;
private:
std::vector<std::shared_ptr<dnn_context>> dnns;
std::vector<std::shared_ptr<smf_procedure>> pending_procedures;
// snssai-sst <-> session management subscription
std::map<uint8_t, std::shared_ptr<session_management_subscription>>
dnn_subscriptions;
std::map<pdu_session_id_t, std::shared_ptr<smf_pdu_session>>
pdu_sessions; // Store all PDU Sessions associated with this UE
mutable std::shared_mutex m_pdu_sessions_mutex;
supi_t supi;
std::string supi_prefix;
plmn_t plmn;
// AMF IP addr
string amf_addr;
std::string amf_id;
std::string amf_addr;
std::string amf_status_uri;
std::string target_amf; // targetServingNfId
// Big recursive lock
mutable std::recursive_mutex m_context;
......
......@@ -416,7 +416,6 @@ bool smf_n1::create_n1_pdu_session_modification_command(
// Get the SMF_PDU_Session
std::shared_ptr<smf_context> sc = {};
std::shared_ptr<dnn_context> sd = {};
std::shared_ptr<smf_pdu_session> sp = {};
supi_t supi = sm_context_res.get_supi();
supi64_t supi64 = smf_supi_to_u64(supi);
......@@ -430,16 +429,21 @@ bool smf_n1::create_n1_pdu_session_modification_command(
return false;
}
bool find_dnn = sc.get()->find_dnn_context(
sm_context_res.get_snssai(), sm_context_res.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu =
sd.get()->find_pdu_session(sm_context_res.get_pdu_session_id(), sp);
if (!sc.get()->find_pdu_session(sm_context_res.get_pdu_session_id(), sp)) {
Logger::smf_n1().warn("PDU session context does not exist!");
return false;
}
std::string dnn = sp.get()->get_dnn();
if (dnn.compare(sm_context_res.get_dnn()) != 0) {
// error
Logger::smf_n1().warn("DNN doesn't matched with this session!");
return false;
}
if (!find_dnn or !find_pdu) {
if (!(sp.get()->get_snssai() == sm_context_res.get_snssai())) {
// error
Logger::smf_n1().warn("DNN or PDU session context does not exist!");
Logger::smf_n1().warn("SNSSAI doesn't matched with this session!");
return false;
}
......@@ -554,7 +558,6 @@ bool smf_n1::create_n1_pdu_session_modification_command(
// Get the SMF_PDU_Session
std::shared_ptr<smf_context> sc = {};
std::shared_ptr<dnn_context> sd = {};
std::shared_ptr<smf_pdu_session> sp = {};
supi_t supi = msg.get_supi();
supi64_t supi64 = smf_supi_to_u64(supi);
......@@ -568,17 +571,24 @@ bool smf_n1::create_n1_pdu_session_modification_command(
return false;
}
bool find_dnn =
sc.get()->find_dnn_context(msg.get_snssai(), msg.get_dnn(), sd);
bool find_pdu = false;
if (find_dnn) {
find_pdu = sd.get()->find_pdu_session(msg.get_pdu_session_id(), sp);
if (!sc.get()->find_pdu_session(msg.get_pdu_session_id(), sp)) {
Logger::smf_n1().warn("PDU session context does not exist!");
return false;
}
if (!find_dnn or !find_pdu) {
std::string dnn = sp.get()->get_dnn();
if (dnn.compare(msg.get_dnn()) != 0) {
// error
Logger::smf_n1().warn("DNN or PDU session context does not exist!");
Logger::smf_n1().warn("DNN doesn't matched with this session!");
return false;
}
/*
if (!(sp.get()->get_snssai() == msg.get_snssai())){
// error
Logger::smf_n1().warn("SNSSAI doesn't matched with this
session!"); return false;
}
*/
sm_msg->header.procedure_transaction_identity =
msg.get_pti().procedure_transaction_id;
......
......@@ -102,9 +102,10 @@ int session_create_sm_context_procedure::run(
std::shared_ptr<smf::smf_context> sc) {
Logger::smf_app().info("Perform a procedure - Create SM Context Request");
// TODO check if compatible with ongoing procedures if any
pfcp::node_id_t up_node_id = {};
snssai_t snssai = sm_context_req->req.get_snssai();
std::string dnn = sm_context_req->req.get_dnn();
pfcp::node_id_t up_node_id = {};
snssai_t snssai = sm_context_req->req.get_snssai();
std::string dnn = sm_context_req->req.get_dnn();
pdu_session_id_t pdu_session_id = sm_context_req->req.get_pdu_session_id();
if (not pfcp_associations::get_instance().select_up_node(
up_node_id, snssai, dnn)) {
......@@ -116,7 +117,16 @@ int session_create_sm_context_procedure::run(
std::shared_ptr<smf_context_ref> scf = {};
if (smf_app_inst->is_scid_2_smf_context(sm_context_req->scid)) {
scf = smf_app_inst->scid_2_smf_context(sm_context_req->scid);
scf.get()->upf_node_id = up_node_id;
// scf.get()->upf_node_id = up_node_id;
std::shared_ptr<smf_pdu_session> sp = {};
if (!sc.get()->find_pdu_session(scf.get()->pdu_session_id, sp)) {
Logger::smf_app().warn("PDU session context does not exist!");
sm_context_resp->res.set_cause(
PDU_SESSION_APPLICATION_ERROR_CONTEXT_NOT_FOUND);
return RETURNerror;
}
sp.get()->set_upf_node_id(up_node_id);
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!",
......@@ -466,7 +476,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
std::string supi_str = n11_triggered_pending->res.get_supi_prefix() + "-" +
smf_supi_to_string(supi);
std::string url =
"http://" + sps.get()->get_amf_addr() + NAMF_COMMUNICATION_BASE +
"http://" + sc.get()->get_amf_addr() + NAMF_COMMUNICATION_BASE +
smf_cfg.amf_addr.api_version +
fmt::format(
NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL, supi_str.c_str());
......@@ -499,7 +509,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
// N1N2MsgTxfrFailureNotification
std::string callback_uri =
sps.get()->get_amf_addr() + NSMF_PDU_SESSION_BASE +
sc.get()->get_amf_addr() + NSMF_PDU_SESSION_BASE +
smf_cfg.sbi_api_version +
fmt::format(
NSMF_CALLBACK_N1N2_MESSAGE_TRANSFER_FAILURE, supi_str.c_str());
......@@ -550,14 +560,22 @@ int session_update_sm_context_procedure::run(
sm_context_req->scid);
}
if (smf_app_inst->is_scid_2_smf_context(scid)) {
scf = smf_app_inst->scid_2_smf_context(scid);
up_node_id = scf.get()->upf_node_id;
scf = smf_app_inst->scid_2_smf_context(scid);
// up_node_id = scf.get()->upf_node_id;
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!", scid);
// TODO:
return RETURNerror;
}
std::shared_ptr<smf_pdu_session> sp = {};
if (!sc.get()->find_pdu_session(scf.get()->pdu_session_id, sp)) {
Logger::smf_app().warn("PDU session context does not exist!");
return RETURNerror;
}
sp.get()->get_upf_node_id(up_node_id);
// TODO: UPF insertion in case of Handover
/* if (not pfcp_associations::get_instance().select_up_node(
......@@ -1445,14 +1463,23 @@ int session_release_sm_context_procedure::run(
sm_context_req->scid);
}
if (smf_app_inst->is_scid_2_smf_context(scid)) {
scf = smf_app_inst->scid_2_smf_context(scid);
up_node_id = scf.get()->upf_node_id;
scf = smf_app_inst->scid_2_smf_context(scid);
// up_node_id = scf.get()->upf_node_id;
} else {
Logger::smf_app().warn(
"SM Context associated with this id " SCID_FMT " does not exit!", scid);
// TODO:
return RETURNerror;
}
std::shared_ptr<smf_pdu_session> sp = {};
if (!sc.get()->find_pdu_session(scf.get()->pdu_session_id, sp)) {
Logger::smf_app().warn("PDU session context does not exist!");
return RETURNerror;
}
sp.get()->get_upf_node_id(up_node_id);
/* if (not pfcp_associations::get_instance().select_up_node(
up_node_id, NODE_SELECTION_CRITERIA_MIN_PFCP_SESSIONS)) {
sm_context_res->res.set_cause(
......
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