Commit 50e9f49e authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

update response code/add Service Request (step 1)

parent 6ec237d7
......@@ -55,20 +55,6 @@ cd /oai-cn5g-smf/build/scripts
cd /oai-cn5g-smf/build/scripts
./smf_conf.sh
## launch SMF
sudo smf -c /usr/local/etc/oai/smf.conf -o
## Build UPF (SPGWU) and Launch UPF (SPGWU)
git clone https://github.com/OPENAIRINTERFACE/openair-cn-cups/
cd /openair-cn-cups/build/scripts
./build_spgwu -I -f
./build_spgwu -c -V -b Debug -j
#configure SPGWU using an example configure file (spgw_u.conf)
cd /oai-cn5g-smf/src/test/upf/
./spgwu_conf.sh
sudo spgwu -c /usr/local/etc/oai/spgw_u.conf -o
## Build and launch UDM
cd /oai-cn5g-smf/src/test/udm
mkdir build
......@@ -85,6 +71,22 @@ cmake ..
make
sudo ./amf-server -i 172.16.1.102
## launch SMF
sudo smf -c /usr/local/etc/oai/smf.conf -o
## Build UPF (SPGWU) and Launch UPF (SPGWU)
git clone https://github.com/OPENAIRINTERFACE/openair-cn-cups/
cd /openair-cn-cups/build/scripts
./build_spgwu -I -f
./build_spgwu -c -V -b Debug -j
#configure SPGWU using an example configure file (spgw_u.conf)
cd /oai-cn5g-smf/src/test/upf/
./spgwu_conf.sh
sudo spgwu -c /usr/local/etc/oai/spgw_u.conf -o
## Build and launch AMF client
cd /oai-cn5g-smf/src/test/amf_client
mkdir build
......
......@@ -31,14 +31,14 @@ void IndividualPDUSessionHSMFApiImpl::release_pdu_session(
const std::string &pduSessionRef, const ReleaseData &releaseData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("release_pdu_session...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Release_pdu_session API has not been implemented yet!\n");
}
void IndividualPDUSessionHSMFApiImpl::update_pdu_session(
const std::string &pduSessionRef, const HsmfUpdateData &hsmfUpdateData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("update_pdu_session...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Update_pdu_session API has not been implemented yet!\n");
}
......
......@@ -90,7 +90,7 @@ void IndividualSMContextApiImpl::retrieve_sm_context(
const SmContextRetrieveData &smContextRetrieveData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("retrieve_sm_context...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Retrieve_sm_context API has not been implemented yet!\n");
}
......@@ -130,13 +130,13 @@ void IndividualSMContextApiImpl::update_sm_context(
/* UE-initiated Service Request Operation, section 4.2.3.2@3GPP TS 23.502 */
//Step 4: PDU Session IDs, Operation Type, UE location Info, Access Type, RAT Type, UE presence in LADN service area, Indication of Access Type can be changed
//PDU Session IDs
//UpCnxState, for activation of user plane (see 5.2.2.3.2.2@3GPP TS 29.502)
//UpCnxState, for activation of user plane (see 5.2.2.3.2.2@3GPP TS 29.502, step 1)
if (smContextUpdateData.upCnxStateIsSet())
sm_context_req_msg.set_upCnx_state(smContextUpdateData.getUpCnxState());
//Access Type
//Access Type (step 1 and 2)
if (smContextUpdateData.anTypeIsSet())
sm_context_req_msg.set_an_type(smContextUpdateData.getAnType());
//RAT Type
//RAT Type (step 1 and 2)
if (smContextUpdateData.ratTypeIsSet())
sm_context_req_msg.set_rat_type(smContextUpdateData.getRatType());
//TODO:
......
......@@ -31,7 +31,7 @@ void PDUSessionsCollectionApiImpl::post_pdu_sessions(
const PduSessionCreateData &pduSessionCreateData,
Pistache::Http::ResponseWriter &response) {
Logger::smf_api_server().info("post_pdu_sessions...");
response.send(Pistache::Http::Code::Ok,
response.send(Pistache::Http::Code::Not_Implemented,
"Post_pdu_sessions API has not been implemented yet!\n");
}
......
......@@ -257,6 +257,7 @@ smf_app::smf_app(const std::string &config_file)
supi2smf_context = { };
set_seid_n4 = { };
seid_n4_generator = 0;
apply_config(smf_cfg);
......@@ -771,7 +772,7 @@ void smf_app::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
Pistache::Http::Code::Not_Found);
return;
}
......@@ -787,7 +788,7 @@ void smf_app::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
Pistache::Http::Code::Not_Found);
return;
}
......@@ -814,7 +815,7 @@ void smf_app::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
Pistache::Http::Code::Not_Found);
return;
}
......@@ -831,7 +832,7 @@ void smf_app::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
Pistache::Http::Code::Not_Found);
return;
}
}
......
......@@ -1513,7 +1513,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
Pistache::Http::Code::Not_Found, n1_sm_msg_hex);
return;
}
......@@ -1536,7 +1536,7 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden, n1_sm_msg_hex);
Pistache::Http::Code::Not_Found, n1_sm_msg_hex);
return;
}
......@@ -1643,17 +1643,23 @@ void smf_context::handle_pdu_session_update_sm_context_request(
//decode N2 SM Info
switch (n2_sm_info_type) {
//UE-Requested PDU Session Establishment procedure (Section 4.3.2.2.1@3GPP TS 23.502)
//or UE Triggered Service Request Procedure (step 2)
case n2_sm_info_type_e::PDU_RES_SETUP_RSP: {
//PDU Session Resource Setup Response Transfer is included in the following procedures:
//1 - UE-Requested PDU Session Establishment procedure (Section 4.3.2.2.1@3GPP TS 23.502)
//2 - UE Triggered Service Request Procedure (step 2)
Logger::smf_app().info("PDU_RES_SETUP_RSP");
Logger::smf_app().info(
"PDU Session Establishment Request, processing N2 SM Information");
//PDU_SESSION_ESTABLISHMENT_UE_REQUESTED & SERVICE_REQUEST_UE_TRIGGERED
procedure_type =
session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED;
//procedure_type = session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP2;
if (sm_context_req_msg.rat_type_is_set()
and sm_context_req_msg.an_type_is_set()) {
procedure_type =
session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP2;
}
//Ngap_PDUSessionResourceSetupResponseTransfer
std::shared_ptr<Ngap_PDUSessionResourceSetupResponseTransfer_t> decoded_msg =
......@@ -1857,6 +1863,9 @@ void smf_context::handle_pdu_session_update_sm_context_request(
if (!sm_context_req_msg.n1_sm_msg_is_set()
and !sm_context_req_msg.n2_sm_info_is_set()
and sm_context_req_msg.upCnx_state_is_set()) {
Logger::smf_app().info("SERVICE_REQUEST_UE_TRIGGERED_STEP1");
Logger::smf_app().info("Service Request (UE-triggered)");
procedure_type =
session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1;
//if request accepted-> set unCnxState to ACTIVATING
......@@ -1871,7 +1880,13 @@ void smf_context::handle_pdu_session_update_sm_context_request(
}
//need update UPF
update_upf = true;
//TODO: to be completed
//Accept the activation of UP connection and continue to using the current UPF
//TODO: Accept the activation of UP connection and select a new UPF
//Reject the activation of UP connection
//SMF fails to find a suitable I-UPF: i) trigger re-establishment of PDU Session;
//or ii) keep PDU session but reject the activation of UP connection;
//or iii) release PDU session
}
......@@ -1900,29 +1915,64 @@ void smf_context::handle_pdu_session_update_sm_context_request(
insert_procedure(sproc);
if (proc->run(smreq, sm_context_resp_pending, shared_from_this())) {
// error !
Logger::smf_app().info("PDU Update SM Context Request procedure failed");
Logger::smf_app().info(
"PDU Update SM Context Request procedure failed (session procedure type %s)",
session_management_procedures_type_e2str[static_cast<int>(procedure_type)]
.c_str());
remove_procedure(proc);
//send error to AMF
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_NETWORK_FAILURE]);
smContextUpdateError.setError(problem_details);
//TODO: need to verify with/without N1 SM
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
//send error to AMF according to the procedure
switch (procedure_type) {
case session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED: {
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING]);
smContextUpdateError.setError(problem_details);
//TODO: need to verify with/without N1 SM
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
}
break;
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_SMF_REQUESTED:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_AN_REQUESTED:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP2:
case session_management_procedures_type_e::PDU_SESSION_RELEASE_AMF_INITIATED:
case session_management_procedures_type_e::PDU_SESSION_RELEASE_UE_REQUESTED_STEP1: {
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
}
break;
default: {
//TODO: to be updated
problem_details.setCause(
pdu_session_application_error_e2str[PDU_SESSION_APPLICATION_ERROR_PEER_NOT_RESPONDING]);
smContextUpdateError.setError(problem_details);
smf_n11_inst->send_pdu_session_update_sm_context_response(
smreq->http_response, smContextUpdateError,
Pistache::Http::Code::Forbidden);
}
}
return;
}
}
//TODO, Step 5.
//TODO, Step 6
/* If the PDU Session establishment is not successful, the SMF informs the AMF by invoking Nsmf_PDUSession_SMContextStatusNotify (Release). The SMF also releases any N4
session(s) created, any PDU Session address if allocated (e.g. IP address) and releases the association with PCF,
if any. In this case, step 19 is skipped.
......
......@@ -411,14 +411,27 @@ bool pdu_session_update_sm_context_request::upCnx_state_is_set() const {
void pdu_session_update_sm_context_request::set_rat_type(
std::string const &value) {
m_rat_type = value;
m_rat_type_is_set = true;
}
//-----------------------------------------------------------------------------
bool pdu_session_update_sm_context_request::rat_type_is_set() const {
return m_rat_type_is_set;
}
//-----------------------------------------------------------------------------
void pdu_session_update_sm_context_request::set_an_type(
std::string const &value) {
m_an_type = value;
m_an_type_is_set = true;
}
//-----------------------------------------------------------------------------
bool pdu_session_update_sm_context_request::an_type_is_set() const {
return m_an_type_is_set;
}
//-----------------------------------------------------------------------------
bool pdu_session_update_sm_context_request::release_is_set() const {
return m_release_is_set;
......
......@@ -407,6 +407,10 @@ class pdu_session_update_sm_context_request : public pdu_session_msg {
m_upCnx_state_is_set = false;
qfis = { };
dl_fteid = { };
m_release = false;
m_release_is_set = false;
m_an_type_is_set = false;
m_rat_type_is_set = false;
// m_eps_bearer_setup = {};
// m_revoke_ebi_list = {};
}
......@@ -427,7 +431,9 @@ class pdu_session_update_sm_context_request : public pdu_session_msg {
void set_upCnx_state(std::string const &value);
bool upCnx_state_is_set() const;
void set_rat_type(std::string const &value);
bool rat_type_is_set() const;
void set_an_type(std::string const &value);
bool an_type_is_set() const;
bool release_is_set() const;
void set_release(bool const value);
......@@ -442,7 +448,9 @@ class pdu_session_update_sm_context_request : public pdu_session_msg {
std::string m_n2_sm_info_type;
std::string m_nf_instanceId;
std::string m_an_type;
bool m_an_type_is_set;
std::string m_rat_type;
bool m_rat_type_is_set;
std::string m_upCnx_state;
bool m_upCnx_state_is_set;
std::string m_target_serving_nfId;
......
......@@ -518,8 +518,70 @@ int session_update_sm_context_procedure::run(
Logger::smf_app().debug("qfi to be modified: %d", i.qfi);
}
Logger::smf_app().debug(
"Update SM Context procedure, session_procedure_type: %s",
session_management_procedures_type_e2str[static_cast<int>(session_procedure_type)]
.c_str());
switch (session_procedure_type) {
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1: {
//PFCP Session Modification to delete AN Tunnel info
for (auto qfi : list_of_qfis_to_be_modified) {
smf_qos_flow qos_flow = { };
if (!ppc->get_qos_flow(qfi, qos_flow)) { //no QoS flow found
Logger::smf_app().error(
"Update SM Context procedure: could not found QoS flow with QFI %d",
qfi.qfi);
//Set cause to SYSTEM_FAILURE and send response
qos_flow_context_updated qcu = { };
qcu.set_cause(SYSTEM_FAILURE);
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
continue;
}
pfcp::far_id_t far_id = { };
pfcp::pdr_id_t pdr_id = { };
//if FAR DL exist -> remove it
if ((qos_flow.far_id_dl.first) && (qos_flow.far_id_dl.second.far_id)) {
Logger::smf_app().debug("Update SM Context procedure: send a request to remove FAR DL at UPF");
// Remove FAR
far_id.far_id = qos_flow.far_id_dl.second.far_id;
pfcp::remove_far remove_far = { };
remove_far.set(qos_flow.far_id_dl.second);
n4_ser->pfcp_ies.set(remove_far);
send_n4 = true;
//qos_flow.far_id_dl.first = true;
}
//remove PDR DL if exist
if (qos_flow.pdr_id_dl.rule_id) {
Logger::smf_app().debug("Update SM Context procedure: send a request to remove PDR DL at UPF");
//Remove PDR DL
pdr_id.rule_id = qos_flow.pdr_id_dl.rule_id;
pfcp::remove_pdr remove_pdr = { };
remove_pdr.set(qos_flow.pdr_id_dl);
n4_ser->pfcp_ies.set(remove_pdr);
send_n4 = true;
}
// may be modified
smf_qos_flow qos_flow2 = qos_flow;
ppc->add_qos_flow(qos_flow2);
qos_flow_context_updated qcu = { };
qcu.set_cause(REQUEST_ACCEPTED);
qcu.set_qfi(qfi);
n11_triggered_pending->res.add_qos_flow_context_updated(qcu);
}
}
break;
case session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED:
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP2:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_SMF_REQUESTED:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_AN_REQUESTED:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_UE_INITIATED_STEP2: {
......@@ -750,7 +812,7 @@ int session_update_sm_context_procedure::run(
} else {
Logger::smf_app().info(
"Update SM Context procedure , could not get FAR ID of QoS Flow ID %d",
"Update SM Context procedure, could not get FAR ID of QoS Flow ID %d",
qos_flow.qfi.qfi);
}
......@@ -831,7 +893,57 @@ void session_update_sm_context_procedure::handle_itti_msg(
std::vector<pfcp::qfi_t> list_of_qfis_to_be_modified = { };
n11_trigger->req.get_qfis(list_of_qfis_to_be_modified);
Logger::smf_app().debug(
"Update SM Context procedure, session_procedure_type: %s",
session_management_procedures_type_e2str[static_cast<int>(session_procedure_type)]
.c_str());
switch (session_procedure_type) {
case session_management_procedures_type_e::SERVICE_REQUEST_UE_TRIGGERED_STEP1: {
if (cause.cause_value == CAUSE_VALUE_REQUEST_ACCEPTED) {
Logger::smf_app().info(
"PDU Session Update SM Context (Service Request- step1) accepted by UPF");
//delete AN Info
std::map<uint8_t, qos_flow_context_updated> qos_flow_context_to_be_updateds =
{ };
n11_triggered_pending->res.get_all_qos_flow_context_updateds(
qos_flow_context_to_be_updateds);
n11_triggered_pending->res.remove_all_qos_flow_context_updateds();
for (auto it : qos_flow_context_to_be_updateds)
Logger::smf_app().debug("qos_flow_context_to_be_modifieds qfi %d",
it.first);
for (auto it : qos_flow_context_to_be_updateds) {
smf_qos_flow qos_flow = { };
if (!ppc->get_qos_flow(it.second.qfi, qos_flow)) { //no QoS flow found
Logger::smf_app().error(
"Update SM Context procedure: could not found QoS flow with QFI %d",
it.first);
continue;
}
//if FAR DL exist -> remove it
if ((qos_flow.far_id_dl.first)
&& (qos_flow.far_id_dl.second.far_id)) {
Logger::smf_app().debug(
"Update SM Context procedure: FAR DL %d has been removed", qos_flow.far_id_dl.second.far_id);
qos_flow.far_id_dl.first = false;
qos_flow.far_id_dl.second.far_id = 0;
}
//remove PDR DL if exist
if (qos_flow.pdr_id_dl.rule_id) {
Logger::smf_app().debug(
"Update SM Context procedure: PDR DL %d has been removed", qos_flow.pdr_id_dl.rule_id);
qos_flow.pdr_id_dl.rule_id = 0;
}
// Update QoS Flow
smf_qos_flow qos_flow2 = qos_flow;
ppc->add_qos_flow(qos_flow2);
}
}
}
break;
case session_management_procedures_type_e::PDU_SESSION_ESTABLISHMENT_UE_REQUESTED:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_SMF_REQUESTED:
case session_management_procedures_type_e::PDU_SESSION_MODIFICATION_AN_REQUESTED:
......@@ -1045,10 +1157,21 @@ void session_update_sm_context_procedure::handle_itti_msg(
n11_triggered_pending->res.set_n2_sm_information(n2_sm_info_hex);
//fill the content of SmContextUpdatedData
n11_triggered_pending->res.sm_context_updated_data =
sm_context_updated_data;
n11_triggered_pending->res.sm_context_updated_data = { };
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
n11_triggered_pending->res.get_pdu_session_id();
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] =
N2_SM_CONTENT_ID;
n11_triggered_pending->res.sm_context_updated_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
"PDU_RES_SETUP_REQ"; //NGAP message
n11_triggered_pending->res.sm_context_updated_data["upCnxState"] = "ACTIVATING";
//TODO: verify whether cause is needed (as in 23.502 but not in 3GPP TS 29.502)
//Update upCnxState to ACTIVATING
ppc->set_upCnx_state(upCnx_state_e::UPCNX_STATE_ACTIVATING);
}
break;
......
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