Commit 7f52e8b8 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Send PDUSessionSMContextUpdate to get N3 info from SMF

parent 71fea8b2
......@@ -66,11 +66,13 @@ amf_app::amf_app(const amf_config& amf_cfg)
: m_amf_ue_ngap_id2ue_ctx(),
m_ue_ctx_key(),
m_supi2ue_ctx(),
m_curl_handle_responses() {
amf_ue_ngap_id2ue_ctx = {};
ue_ctx_key = {};
supi2ue_ctx = {};
curl_handle_responses = {};
m_curl_handle_responses(),
m_curl_handle_responses_gtp() {
amf_ue_ngap_id2ue_ctx = {};
ue_ctx_key = {};
supi2ue_ctx = {};
curl_handle_responses = {};
curl_handle_responses_gtp = {};
Logger::amf_app().startup("Creating AMF application functionality layer");
if (itti_inst->create_task(TASK_AMF_APP, amf_app_task, nullptr)) {
Logger::amf_app().error("Cannot create task TASK_AMF_APP");
......@@ -514,3 +516,24 @@ void amf_app::trigger_process_response(uint32_t pid, uint32_t http_code) {
curl_handle_responses.erase(pid);
}
}
//---------------------------------------------------------------------------------------------
void amf_app::add_promise(
uint32_t id, boost::shared_ptr<boost::promise<GtpTunnel_t>>& p) {
std::unique_lock lock(m_curl_handle_responses_gtp);
curl_handle_responses_gtp.emplace(id, p);
}
//------------------------------------------------------------------------------
void amf_app::trigger_process_response(uint32_t pid, GtpTunnel_t gtp_info) {
Logger::amf_app().debug(
"Trigger process response: Set promise with ID %u "
"to ready",
pid);
std::unique_lock lock(m_curl_handle_responses);
if (curl_handle_responses_gtp.count(pid) > 0) {
curl_handle_responses_gtp[pid]->set_value(gtp_info);
// Remove this promise from list
curl_handle_responses_gtp.erase(pid);
}
}
......@@ -161,6 +161,10 @@ class amf_app {
void trigger_process_response(uint32_t pid, uint32_t http_code);
void add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<GtpTunnel_t>>& p);
void trigger_process_response(uint32_t pid, GtpTunnel_t gtp_info);
private:
// context management
std::map<long, std::shared_ptr<ue_context>> amf_ue_ngap_id2ue_ctx;
......@@ -174,6 +178,10 @@ class amf_app {
mutable std::shared_mutex m_curl_handle_responses;
std::map<uint32_t, boost::shared_ptr<boost::promise<uint32_t>>>
curl_handle_responses;
mutable std::shared_mutex m_curl_handle_responses_gtp;
std::map<uint32_t, boost::shared_ptr<boost::promise<GtpTunnel_t>>>
curl_handle_responses_gtp;
};
} // namespace amf_application
......
......@@ -94,10 +94,7 @@ void octet_stream_2_hex_stream(uint8_t* buf, int len, std::string& out) {
printf("n1sm buffer: %s\n", out.c_str());
}
/****************************************************/
/** used to run NF(s) consumer, like smf_client ****/
/***************************************************/
//------------------------------------------------------------------------------
void amf_n11_task(void*);
//------------------------------------------------------------------------------
void amf_n11_task(void*) {
......@@ -583,6 +580,7 @@ void amf_n11::curl_http_client(
Logger::amf_n11().debug("Response body %s", response.c_str());
// Notify to the result if necessary
// TODO: Notify with the N3 information
if (promise_id > 0) {
amf_app_inst->trigger_process_response(promise_id, httpCode);
}
......
......@@ -1236,7 +1236,6 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
// Generate a promise and associate this promise to the curl handle
uint32_t promise_id = amf_app_inst->generate_promise_id();
Logger::amf_n2().debug("Promise ID generated %d", promise_id);
uint32_t* pid_ptr = &promise_id;
boost::shared_ptr<boost::promise<uint32_t>> p =
boost::make_shared<boost::promise<uint32_t>>();
boost::shared_future<uint32_t> f = p->get_future();
......@@ -1407,6 +1406,70 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) {
(long) QosFlowWithDataForwardinglist[0].qosFlowIdentifier;
Logger::ngap().debug("QFI %lu", qosflowidentifiervalue);
// Send PDUSessionUpdateSMContextRequest to SMF for each active PDU sessions
std::map<uint32_t, boost::shared_future<GtpTunnel_t>> curl_responses;
for (auto pdu_session_resource : list) {
// Generate a promise and associate this promise to the curl handle
uint32_t promise_id = amf_app_inst->generate_promise_id();
Logger::amf_n2().debug("Promise ID generated %d", promise_id);
boost::shared_ptr<boost::promise<GtpTunnel_t>> p =
boost::make_shared<boost::promise<GtpTunnel_t>>();
boost::shared_future<GtpTunnel_t> f = p->get_future();
amf_app_inst->add_promise(promise_id, p);
curl_responses.emplace(promise_id, f);
Logger::amf_n2().debug(
"Sending ITTI to trigger PDUSessionUpdateSMContextRequest to SMF to "
"task TASK_AMF_N11");
itti_nsmf_pdusession_update_sm_context* itti_msg =
new itti_nsmf_pdusession_update_sm_context(TASK_NGAP, TASK_AMF_N11);
itti_msg->pdu_session_id = pdu_session_resource.pduSessionId;
itti_msg->n2sm = blk2bstr(
pdu_session_resource.handoverRequestAcknowledgeTransfer.buf,
pdu_session_resource.handoverRequestAcknowledgeTransfer.size);
itti_msg->is_n2sm_set = true;
itti_msg->n2sm_info_type = "HANDOVER_REQ_ACK";
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->promise_id = promise_id;
std::shared_ptr<itti_nsmf_pdusession_update_sm_context> i =
std::shared_ptr<itti_nsmf_pdusession_update_sm_context>(itti_msg);
int ret = itti_inst->send_msg(i);
if (0 != ret) {
Logger::ngap().error(
"Could not send ITTI message %s to task TASK_AMF_N11",
i->get_msg_name());
}
}
// TODO: wait for response from SMF and transfer T-RAN N3 information/ or
// T-UPF to the source gNB
bool result = true;
while (!curl_responses.empty()) {
boost::future_status status;
// wait for timeout or ready
status = curl_responses.begin()->second.wait_for(
boost::chrono::milliseconds(FUTURE_STATUS_TIMEOUT_MS));
if (status == boost::future_status::ready) {
assert(curl_responses.begin()->second.is_ready());
assert(curl_responses.begin()->second.has_value());
assert(!curl_responses.begin()->second.has_exception());
// Wait for the result from APP and send reply to AMF
GtpTunnel_t gtp_info = curl_responses.begin()->second.get();
// TODO: process gtp_info
Logger::ngap().debug(
"Got result for promise ID %d", curl_responses.begin()->first);
} else {
result = true;
}
curl_responses.erase(curl_responses.begin());
}
// TODO: process result
// send HandoverCommandMsg to Source gnb
std::unique_ptr<HandoverCommandMsg> handovercommand =
std::make_unique<HandoverCommandMsg>();
......
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