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

Merge branch 'dsTest' into 'develop'

Test with dsTester

See merge request oai/oai-cn5g-smf!14
parents 9a00386f 59a46d6e
......@@ -173,11 +173,15 @@ void SMContextsCollectionApiImpl::post_sm_contexts(
Logger::smf_api_server().debug("Got result for promise ID %d", promise_id);
nlohmann::json json_data = { };
response.headers().add < Pistache::Http::Header::Location
> (sm_context_response.get_smf_context_uri()); //Location header
sm_context_response.get_json_data(json_data);
if (!json_data.empty()) {
response.headers().add<Pistache::Http::Header::ContentType>(
Pistache::Http::Mime::MediaType("application/json"));
response.send(Pistache::Http::Code(sm_context_response.get_http_code()), json_data.dump().c_str());
response.headers().add < Pistache::Http::Header::ContentType
> (Pistache::Http::Mime::MediaType("application/json"));
response.send(Pistache::Http::Code(sm_context_response.get_http_code()),
json_data.dump().c_str());
} else {
response.send(Pistache::Http::Code(sm_context_response.get_http_code()));
}
......
......@@ -85,6 +85,7 @@ void SMFApiServer::init(size_t thr) {
}
void SMFApiServer::start() {
Logger::smf_api_server().info("HTTP1 server started");
m_httpEndpoint->setHandler(m_router->handler());
m_httpEndpoint->serve();
......
......@@ -49,8 +49,9 @@ using namespace oai::smf_server::model;
void smf_http2_server::start() {
boost::system::error_code ec;
Logger::smf_api_server().info("HTTP2 server started");
//Create SM Context Request
server.handle("/nsmf-pdusession/v2/sm-contexts",
server.handle(NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL,
[&](const request &request, const response &response) {
request.on_data([&](const uint8_t *data, std::size_t len) {
......@@ -130,7 +131,7 @@ void smf_http2_server::start() {
});
//Update SM Context Request
server.handle("/nsmf-pdusession/v2/sm-contexts/",
server.handle(NSMF_PDU_SESSION_SM_CONTEXT_UPDATE_URL,
[&](const request &request, const response &response) {
request.on_data([&](const uint8_t *data, std::size_t len) {
......
......@@ -76,6 +76,13 @@ typedef struct s_nssai // section 28.4, TS23.003
sST(p.sST),
sD(p.sD) {
}
bool operator==(const struct s_nssai &s) const {
if ((s.sST == this->sST) && (s.sD.compare(this->sD) == 0)) {
return true;
} else {
return false;
}
}
} snssai_t;
......@@ -171,11 +178,15 @@ typedef struct qos_profile_s {
} parameter;
} qos_profile_t;
#define NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL "/namf-comm/v2/ue-contexts/{}/n1-n2-messages" //may get from configuration file
#define NUDM_SDM_GET_SM_DATA_URL "/nudm-sdm/v2/{}/sm-data" //may get from configuration file
//URL, N1, N2 (may get from configuration file)
#define NAMF_COMMUNICATION_N1N2_MESSAGE_TRANSFER_URL "/namf-comm/v2/ue-contexts/{}/n1-n2-messages" //context id
#define NUDM_SDM_GET_SM_DATA_URL "/nudm-sdm/v2/{}/sm-data" //ue Id
#define N1_SM_CONTENT_ID "n1SmMsg"
#define N1N2_MESSAGE_CLASS "SM"
#define N2_SM_CONTENT_ID "n2SmMsg"
#define N2_SM_CONTENT_ID "n2msg"
#define NSMF_CALLBACK_N1N2_MESSAGE_TRANSFER_FAILURE "/nsmf-pdusession/v2/callback/N1N2MsgTxfrFailureNotification/{}" //UE Id
#define NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL "/nsmf-pdusession/v2/sm-contexts"
#define NSMF_PDU_SESSION_SM_CONTEXT_UPDATE_URL "/nsmf-pdusession/v2/sm-contexts/"
//for CURL
#define AMF_CURL_TIMEOUT_MS 100L
......
......@@ -119,7 +119,7 @@ void mime_parser::create_multipart_related_content(std::string &body,
body.append(std::string((char*) n1_msg_hex, n1_message.length() / 2) + CRLF);
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
body.append(CRLF);
body.append(std::string((char*) n2_msg_hex, n2_message.length() / 2) + CRLF);
......@@ -148,7 +148,7 @@ void mime_parser::create_multipart_related_content(
+ "Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { //NGAP
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
}
body.append(CRLF);
......
......@@ -337,7 +337,6 @@ set(NAS_include_files
${SRC_TOP_DIR}/ngap/ies
${SRC_TOP_DIR}/common
)
add_library(NAS ${NAS_src_files} ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES})
set(NGAP_include_files
......@@ -375,9 +374,8 @@ IF(STATIC_LINKING)
SET_TARGET_PROPERTIES(smf PROPERTIES LINK_SEARCH_END_STATIC 1)
# asan do not support static linking
SET(ASAN)
ENDIF(STATIC_LINKING)
ENDIF(STATIC_LINKING)
target_link_libraries (smf ${ASAN}
-Wl,--start-group CN_UTILS SMF UDP GTPV2C PFCP 3GPP_COMMON_TYPES SMF_API -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} -lnghttp2_asio -lboost_system -lboost_thread -lssl -lcrypto NAS gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
-Wl,--start-group CN_UTILS SMF UDP GTPV2C PFCP 3GPP_COMMON_TYPES SMF_API -lnettle ${NETTLE_LIBRARIES} ${CRYPTO_LIBRARIES} -lnghttp2_asio -lboost_system -lboost_thread -lssl -lcrypto NAS gflags glog dl double-conversion folly -Wl,--end-group pthread m rt config++ event boost_system pistache curl)
\ No newline at end of file
......@@ -46,7 +46,8 @@ itti_mw *itti_inst = nullptr;
async_shell_cmd *async_shell_cmd_inst = nullptr;
smf_app *smf_app_inst = nullptr;
smf_config smf_cfg;
SMFApiServer *smf_api_server_1 = nullptr;
//SMFApiServer *smf_api_server_1 = nullptr;
//smf_http2_server *smf_api_server_2 = nullptr;
void send_heartbeat_to_tasks(const uint32_t sequence);
......@@ -71,12 +72,14 @@ void my_app_signal_handler(int s)
std::cout << "Freeing Allocated memory..." << std::endl;
if (async_shell_cmd_inst) delete async_shell_cmd_inst; async_shell_cmd_inst = nullptr;
std::cout << "Async Shell CMD memory done." << std::endl;
//smf_api_server_1->shutdown();
//if (smf_api_server_1) delete smf_api_server_1; smf_api_server_1 = nullptr;
//if (smf_api_server_2) delete smf_api_server_2; smf_api_server_2 = nullptr;
std::cout << "SMF API Server memory done." << std::endl;
if (itti_inst) delete itti_inst; itti_inst = nullptr;
std::cout << "ITTI memory done." << std::endl;
if (smf_app_inst) delete smf_app_inst; smf_app_inst = nullptr;
std::cout << "SMF APP memory done." << std::endl;
smf_api_server_1->shutdown();
if (smf_api_server_1) delete smf_api_server_1; smf_api_server_1 = nullptr;
std::cout << "Freeing Allocated memory done" << std::endl;
exit(0);
}
......@@ -129,13 +132,14 @@ int main(int argc, char **argv)
Pistache::Address addr(std::string(inet_ntoa (*((struct in_addr *)&smf_cfg.sbi.addr4))) , Pistache::Port(smf_cfg.sbi.port));
SMFApiServer *smf_api_server_1 = new SMFApiServer(addr, smf_app_inst);
smf_api_server_1->init(2);
smf_api_server_1->start();
//std::thread smf_api_manager(&SMFApiServer::start, smf_api_server_1);
//smf_api_server_1->start();
std::thread smf_http1_manager(&SMFApiServer::start, smf_api_server_1);
//SMF NGHTTP API server (HTTP2)
smf_http2_server *smf_api_server_2 = new smf_http2_server(conv::toString(smf_cfg.sbi.addr4), smf_cfg.sbi_http2_port, smf_app_inst);
smf_api_server_2->start();
//std::thread smf_api(&smf_http2_server::start, smf_api_server_2);
//smf_api_server_2->start();
std::thread smf_http2_manager(&smf_http2_server::start, smf_api_server_2);
smf_http1_manager.join();
smf_http2_manager.join();
FILE *fp = NULL;
std::string filename = fmt::format("/tmp/smf_{}.status", getpid());
......
......@@ -277,7 +277,12 @@ void smf_app_task(void*) {
//------------------------------------------------------------------------------
smf_app::smf_app(const std::string &config_file)
:
m_seid2smf_context() {
m_seid2smf_context(),
m_supi2smf_context(),
m_scid2smf_context(),
m_sm_context_create_promises(),
m_sm_context_update_promises(),
m_sm_context_release_promises() {
Logger::smf_app().startup("Starting...");
supi2smf_context = { };
......@@ -547,13 +552,20 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex,
smreq->pid);
} else {
//trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
return;
}
......@@ -598,13 +610,19 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(smreq->req,
if (smf_n1_n2_inst.create_n1_sm_container(smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message, cause_n1);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
n1_sm_message, cause_n1)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex,
smreq->pid);
} else {
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
return;
}
......@@ -644,13 +662,19 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject including cause "#81 Invalid PTI value" (section 7.3.1 @3GPP TS 24.501)
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_81_INVALID_PTI_VALUE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_81_INVALID_PTI_VALUE)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex,
smreq->pid);
} else {
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
return;
}
smreq->req.set_pti(pti);
......@@ -660,6 +684,10 @@ void smf_app::handle_pdu_session_create_sm_context_request(
|| (pdu_session_id > PDU_SESSION_IDENTITY_LAST )) {
Logger::smf_app().warn("Invalid PDU Session ID value (%d)", pdu_session_id);
//section 7.3.2@3GPP TS 24.501; NAS N1 SM message: ignore the message
//trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE, smreq->pid,
N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
return;
}
......@@ -674,15 +702,22 @@ void smf_app::handle_pdu_session_create_sm_context_request(
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//(24.501 (section 7.4)) implementation dependent->do similar to UE: response with a 5GSM STATUS message including cause "#98 message type not compatible with protocol state."
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message,
cause_value_5gsm_e::CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_98_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex,
smreq->pid);
} else {
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
return;
}
......@@ -709,17 +744,35 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, 24.501 cause "#27 Missing or unknown DNN"
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_27_MISSING_OR_UNKNOWN_DNN);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
cause_value_5gsm_e::CAUSE_27_MISSING_OR_UNKNOWN_DNN)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex,
smreq->pid);
} else {
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
return;
}
//Step 4. Verify the session is already existed
if (is_scid_2_smf_context(supi64, dnn, snssai, 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);
//trigger to send reply to AMF
trigger_http_response(http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE, smreq->pid,
N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
return;
}
//Step 4. create a context for this supi if not existed, otherwise update
//Step 5. create a context for this supi if not existed, otherwise update
std::shared_ptr<smf_context> sc = { };
if (is_supi_2_smf_context(supi64)) {
Logger::smf_app().debug("Update SMF context with SUPI " SUPI_64_FMT "",
......@@ -735,7 +788,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
set_supi_2_smf_context(supi64, sc);
}
//Step 5. Create/update context with dnn information
//Step 6. Create/update context with dnn information
std::shared_ptr<dnn_context> sd = { };
if (!sc.get()->find_dnn_context(snssai, dnn, sd)) {
......@@ -751,7 +804,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
}
}
//Step 6. retrieve Session Management Subscription data from UDM if not available (step 4, section 4.3.2 3GPP TS 23.502)
//Step 7. retrieve Session Management Subscription data from UDM if not available (step 4, section 4.3.2 3GPP TS 23.502)
std::string dnn_selection_mode = smreq->req.get_dnn_selection_mode();
//if the Session Management Subscription data is not available, get from configuration file or UDM
if (not sc.get()->is_dnn_snssai_subscription_data(dnn, snssai)) {
......@@ -779,16 +832,21 @@ void smf_app::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, with cause "29 User authentication or authorization failed"
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_message_hex);
//trigger to send reply to AMF
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_message_hex, smreq->pid);
} else {
trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
return;
}
} else {
......@@ -803,7 +861,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
}
}
// Step 7. generate a SMF context Id and store the corresponding information in a map (SM_Context_ID, (supi, dnn, nssai, pdu_session_id))
// Step 8. generate a SMF context Id and store the corresponding information in a map (SM_Context_ID, (supi, dnn, nssai, 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());
......@@ -818,7 +876,7 @@ void smf_app::handle_pdu_session_create_sm_context_request(
Logger::smf_app().debug("Generated a SMF Context ID " SCID_FMT " ", scid);
//Step 8. let the context handle the message
//Step 9. Let the context handle the message
sc.get()->handle_pdu_session_create_sm_context_request(smreq);
}
......@@ -1092,6 +1150,21 @@ bool smf_app::is_scid_2_smf_context(const scid_t &scid) const {
return bool { scid2smf_context.count(scid) > 0 };
}
//------------------------------------------------------------------------------
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 {
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;
}
return false;
}
//------------------------------------------------------------------------------
bool smf_app::scid_2_smf_context(const scid_t &scid,
std::shared_ptr<smf_context_ref> &scf) const {
......@@ -1376,6 +1449,7 @@ bool smf_app::get_session_management_subscription_data(
void smf_app::add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_create_sm_context_response> > &p) {
std::shared_lock lock(m_sm_context_create_promises);
sm_context_create_promises.emplace(id, p);
}
......@@ -1383,6 +1457,7 @@ void smf_app::add_promise(
void smf_app::add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_update_sm_context_response> > &p) {
std::shared_lock lock(m_sm_context_update_promises);
sm_context_update_promises.emplace(id, p);
}
......@@ -1390,6 +1465,7 @@ void smf_app::add_promise(
void smf_app::add_promise(
uint32_t id,
boost::shared_ptr<boost::promise<pdu_session_release_sm_context_response> > &p) {
std::shared_lock lock(m_sm_context_release_promises);
sm_context_release_promises.emplace(id, p);
}
......@@ -1426,6 +1502,7 @@ void smf_app::trigger_http_response(
uint32_t &promise_id) {
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of API Server");
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
std::make_shared<itti_n11_update_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
......@@ -1442,6 +1519,7 @@ void smf_app::trigger_http_response(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
}
//---------------------------------------------------------------------------------------------
......@@ -1452,6 +1530,7 @@ void smf_app::trigger_http_response(
Logger::smf_app().debug(
"Send ITTI msg to SMF APP to trigger the response of HTTP Server");
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
std::make_shared<itti_n11_update_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
......@@ -1469,6 +1548,7 @@ void smf_app::trigger_http_response(
"Could not send ITTI message %s to task TASK_SMF_APP",
itti_msg->get_msg_name());
}
}
//---------------------------------------------------------------------------------------------
......@@ -1494,12 +1574,45 @@ void smf_app::trigger_http_response(const uint32_t &http_code,
}
}
break;
case N11_SESSION_CREATE_SM_CONTEXT_RESPONSE: {
std::shared_ptr<itti_n11_create_sm_context_response> itti_msg =
std::make_shared<itti_n11_create_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
pdu_session_create_sm_context_response sm_context_response = { };
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
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_APP",
itti_msg->get_msg_name());
}
}
break;
default: {
case N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE: {
std::shared_ptr<itti_n11_update_sm_context_response> itti_msg =
std::make_shared<itti_n11_update_sm_context_response>(TASK_SMF_N11,
TASK_SMF_APP,
promise_id);
pdu_session_update_sm_context_response sm_context_response = { };
sm_context_response.set_http_code(http_code);
itti_msg->res = sm_context_response;
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_APP",
itti_msg->get_msg_name());
}
}
break;
default: {
//TODO:
}
}
......
......@@ -119,6 +119,10 @@ class smf_app {
std::map<scid_t, std::shared_ptr<smf_context_ref>> scid2smf_context;
mutable std::shared_mutex m_scid2smf_context;
//Store promise IDs for Create/Update session
mutable std::shared_mutex m_sm_context_create_promises;
mutable std::shared_mutex m_sm_context_update_promises;
mutable std::shared_mutex m_sm_context_release_promises;
std::map<uint32_t,
boost::shared_ptr<boost::promise<pdu_session_create_sm_context_response>>> sm_context_create_promises;
std::map<uint32_t,
......@@ -390,6 +394,18 @@ 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
* @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
*/
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;
/*
* Find SMF Context Reference by its ID
* @param [const scid_t &] scid: SM Context Reference ID
......@@ -604,6 +620,7 @@ class smf_app {
* @param [const uint32_t &] http_code: Status code of HTTP response
* @param [const oai::smf_server::model::SmContextCreateError &] smContextCreateError: store the json content of response message
* @param [uint32_t &] promise_id: Promise Id
* @param [uint8_t] msg_type: Type of HTTP message (Update/Release)
* @return void
*/
void trigger_http_response(
......@@ -617,6 +634,7 @@ class smf_app {
* @param [const oai::smf_server::model::SmContextUpdateError &] smContextUpdateError: store the json content of response message
* @param [const std::string &] n1_sm_msg: N1 SM message
* @param [uint32_t &] promise_id: Promise Id
* @param [uint8_t] msg_type: Type of HTTP message (Update/Release)
* @return void
*/
void trigger_http_response(
......@@ -628,7 +646,7 @@ class smf_app {
* To trigger the response to the HTTP server by set the value of the corresponding promise to ready
* @param [const uint32_t &] http_code: Status code of HTTP response
* @param [uint32_t &] promise_id: Promise Id
* @param [uint8_t] msg_type
* @param [uint8_t] msg_type: Type of HTTP message (Create/Update/Release)
* @return void
*/
void trigger_http_response(const uint32_t &http_code, uint32_t &promise_id,
......
......@@ -1151,16 +1151,23 @@ void smf_context::handle_pdu_session_create_sm_context_request(
smContextCreateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req,
PDU_SESSION_ESTABLISHMENT_REJECT,
n1_sm_message,
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_401_UNAUTHORIZED,
smContextCreateError, n1_sm_msg_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_29_USER_AUTHENTICATION_OR_AUTHORIZATION_FAILED)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_401_UNAUTHORIZED,
smContextCreateError, n1_sm_msg_hex, smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
//TODO:
//SMF unsubscribes to the modifications of Session Management Subscription data for (SUPI, DNN, S-NSSAI)
//using Nudm_SDM_Unsubscribe()
......@@ -1176,7 +1183,8 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sm_context_resp->http_version = smreq->http_version;
sm_context_resp->res.set_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK); //default status code
sm_context_resp->res.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK); //default status code
sm_context_resp->res.set_supi(supi);
sm_context_resp->res.set_supi_prefix(smreq->req.get_supi_prefix());
sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
......@@ -1220,11 +1228,13 @@ void smf_context::handle_pdu_session_create_sm_context_request(
sd->insert_pdu_session(sp);
} else {
Logger::smf_app().debug("PDN connection is already existed!");
//TODO:
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_406_NOT_ACCEPTABLE, smreq->pid,
N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
return;
}
//pending session??
//TODO: if "Integrity Protection is required", check UE Integrity Protection Maximum Data Rate
//TODO: (Optional) Secondary authentication/authorization
......@@ -1315,14 +1325,19 @@ void smf_context::handle_pdu_session_create_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextCreateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_message,
cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE);
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_msg_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_28_UNKNOWN_PDU_SESSION_TYPE)) {
smf_app_inst->convert_string_2_hex(n1_sm_message, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextCreateError, n1_sm_msg_hex, smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_CREATE_SM_CONTEXT_RESPONSE);
}
request_accepted = false;
break;
}
......@@ -1364,7 +1379,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
json_data["cause"] = 0;
sm_context_response.set_json_data(json_data);
sm_context_response.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK);
http_status_code_e::HTTP_STATUS_CODE_201_CREATED);
itti_msg->res = sm_context_response;
int ret = itti_inst->send_msg(itti_msg);
......@@ -1469,6 +1484,7 @@ void smf_context::handle_pdu_session_create_sm_context_request(
"Could not send ITTI message %s to task TASK_SMF_N11",
sm_context_resp_pending->get_msg_name());
}
}
}
......@@ -1520,7 +1536,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
std::shared_ptr<itti_n11_update_sm_context_response> sm_context_resp_pending =
std::shared_ptr<itti_n11_update_sm_context_response>(n11_sm_context_resp);
sm_context_resp_pending->res.set_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK); //default status code
sm_context_resp_pending->res.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK); //default status code
n11_sm_context_resp->res.set_supi(sm_context_req_msg.get_supi());
n11_sm_context_resp->res.set_supi_prefix(
sm_context_req_msg.get_supi_prefix());
......@@ -1529,6 +1546,8 @@ void smf_context::handle_pdu_session_update_sm_context_request(
sm_context_req_msg.get_pdu_session_id());
n11_sm_context_resp->res.set_snssai(sm_context_req_msg.get_snssai());
n11_sm_context_resp->res.set_dnn(sm_context_req_msg.get_dnn());
n11_sm_context_resp->res.set_pdu_session_type(
sp.get()->get_pdn_type().pdn_type);
//Step 2.1. Decode N1 (if content is available)
if (sm_context_req_msg.n1_sm_msg_is_set()) {
......@@ -1766,13 +1785,19 @@ void smf_context::handle_pdu_session_update_sm_context_request(
std::string n1_sm_msg_to_be_created, n1_sm_msg_hex_to_be_created;
std::string n2_sm_info_to_be_created, n2_sm_info_hex_to_be_created;
//N1 SM (PDU Session Modification Command)
smf_n1_n2_inst.create_n1_sm_container(
if (not smf_n1_n2_inst.create_n1_sm_container(
n11_sm_context_resp->res, PDU_SESSION_MODIFICATION_COMMAND,
n1_sm_msg_to_be_created, cause_value_5gsm_e::CAUSE_0_UNKNOWN); //TODO: need cause?
//N2 SM (PDU Session Resource Modify Request Transfer IE)
smf_n1_n2_inst.create_n2_sm_information(
n11_sm_context_resp->res, 1, n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info_to_be_created);
n1_sm_msg_to_be_created, cause_value_5gsm_e::CAUSE_0_UNKNOWN) or //TODO: need cause?
//N2 SM (PDU Session Resource Modify Request Transfer IE)
not smf_n1_n2_inst.create_n2_sm_information(
n11_sm_context_resp->res, 1, n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info_to_be_created)) {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE);
return;
}
smf_app_inst->convert_string_2_hex(n1_sm_msg_to_be_created,
n1_sm_msg_hex_to_be_created);
smf_app_inst->convert_string_2_hex(n2_sm_info_to_be_created,
......@@ -1917,14 +1942,21 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setError(problem_details);
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_RELEASE_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n1_sm_msg_hex, smreq->pid);
cause_value_5gsm_e::CAUSE_43_INVALID_PDU_SESSION_IDENTITY)) {
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n1_sm_msg_hex, smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE);
}
return;
}
//Abnormal cases in network side (see section 6.3.3.5 @3GPP TS 24.501)
if (sp.get()->get_pdu_session_status()
......@@ -2075,14 +2107,20 @@ void smf_context::handle_pdu_session_update_sm_context_request(
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
//24.501: response with a 5GSM STATUS message including cause "#95 Semantically incorrect message"
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
sm_context_req_msg, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); //TODO: need N1SM?
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
cause_value_5gsm_e::CAUSE_95_SEMANTICALLY_INCORRECT_MESSAGE)) {
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex); //TODO: need N1SM?
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE);
}
return;
}
......@@ -2161,15 +2199,20 @@ void smf_context::handle_pdu_session_update_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject, 24.501 cause "#26 Insufficient resources"
smf_n1_n2_inst.create_n1_sm_container(
if (smf_n1_n2_inst.create_n1_sm_container(
smreq->req, PDU_SESSION_ESTABLISHMENT_REJECT, n1_sm_msg,
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES);
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n1_sm_msg_hex, smreq->pid);
//TODO: Need release established resources?
cause_value_5gsm_e::CAUSE_26_INSUFFICIENT_RESOURCES)) {
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n1_sm_msg_hex, smreq->pid);
//TODO: Need release established resources?
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE);
}
return;
}
break;
......@@ -2386,14 +2429,19 @@ void smf_context::handle_pdu_session_update_sm_context_request(
refToBinaryData.setContentId(N1_SM_CONTENT_ID);
smContextUpdateError.setN1SmMsg(refToBinaryData);
//PDU Session Establishment Reject
smf_n1_n2_inst.create_n1_sm_container(
if (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);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
cause_value_5gsm_e::CAUSE_38_NETWORK_FAILURE)) {
smf_app_inst->convert_string_2_hex(n1_sm_msg, n1_sm_msg_hex);
//trigger to send reply to AMF
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, smreq->pid);
} else {
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_500_INTERNAL_SERVER_ERROR,
smreq->pid, N11_SESSION_UPDATE_SM_CONTEXT_RESPONSE);
}
}
break;
......@@ -2482,7 +2530,8 @@ void smf_context::handle_pdu_session_release_sm_context_request(
std::shared_ptr<itti_n11_release_sm_context_response>(
n11_sm_context_resp);
n11_sm_context_resp->res.set_http_code(http_status_code_e::HTTP_STATUS_CODE_200_OK); //default http response code
n11_sm_context_resp->res.set_http_code(
http_status_code_e::HTTP_STATUS_CODE_200_OK); //default http response code
n11_sm_context_resp->res.set_supi(smreq->req.get_supi());
n11_sm_context_resp->res.set_supi_prefix(smreq->req.get_supi_prefix());
n11_sm_context_resp->res.set_cause(REQUEST_ACCEPTED);
......@@ -2565,6 +2614,7 @@ void smf_context::handle_pdu_session_modification_network_requested(
Logger::smf_app().debug(
"Prepare N1N2MessageTransfer message and send to AMF");
//TODO: handle encode N1, N2 failure
//N1: PDU_SESSION_MODIFICATION_COMMAND
smf_n1_n2_inst.create_n1_sm_container(itti_msg->msg,
PDU_SESSION_MODIFICATION_COMMAND,
......@@ -2577,6 +2627,7 @@ void smf_context::handle_pdu_session_modification_network_requested(
smf_n1_n2_inst.create_n2_sm_information(itti_msg->msg, 1,
n2_sm_info_type_e::PDU_RES_MOD_REQ,
n2_sm_info);
smf_app_inst->convert_string_2_hex(n2_sm_info, n2_sm_info_hex);
itti_msg->msg.set_n2_sm_information(n2_sm_info_hex);
......
......@@ -68,7 +68,7 @@ using namespace smf;
extern smf_app *smf_app_inst;
//-----------------------------------------------------------------------------------------------------
void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
bool smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
uint8_t n1_msg_type,
std::string &nas_msg_str,
cause_value_5gsm_e sm_cause) {
......@@ -103,7 +103,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
Logger::smf_app().error(
"Cannot create an PDU Session Establishment Accept for this message (type %d)",
msg.get_msg_type());
return;
return false;
}
pdu_session_create_sm_context_response &sm_context_res =
......@@ -112,6 +112,13 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//get default QoS value
qos_flow_context_updated qos_flow = { };
qos_flow = sm_context_res.get_qos_flow_context();
//check the QoS Flow
if ((qos_flow.qfi.qfi < QOS_FLOW_IDENTIFIER_FIRST )
or (qos_flow.qfi.qfi > QOS_FLOW_IDENTIFIER_LAST )) {
//error
Logger::smf_app().error("Incorrect QFI %d", qos_flow.qfi.qfi);
return false;
}
Logger::smf_app().info(
"PDU_SESSION_ESTABLISHMENT_ACCEPT, encode starting...");
......@@ -149,18 +156,21 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
//authorized QoS rules of the PDU session: QOSRules (Section 6.2.5@3GPP TS 24.501)
//(Section 6.4.1.3@3GPP TS 24.501 V16.1.0) Make sure that the number of the packet filters used in the authorized QoS rules of the PDU Session does not
// exceed the maximum number of packet filters supported by the UE for the PDU session
sm_msg->pdu_session_establishment_accept.qosrules.lengthofqosrulesie =
qos_flow.qos_rules.size();
sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie =
(QOSRulesIE*) calloc(qos_flow.qos_rules.size(), sizeof(QOSRulesIE));
int i = 0;
for (auto rule : qos_flow.qos_rules) {
sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie[i]
.qosruleidentifer = rule.second.qosruleidentifer;
memcpy(&sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie[i],
&rule.second, sizeof(QOSRulesIE));
i++;
if (qos_flow.qos_rules.size() > 0) {
sm_msg->pdu_session_establishment_accept.qosrules.lengthofqosrulesie =
qos_flow.qos_rules.size();
sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie =
(QOSRulesIE*) calloc(qos_flow.qos_rules.size(), sizeof(QOSRulesIE));
int i = 0;
for (auto rule : qos_flow.qos_rules) {
sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie[i]
.qosruleidentifer = rule.second.qosruleidentifer;
memcpy(
&sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie[i],
&rule.second, sizeof(QOSRulesIE));
i++;
}
}
//SessionAMBR
......@@ -179,7 +189,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
} else {
Logger::smf_app().warn(
"SMF context with SUPI " SUPI_64_FMT " does not exist!", supi64);
//TODO:
return false;
}
//Presence
......@@ -298,8 +308,11 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
nas_msg_str = n1Message;
//free memory
free_wrapper(
(void**) &sm_msg->pdu_session_establishment_accept.qosrules.qosrulesie);
if (qos_flow.qos_rules.size() > 0) {
free_wrapper(
(void**) &sm_msg->pdu_session_establishment_accept.qosrules
.qosrulesie);
}
free_wrapper(
(void**) &sm_msg->pdu_session_establishment_accept.qosflowdescriptions
.qosflowdescriptionscontents);
......@@ -434,7 +447,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
} else {
Logger::smf_app().warn(
"SMF context with SUPI " SUPI_64_FMT " does not exist!", supi64);
//TODO:
return false;
}
bool find_dnn = sc.get()->find_dnn_context(sm_context_res.get_snssai(),
......@@ -447,8 +460,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
if (!find_dnn or !find_pdu) {
//error
Logger::smf_app().warn("DNN or PDU session context does not exist!");
//TODO:
return;
return false;
}
//PTI
......@@ -475,6 +487,10 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
std::vector<QOSRulesIE> qos_rules;
sp.get()->get_qos_rules_to_be_synchronised(qos_rules);
if (qos_rules.size() == 0) {
return false;
}
sm_msg->pdu_session_modification_command.qosrules.lengthofqosrulesie =
qos_rules.size();
......@@ -630,7 +646,7 @@ void smf_n1_n2::create_n1_sm_container(pdu_session_msg &msg,
}
//------------------------------------------------------------------------------
void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
bool smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
uint8_t ngap_msg_type,
n2_sm_info_type_e ngap_ie_type,
std::string &ngap_msg_str) {
......@@ -684,6 +700,10 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
qos_flows.begin(); it != qos_flows.end(); ++it)
Logger::smf_app().debug("QoS Flow context to be updated QFI %d",
it->first);
if (qos_flows.empty()) {
return false;
}
//TODO: support only 1 qos flow
qos_flow = qos_flows.begin()->second;
......@@ -703,7 +723,15 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
msg.get_msg_type());
//TODO:
free_wrapper((void**) &ngap_IEs);
return;
return false;
}
//check the QoS Flow
if ((qos_flow.qfi.qfi < QOS_FLOW_IDENTIFIER_FIRST )
or (qos_flow.qfi.qfi > QOS_FLOW_IDENTIFIER_LAST )) {
//error
Logger::smf_app().error("Incorrect QFI %d", qos_flow.qfi.qfi);
return false;
}
//PDUSessionAggregateMaximumBitRate
......@@ -734,7 +762,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
} else {
Logger::smf_app().warn(
"SMF context with SUPI " SUPI_64_FMT " does not exist!", supi64);
//TODO:
return false;
}
ASN_SEQUENCE_ADD(&ngap_IEs->protocolIEs.list,
......@@ -801,8 +829,11 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
pduSessionType->criticality = Ngap_Criticality_reject;
pduSessionType->value.present =
Ngap_PDUSessionResourceSetupRequestTransferIEs__value_PR_PDUSessionType;
pduSessionType->value.choice.PDUSessionType = msg.get_pdu_session_type(); //TODO: different between Ngap_PDUSessionType_ipv4 vs pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4
pduSessionType->value.choice.PDUSessionType = msg.get_pdu_session_type()
- 1; //TODO: dirty code, difference between Ngap_PDUSessionType_ipv4 vs pdu_session_type_e::PDU_SESSION_TYPE_E_IPV4 (TS 38.413 vs TS 24.501)
ASN_SEQUENCE_ADD(&ngap_IEs->protocolIEs.list, pduSessionType);
Logger::smf_app().debug("PDU Session Type: %d ",
msg.get_pdu_session_type());
//SecurityIndication
//TODO: should get from UDM
......@@ -885,7 +916,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
Logger::smf_app().warn(
"NGAP PDU Session Resource Setup Request Transfer encode failed (encode size %d)",
encoded_size);
return;
return false;
}
#if DEBUG_IS_ON
......@@ -945,6 +976,14 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
//TODO: support only 1 qos flow
qos_flow_context_updated qos_flow = qos_flows.begin()->second;
//check the QoS Flow
if ((qos_flow.qfi.qfi < QOS_FLOW_IDENTIFIER_FIRST )
or (qos_flow.qfi.qfi > QOS_FLOW_IDENTIFIER_LAST )) {
//error
Logger::smf_app().error("Incorrect QFI %d", qos_flow.qfi.qfi);
return false;
}
Logger::smf_app().debug(
"QoS Flow, UL F-TEID ID " "0x%" PRIx32 ", IP Address %s ",
qos_flow.ul_fteid.teid_gre_key,
......@@ -1161,7 +1200,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
Logger::smf_app().warn(
"NGAP PDU Session Resource Modify Request Transfer encode failed (encoded size %d)",
encoded_size);
return;
return false;
}
#if DEBUG_IS_ON
......@@ -1285,7 +1324,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
Logger::smf_app().warn(
"NGAP PDU Session Resource Setup Response Transfer encode failed (encoded size %d)",
encoded_size);
return;
return false;
}
#if DEBUG_IS_ON
......@@ -1395,7 +1434,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
Logger::smf_app().warn(
" NGAP PDU Session Resource Modify Response Transfer encode failed (encoded size %d)",
encoded_size);
return;
return false;
}
#if DEBUG_IS_ON
......@@ -1471,7 +1510,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
Logger::smf_app().warn(
"NGAP PDU Session Release Command encode failed (encoded size %d)",
encoded_size);
return;
return false;
}
#if DEBUG_IS_ON
......@@ -1515,7 +1554,7 @@ void smf_n1_n2::create_n2_sm_information(pdu_session_msg &msg,
Logger::smf_app().warn(
"NGAP PDU Session Release Command encode failed (encoded size %d)",
encoded_size);
return;
return false;
}
#if DEBUG_IS_ON
......@@ -1606,9 +1645,9 @@ int smf_n1_n2::decode_n2_sm_information(
if (rc.code != RC_OK) {
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror;
return RETURNerror ;
}
return RETURNok;
return RETURNok ;
}
//---------------------------------------------------------------------------------------------
......@@ -1635,9 +1674,9 @@ int smf_n1_n2::decode_n2_sm_information(
if (rc.code != RC_OK) {
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror;
return RETURNerror ;
}
return RETURNok;
return RETURNok ;
}
//---------------------------------------------------------------------------------------------
......@@ -1664,9 +1703,9 @@ int smf_n1_n2::decode_n2_sm_information(
if (rc.code != RC_OK) {
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror;
return RETURNerror ;
}
return RETURNok;
return RETURNok ;
}
//---------------------------------------------------------------------------------------------
......@@ -1693,7 +1732,7 @@ int smf_n1_n2::decode_n2_sm_information(
if (rc.code != RC_OK) {
Logger::smf_app().warn("asn_decode failed with code %d", rc.code);
return RETURNerror;
return RETURNerror ;
}
return RETURNok;
return RETURNok ;
}
......@@ -78,9 +78,9 @@ class smf_n1_n2 {
* @param [uint8_t] msg_type Type of N1 message
* @param [std::string&] nas_msg_str store NAS message in form of string
* @param [uint8_t] sm_cause store NAS Cause
*
* @return boolean: True if the NAS message has been created successfully, otherwise return false
*/
void create_n1_sm_container(pdu_session_msg &msg, uint8_t msg_type,
bool create_n1_sm_container(pdu_session_msg &msg, uint8_t msg_type,
std::string &nas_msg_str,
cause_value_5gsm_e sm_cause);
......@@ -89,9 +89,10 @@ class smf_n1_n2 {
* @param [std::shared_ptr<itti_n11_create_sm_context_response>] sm_context_res
* @param [uint8_t] msg_type Type of N2 message
* @param [std::string&] ngap_msg_str store NGAP message in form of string
* @return boolean: True if the NGAP message has been created successfully, otherwise return false
*
*/
void create_n2_sm_information(pdu_session_msg &msg, uint8_t ngap_msg_type,
bool create_n2_sm_information(pdu_session_msg &msg, uint8_t ngap_msg_type,
n2_sm_info_type_e ngap_ie_type,
std::string &ngap_msg_str);
......
......@@ -465,7 +465,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
if (n11_triggered_pending->res.get_cause() == REQUEST_ACCEPTED) {
json_data["n2InfoContainer"]["n2InformationClass"] =
N1N2_MESSAGE_CLASS;
json_data["n2InfoContainer"]["smInfo"]["PduSessionId"] =
json_data["n2InfoContainer"]["smInfo"]["pduSessionId"] =
n11_triggered_pending->res.get_pdu_session_id();
//N2InfoContent (section 6.1.6.2.27@3GPP TS 29.518)
json_data["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
......@@ -477,6 +477,15 @@ void session_create_sm_context_procedure::handle_itti_msg(
json_data["n2InfoContainer"]["smInfo"]["sNssai"]["sd"] =
n11_triggered_pending->res.get_snssai().sD;
json_data["n2InfoContainer"]["ranInfo"] = "SM";
//N1N2MsgTxfrFailureNotification
std::string callback_uri = std::string(
inet_ntoa(*((struct in_addr*) &smf_cfg.amf_addr.ipv4_addr))) + ":"
+ std::to_string(smf_cfg.amf_addr.port)
+ fmt::format(NSMF_CALLBACK_N1N2_MESSAGE_TRANSFER_FAILURE,
supi_str.c_str());
json_data["n1n2FailureTxfNotifURI"] = callback_uri.c_str();
//json_data["n1n2FailureTxfNotifURI"] = "http://192.168.122.1/namf-comm/callback/N1N2MsgTxfrFailureNotification/imsi-310410000000001-1";
}
//Others information
//n11_triggered_pending->res.n1n2_message_transfer_data["pti"] = 1; //Don't need this info for the moment
......@@ -1025,6 +1034,7 @@ void session_update_sm_context_procedure::handle_itti_msg(
smf_app_inst->trigger_http_response(
http_status_code_e::HTTP_STATUS_CODE_403_FORBIDDEN,
smContextUpdateError, n11_triggered_pending->pid);
return;
}
}
break;
......
......@@ -4,6 +4,7 @@
#include <string>
#include <unistd.h>
#include <stdexcept>
#include <thread>
#ifndef CURLPIPE_MULTIPLEX
#define CURLPIPE_MULTIPLEX 0
......@@ -11,6 +12,9 @@
#define HTTP_V1 1
#define HTTP_V2 2
#define HTTP_CODE_OK 200
#define HTTP_CODE_CREATED 201
/*
* To read content of the response from UDM
*/
......@@ -129,7 +133,7 @@ void create_multipart_related_content(std::string &body, std::string &json_part,
body.append("--" + boundary + CRLF);
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
body.append(CRLF);
body.append(n2_message + CRLF);
......@@ -154,7 +158,7 @@ void create_multipart_related_content(
+ "Content-Id: n1SmMsg" + CRLF);
} else if (content_type == multipart_related_content_part_e::NGAP) { //NGAP
body.append(
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2SmMsg"
"Content-Type: application/vnd.3gpp.ngap" + CRLF + "Content-Id: n2msg"
+ CRLF);
}
body.append(CRLF);
......@@ -163,11 +167,15 @@ void create_multipart_related_content(
}
//------------------------------------------------------------------------------
void send_pdu_session_establishment_request(std::string smf_ip_address,
bool send_pdu_session_establishment_request(uint8_t pid,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
//TODO: return the created SM context Id
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Create)"
<< std::endl;
// Response information.
long httpCode = { 0 };
nlohmann::json pdu_session_establishment_request;
//encode PDU Session Establishment Request
......@@ -178,7 +186,7 @@ void send_pdu_session_establishment_request(std::string smf_ip_address,
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xc1, size); //MessageType - PDU_SESSION_ESTABLISHMENT_REQUEST
ENCODE_U8(buffer + size, 0xff, size); //Integrity Protection Maximum Data Rate
......@@ -206,7 +214,7 @@ void send_pdu_session_establishment_request(std::string smf_ip_address,
pdu_session_establishment_request["dnn"] = "default";
pdu_session_establishment_request["sNssai"]["sst"] = 222;
pdu_session_establishment_request["sNssai"]["sd"] = "0000D4";
pdu_session_establishment_request["pduSessionId"] = 1;
pdu_session_establishment_request["pduSessionId"] = pid;
pdu_session_establishment_request["requestType"] = "INITIAL_REQUEST";
pdu_session_establishment_request["servingNfId"] = "servingNfId";
pdu_session_establishment_request["servingNetwork"]["mcc"] = "234";
......@@ -256,8 +264,6 @@ void send_pdu_session_establishment_request(std::string smf_ip_address,
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -281,20 +287,28 @@ void send_pdu_session_establishment_request(std::string smf_ip_address,
<< "[AMF N11] PDU session establishment request, response from SMF "
<< response_data.dump().c_str() << ", Http Code " << httpCode
<< std::endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
free(buffer);
if (httpCode == HTTP_CODE_CREATED) {
return true;
} else {
return false;
}
}
//------------------------------------------------------------------------------
void send_pdu_session_update_sm_context_establishment(
std::string smf_ip_address, uint8_t http_version, std::string port) {
bool send_pdu_session_update_sm_context_establishment(
uint8_t context_id, std::string smf_ip_address, uint8_t http_version,
std::string port) {
std::cout << "[AMF N11] PDU Session Establishment Request (SM Context Update)"
<< std::endl;
// Response information.
long httpCode = { 0 };
nlohmann::json pdu_session_update_request;
//encode PDU Session Resource Setup Response Transfer IE
/*
......@@ -330,14 +344,17 @@ void send_pdu_session_update_sm_context_establishment(
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
// url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//Fill the json part
pdu_session_update_request["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
//pdu_session_update_request["n2InfoContainer"]["n2InformationClass"] = "SM";
//pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2SmMsg";
//pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2msg";
// pdu_session_update_request["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
// "PDU_RES_SETUP_RSP"; //NGAP message
......@@ -381,8 +398,6 @@ void send_pdu_session_update_sm_context_establishment(
#endif
}
// Response information.
long httpCode = { 0 };
std::unique_ptr<std::string> httpData(new std::string());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &callback);
......@@ -415,10 +430,19 @@ void send_pdu_session_update_sm_context_establishment(
curl_global_cleanup();
free(buffer);
if (httpCode == HTTP_CODE_OK) {
return true;
} else {
return false;
}
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step1(std::string smf_ip_address,
void send_pdu_session_modification_request_step1(uint8_t pid,
uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
......@@ -435,7 +459,7 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address,
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xc9, size); //MessageType - PDU Session Modification Request
ENCODE_U8(buffer + size, 0x28, size); //_5GSMCapability
......@@ -478,10 +502,13 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_modification_request["pduSessionId"] = 1;
pdu_session_modification_request["pduSessionId"] = pid;
pdu_session_modification_request["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
std::string body;
......@@ -557,7 +584,8 @@ void send_pdu_session_modification_request_step1(std::string smf_ip_address,
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_request_step2(std::string smf_ip_address,
void send_pdu_session_modification_request_step2(uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
......@@ -599,11 +627,14 @@ void send_pdu_session_modification_request_step2(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
// url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_modification["n2SmInfoType"] = "PDU_RES_MOD_RSP"; //"PDU_RES_SETUP_RSP"
pdu_session_modification["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
pdu_session_modification["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
std::string body;
std::string boundary = "----Boundary";
......@@ -678,7 +709,8 @@ void send_pdu_session_modification_request_step2(std::string smf_ip_address,
}
//------------------------------------------------------------------------------
void send_pdu_session_modification_complete(std::string smf_ip_address,
void send_pdu_session_modification_complete(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
......@@ -692,7 +724,7 @@ void send_pdu_session_modification_complete(std::string smf_ip_address,
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xcc, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //presence
......@@ -711,7 +743,10 @@ void send_pdu_session_modification_complete(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
// url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_modification_complete["n1SmMsg"]["contentId"] = "n1SmMsg"; // NAS
......@@ -789,7 +824,8 @@ void send_pdu_session_modification_complete(std::string smf_ip_address,
}
//------------------------------------------------------------------------------
void send_pdu_session_release_request(std::string smf_ip_address,
void send_pdu_session_release_request(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release Request (SM Context Update)"
......@@ -804,7 +840,7 @@ void send_pdu_session_release_request(std::string smf_ip_address,
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xd1, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //presence
......@@ -822,7 +858,10 @@ void send_pdu_session_release_request(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_release_request["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
......@@ -901,7 +940,8 @@ void send_pdu_session_release_request(std::string smf_ip_address,
}
//------------------------------------------------------------------------------
void send_pdu_session_release_resource_release_ack(std::string smf_ip_address,
void send_pdu_session_release_resource_release_ack(uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
......@@ -929,11 +969,14 @@ void send_pdu_session_release_resource_release_ack(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
// url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_release_ack["n2SmInfoType"] = "PDU_RES_REL_RSP";
pdu_session_release_ack["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
pdu_session_release_ack["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
std::string body;
std::string boundary = "----Boundary";
......@@ -1009,7 +1052,8 @@ void send_pdu_session_release_resource_release_ack(std::string smf_ip_address,
}
//------------------------------------------------------------------------------
void send_pdu_session_release_complete(std::string smf_ip_address,
void send_pdu_session_release_complete(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout
......@@ -1025,7 +1069,7 @@ void send_pdu_session_release_complete(std::string smf_ip_address,
char *buffer = (char*) calloc(1, buffer_size);
int size = 0;
ENCODE_U8(buffer, 0x2e, size); //ExtendedProtocolDiscriminator
ENCODE_U8(buffer + size, 0x01, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, pid, size); //PDUSessionIdentity
ENCODE_U8(buffer + size, 0x01, size); //ProcedureTransactionIdentity
ENCODE_U8(buffer + size, 0xd4, size); //MessageType
ENCODE_U8(buffer + size, 0x00, size); //Cause
......@@ -1044,7 +1088,10 @@ void send_pdu_session_release_complete(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
pdu_session_release_complete["cause"] = "INSUFFICIENT_UP_RESOURCES"; //need to be updated
......@@ -1124,7 +1171,8 @@ void send_pdu_session_release_complete(std::string smf_ip_address,
//------------------------------------------------------------------------------
void send_pdu_session_update_sm_context_ue_service_request(
std::string smf_ip_address, uint8_t http_version, std::string port) {
uint8_t context_id, std::string smf_ip_address, uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] UE-triggered Service Request (SM Context Update Step 1)"
<< std::endl;
......@@ -1139,7 +1187,10 @@ void send_pdu_session_update_sm_context_ue_service_request(
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//PDU session ID (as specified in section 4.2.3.2 @ 3GPP TS 23.502, but can't find in Yaml file)
service_requests["upCnxState"] = "ACTIVATING";
......@@ -1209,7 +1260,8 @@ void send_pdu_session_update_sm_context_ue_service_request(
//------------------------------------------------------------------------------
void send_pdu_session_update_sm_context_ue_service_request_step2(
std::string smf_ip_address, uint8_t http_version, std::string port) {
uint8_t context_id, std::string smf_ip_address, uint8_t http_version,
std::string port) {
std::cout
<< "[AMF N11] UE-triggered Service Request (SM Context Update Step 2)"
<< std::endl;
......@@ -1249,14 +1301,17 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
//url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/modify"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/modify"));
//Fill the json part
service_requests["n2SmInfoType"] = "PDU_RES_SETUP_RSP";
service_requests["n2SmInfo"]["contentId"] = "n2SmMsg"; //NGAP
service_requests["n2SmInfo"]["contentId"] = "n2msg"; //NGAP
//service_requests["n2InfoContainer"]["n2InformationClass"] = "SM";
//service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2SmMsg";
//service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapData"]["contentId"] = "n2msg";
// service_requests["n2InfoContainer"]["smInfo"]["n2InfoContent"]["ngapIeType"] =
// "PDU_RES_SETUP_RSP"; //NGAP message
......@@ -1340,7 +1395,8 @@ void send_pdu_session_update_sm_context_ue_service_request_step2(
}
//------------------------------------------------------------------------------
void send_release_sm_context_request(std::string smf_ip_address,
void send_release_sm_context_request(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version, std::string port) {
std::cout << "[AMF N11] PDU Session Release SM context Request" << std::endl;
......@@ -1353,10 +1409,13 @@ void send_release_sm_context_request(std::string smf_ip_address,
url.append(std::string(":"));
url.append(port);
}
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/release"));
//url.append(std::string("/nsmf-pdusession/v2/sm-contexts/1/release"));
url.append(std::string("/nsmf-pdusession/v2/sm-contexts/"));
url.append(std::to_string(context_id));
url.append(std::string("/release"));
//Fill the json part
send_release_sm_context_request["pduSessionId"] = 1;
send_release_sm_context_request["pduSessionId"] = pid;
std::string body = send_release_sm_context_request.dump();
......@@ -1418,6 +1477,143 @@ void send_release_sm_context_request(std::string smf_ip_address,
}
//------------------------------------------------------------------------------
bool pdu_session_establishment(uint8_t pid, uint8_t context_id,
std::string smf_ip_address, uint8_t http_version,
std::string port) {
bool status = false;
if (send_pdu_session_establishment_request(pid, smf_ip_address, http_version,
port)) {
usleep(100000);
status = send_pdu_session_update_sm_context_establishment(context_id,
smf_ip_address,
http_version,
port);
}
return status;
}
//------------------------------------------------------------------------------
void test_all_procedures_for_one_session(uint8_t pid, uint8_t context_id,
std::string smf_ip_address,
uint8_t http_version,
std::string port) {
bool status = false;
if (send_pdu_session_establishment_request(pid, smf_ip_address, http_version,
port)) {
usleep(100000);
status = send_pdu_session_update_sm_context_establishment(context_id,
smf_ip_address,
http_version,
port);
}
if (status) {
usleep(200000);
//UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(context_id,
smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(context_id,
smf_ip_address,
http_version,
port);
usleep(200000);
//PDU Session Modification
send_pdu_session_modification_request_step1(pid, context_id, smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_modification_request_step2(context_id, smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_modification_complete(pid, context_id, smf_ip_address,
http_version, port);
usleep(200000);
//PDU Session Release procedure
send_pdu_session_release_request(pid, context_id, smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_release_resource_release_ack(context_id, smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_release_complete(pid, context_id, smf_ip_address,
http_version, port);
usleep(200000);
//Release SM context
//send_release_sm_context_request(pid, smf_ip_address, http_version, port);
}
}
//------------------------------------------------------------------------------
void test_session_establishment_multiple_threads(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
std::vector<std::thread> pdu_threads;
for (int i = 0; i < 10; i++) {
std::thread session_establishment(&pdu_session_establishment, i, i,
smf_ip_address, http_version, port);
pdu_threads.push_back(std::move(session_establishment));
}
for (auto &t : pdu_threads) {
t.join();
}
}
//------------------------------------------------------------------------------
void test_all_procedures_for_multiple_threads(std::string smf_ip_address,
uint8_t http_version,
std::string port) {
uint8_t pid = 1;
uint8_t context_id = 1;
//bool status = false;
std::thread t1(&send_pdu_session_establishment_request, pid, smf_ip_address,
http_version, port);
std::thread t2(&send_pdu_session_update_sm_context_establishment, context_id,
smf_ip_address, http_version, port);
std::thread t3(&send_pdu_session_update_sm_context_ue_service_request,
context_id, smf_ip_address, http_version, port);
std::thread t4(&send_pdu_session_update_sm_context_ue_service_request_step2,
context_id, smf_ip_address, http_version, port);
std::thread t5(&send_pdu_session_modification_request_step1, pid, context_id,
smf_ip_address, http_version, port);
std::thread t6(&send_pdu_session_modification_request_step2, context_id,
smf_ip_address, http_version, port);
std::thread t7(&send_pdu_session_modification_complete, pid, context_id,
smf_ip_address, http_version, port);
//PDU Session Release procedure
std::thread t8(&send_pdu_session_release_request, pid, context_id,
smf_ip_address, http_version, port);
std::thread t9(&send_pdu_session_release_resource_release_ack, context_id,
smf_ip_address, http_version, port);
std::thread t10(&send_pdu_session_release_complete, pid, context_id,
smf_ip_address, http_version, port);
//Release SM context
//send_release_sm_context_request(pid, smf_ip_address, http_version, port);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
t9.join();
t10.join();
}
//------------------------------------------------------------------------------
int main(int argc, char *argv[]) {
std::string smf_ip_address;
......@@ -1462,39 +1658,15 @@ int main(int argc, char *argv[]) {
<< std::to_string(http_version) << ", -p " << port.c_str()
<< std::endl;
//PDU Session Establishment procedure
send_pdu_session_establishment_request(smf_ip_address, http_version, port);
usleep(100000);
send_pdu_session_update_sm_context_establishment(smf_ip_address, http_version,
port);
usleep(200000);
//UE-initiated Service Request
send_pdu_session_update_sm_context_ue_service_request(smf_ip_address,
http_version, port);
usleep(200000);
send_pdu_session_update_sm_context_ue_service_request_step2(smf_ip_address,
http_version,
port);
usleep(200000);
//PDU Session Modification
send_pdu_session_modification_request_step1(smf_ip_address, http_version,
port);
usleep(200000);
send_pdu_session_modification_request_step2(smf_ip_address, http_version,
port);
usleep(200000);
send_pdu_session_modification_complete(smf_ip_address, http_version, port);
usleep(200000);
//PDU Session Release procedure
send_pdu_session_release_request(smf_ip_address, http_version, port);
usleep(200000);
send_pdu_session_release_resource_release_ack(smf_ip_address, http_version,
port);
usleep(200000);
send_pdu_session_release_complete(smf_ip_address, http_version, port);
usleep(200000);
//Release SM context
//send_release_sm_context_request(smf_ip_address, http_version, port);
bool cont = false;
uint8_t context_id = 1;
uint8_t pid = 1;
test_all_procedures_for_one_session(pid, context_id, smf_ip_address,
http_version, port);
//test_session_establishment_multiple_threads(smf_ip_address, http_version, port);
//test_all_procedures_for_multiple_threads(smf_ip_address, http_version,
// port);
return 0;
}
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