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

First version for N2 Handover

parent 17940c21
...@@ -97,6 +97,7 @@ COPY --from=oai-amf-builder /usr/lib/x86_64-linux-gnu/libpsl.so.5 . ...@@ -97,6 +97,7 @@ COPY --from=oai-amf-builder /usr/lib/x86_64-linux-gnu/libpsl.so.5 .
WORKDIR /usr/local/lib WORKDIR /usr/local/lib
COPY --from=oai-amf-builder /usr/lib/libboost_system.so.1.67.0 . COPY --from=oai-amf-builder /usr/lib/libboost_system.so.1.67.0 .
COPY --from=oai-amf-builder /usr/lib/libboost_thread.so.1.67.0 . COPY --from=oai-amf-builder /usr/lib/libboost_thread.so.1.67.0 .
COPY --from=oai-amf-builder /usr/lib/libboost_chrono.so.1.67.0 .
COPY --from=oai-amf-builder /usr/local/lib/libpistache.so . COPY --from=oai-amf-builder /usr/local/lib/libpistache.so .
RUN ldconfig RUN ldconfig
......
...@@ -66,13 +66,11 @@ amf_app::amf_app(const amf_config& amf_cfg) ...@@ -66,13 +66,11 @@ amf_app::amf_app(const amf_config& amf_cfg)
: m_amf_ue_ngap_id2ue_ctx(), : m_amf_ue_ngap_id2ue_ctx(),
m_ue_ctx_key(), m_ue_ctx_key(),
m_supi2ue_ctx(), m_supi2ue_ctx(),
m_curl_handle_responses(), m_curl_handle_responses_n2_sm() {
m_curl_handle_responses_gtp() { amf_ue_ngap_id2ue_ctx = {};
amf_ue_ngap_id2ue_ctx = {}; ue_ctx_key = {};
ue_ctx_key = {}; supi2ue_ctx = {};
supi2ue_ctx = {}; curl_handle_responses_n2_sm = {};
curl_handle_responses = {};
curl_handle_responses_gtp = {};
Logger::amf_app().startup("Creating AMF application functionality layer"); Logger::amf_app().startup("Creating AMF application functionality layer");
if (itti_inst->create_task(TASK_AMF_APP, amf_app_task, nullptr)) { if (itti_inst->create_task(TASK_AMF_APP, amf_app_task, nullptr)) {
Logger::amf_app().error("Cannot create task TASK_AMF_APP"); Logger::amf_app().error("Cannot create task TASK_AMF_APP");
...@@ -493,48 +491,21 @@ void amf_app::trigger_nf_deregistration() { ...@@ -493,48 +491,21 @@ void amf_app::trigger_nf_deregistration() {
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------
void amf_app::add_promise( void amf_app::add_promise(
uint32_t id, boost::shared_ptr<boost::promise<uint32_t>>& p) { uint32_t id, boost::shared_ptr<boost::promise<std::string>>& p) {
std::unique_lock lock(m_curl_handle_responses); std::unique_lock lock(m_curl_handle_responses_n2_sm);
curl_handle_responses.emplace(id, p); curl_handle_responses_n2_sm.emplace(id, p);
}
//---------------------------------------------------------------------------------------------
void amf_app::remove_promise(uint32_t id) {
std::unique_lock lock(m_curl_handle_responses);
curl_handle_responses.erase(id);
}
//------------------------------------------------------------------------------
void amf_app::trigger_process_response(uint32_t pid, uint32_t http_code) {
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.count(pid) > 0) {
curl_handle_responses[pid]->set_value(http_code);
// Remove this promise from list
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) { void amf_app::trigger_process_response(uint32_t pid, std::string n2_sm) {
Logger::amf_app().debug( Logger::amf_app().debug(
"Trigger process response: Set promise with ID %u " "Trigger process response: Set promise with ID %u "
"to ready", "to ready",
pid); pid);
std::unique_lock lock(m_curl_handle_responses); std::unique_lock lock(m_curl_handle_responses_n2_sm);
if (curl_handle_responses_gtp.count(pid) > 0) { if (curl_handle_responses_n2_sm.count(pid) > 0) {
curl_handle_responses_gtp[pid]->set_value(gtp_info); curl_handle_responses_n2_sm[pid]->set_value(n2_sm);
// Remove this promise from list // Remove this promise from list
curl_handle_responses_gtp.erase(pid); curl_handle_responses_n2_sm.erase(pid);
} }
} }
...@@ -162,8 +162,8 @@ class amf_app { ...@@ -162,8 +162,8 @@ class amf_app {
void trigger_process_response(uint32_t pid, uint32_t http_code); void trigger_process_response(uint32_t pid, uint32_t http_code);
void add_promise( void add_promise(
uint32_t pid, boost::shared_ptr<boost::promise<GtpTunnel_t>>& p); uint32_t pid, boost::shared_ptr<boost::promise<std::string>>& p);
void trigger_process_response(uint32_t pid, GtpTunnel_t gtp_info); void trigger_process_response(uint32_t pid, std::string n2_sm);
private: private:
// context management // context management
...@@ -175,13 +175,9 @@ class amf_app { ...@@ -175,13 +175,9 @@ class amf_app {
std::map<std::string, std::shared_ptr<ue_context>> supi2ue_ctx; std::map<std::string, std::shared_ptr<ue_context>> supi2ue_ctx;
mutable std::shared_mutex m_supi2ue_ctx; mutable std::shared_mutex m_supi2ue_ctx;
mutable std::shared_mutex m_curl_handle_responses; mutable std::shared_mutex m_curl_handle_responses_n2_sm;
std::map<uint32_t, boost::shared_ptr<boost::promise<uint32_t>>> std::map<uint32_t, boost::shared_ptr<boost::promise<std::string>>>
curl_handle_responses; curl_handle_responses_n2_sm;
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 } // namespace amf_application
......
...@@ -215,9 +215,17 @@ void amf_n11::handle_itti_message( ...@@ -215,9 +215,17 @@ void amf_n11::handle_itti_message(
pdu_session_update_request["n2SmInfoType"] = itti_msg.n2sm_info_type; pdu_session_update_request["n2SmInfoType"] = itti_msg.n2sm_info_type;
pdu_session_update_request["n2SmInfo"]["contentId"] = "n2msg"; pdu_session_update_request["n2SmInfo"]["contentId"] = "n2msg";
std::string json_part = pdu_session_update_request.dump(); std::string json_part = pdu_session_update_request.dump();
std::string n2SmMsg; std::string n2SmMsg = {};
octet_stream_2_hex_stream( octet_stream_2_hex_stream(
(uint8_t*) bdata(itti_msg.n2sm), blength(itti_msg.n2sm), n2SmMsg); (uint8_t*) bdata(itti_msg.n2sm), blength(itti_msg.n2sm), n2SmMsg);
// For N2 HO
if (itti_msg.n2sm_info_type.compare("HANDOVER_REQUIRED") == 0) {
pdu_session_update_request["hoState"] = "PREPARING";
} else if (itti_msg.n2sm_info_type.compare("HANDOVER_REQ_ACK") == 0) {
pdu_session_update_request["hoState"] = "PREPARED";
}
curl_http_client( curl_http_client(
remote_uri, json_part, "", n2SmMsg, supi, itti_msg.pdu_session_id, remote_uri, json_part, "", n2SmMsg, supi, itti_msg.pdu_session_id,
itti_msg.promise_id); itti_msg.promise_id);
...@@ -579,12 +587,6 @@ void amf_n11::curl_http_client( ...@@ -579,12 +587,6 @@ void amf_n11::curl_http_client(
Logger::amf_n11().debug("Get response with HTTP code (%d)", httpCode); Logger::amf_n11().debug("Get response with HTTP code (%d)", httpCode);
Logger::amf_n11().debug("response body %s", response.c_str()); 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);
}
if (static_cast<http_response_codes_e>(httpCode) == if (static_cast<http_response_codes_e>(httpCode) ==
http_response_codes_e::HTTP_RESPONSE_CODE_0) { http_response_codes_e::HTTP_RESPONSE_CODE_0) {
// TODO: should be removed // TODO: should be removed
...@@ -593,6 +595,8 @@ void amf_n11::curl_http_client( ...@@ -593,6 +595,8 @@ void amf_n11::curl_http_client(
// free curl before returning // free curl before returning
curl_slist_free_all(headers); curl_slist_free_all(headers);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
curl_global_cleanup();
free_wrapper((void**) &body_data);
return; return;
} }
...@@ -611,9 +615,12 @@ void amf_n11::curl_http_client( ...@@ -611,9 +615,12 @@ void amf_n11::curl_http_client(
Logger::amf_n11().error("There's no content in the response"); Logger::amf_n11().error("There's no content in the response");
curl_slist_free_all(headers); curl_slist_free_all(headers);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
curl_global_cleanup();
free_wrapper((void**) &body_data);
// TODO: send context response error // TODO: send context response error
return; return;
} }
// TODO: HO
// Transfer N1 to gNB/UE if available // Transfer N1 to gNB/UE if available
if (number_parts > 1) { if (number_parts > 1) {
...@@ -668,10 +675,28 @@ void amf_n11::curl_http_client( ...@@ -668,10 +675,28 @@ void amf_n11::curl_http_client(
"Could not get Json content from the response"); "Could not get Json content from the response");
curl_slist_free_all(headers); curl_slist_free_all(headers);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
curl_global_cleanup();
free_wrapper((void**) &body_data);
// TODO: // TODO:
return; return;
} }
// For N2 HO
bool is_ho_procedure = false;
if (response_data.find("hoState") != response_data.end()) {
is_ho_procedure = true;
}
// Notify to the result
if ((promise_id > 0) and (is_ho_procedure)) {
amf_app_inst->trigger_process_response(
promise_id, n1sm); // actually, N2 SM Info
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
free_wrapper((void**) &body_data);
return;
}
itti_n1n2_message_transfer_request* itti_msg = itti_n1n2_message_transfer_request* itti_msg =
new itti_n1n2_message_transfer_request(TASK_AMF_N11, TASK_AMF_APP); new itti_n1n2_message_transfer_request(TASK_AMF_N11, TASK_AMF_APP);
......
...@@ -1213,35 +1213,35 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) { ...@@ -1213,35 +1213,35 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
std::vector<PDUSessionResourceSetupRequestItem_t> list; std::vector<PDUSessionResourceSetupRequestItem_t> list;
PDUSessionResourceSetupRequestItem_t item = {}; PDUSessionResourceSetupRequestItem_t item = {};
std::map<uint32_t, boost::shared_future<uint32_t>> curl_responses; std::map<uint8_t, boost::shared_future<std::string>> curl_responses;
for (auto pdu_session_resource : pdu_session_resource_list) { for (auto pdu_session_resource : pdu_session_resource_list) {
std::shared_ptr<pdu_session_context> psc = {}; std::shared_ptr<pdu_session_context> psc = {};
if (amf_app_inst->find_pdu_session_context( if (amf_app_inst->find_pdu_session_context(
supi, pdu_session_resource.pduSessionId, psc)) { supi, pdu_session_resource.pduSessionId, psc)) {
item.pduSessionId = psc.get()->pdu_session_id; /* item.pduSessionId = psc.get()->pdu_session_id;
item.s_nssai.sst = psc.get()->snssai.sST; item.s_nssai.sst = psc.get()->snssai.sST;
item.s_nssai.sd = psc.get()->snssai.sD; item.s_nssai.sd = psc.get()->snssai.sD;
item.pduSessionNAS_PDU = nullptr; item.pduSessionNAS_PDU = nullptr;
item.pduSessionResourceSetupRequestTransfer.buf = item.pduSessionResourceSetupRequestTransfer.buf =
pdu_session_resource.HandoverRequiredTransfer.buf; pdu_session_resource.HandoverRequiredTransfer.buf;
item.pduSessionResourceSetupRequestTransfer.size = item.pduSessionResourceSetupRequestTransfer.size =
pdu_session_resource.HandoverRequiredTransfer.size; pdu_session_resource.HandoverRequiredTransfer.size;
list.push_back(item); list.push_back(item);
*/
// Send PDUSessionUpdateSMContextRequest to SMF for each active PDU // Send PDUSessionUpdateSMContextRequest to SMF for each active PDU
// sessions // sessions
// Generate a promise and associate this promise to the curl handle // Generate a promise and associate this promise to the curl handle
uint32_t promise_id = amf_app_inst->generate_promise_id(); uint32_t promise_id = amf_app_inst->generate_promise_id();
Logger::amf_n2().debug("Promise ID generated %d", promise_id); Logger::amf_n2().debug("Promise ID generated %d", promise_id);
boost::shared_ptr<boost::promise<uint32_t>> p = boost::shared_ptr<boost::promise<std::string>> p =
boost::make_shared<boost::promise<uint32_t>>(); boost::make_shared<boost::promise<std::string>>();
boost::shared_future<uint32_t> f = p->get_future(); boost::shared_future<std::string> f = p->get_future();
amf_app_inst->add_promise(promise_id, p); amf_app_inst->add_promise(promise_id, p);
curl_responses.emplace(promise_id, f); curl_responses.emplace(psc.get()->pdu_session_id, f);
Logger::amf_n2().debug( Logger::amf_n2().debug(
"Sending ITTI to trigger PDUSessionUpdateSMContextRequest to SMF to " "Sending ITTI to trigger PDUSessionUpdateSMContextRequest to SMF to "
...@@ -1269,27 +1269,6 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) { ...@@ -1269,27 +1269,6 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
} }
} }
/*
for (auto pdu_session : pdu_sessions) {
if (pdu_session.get() != nullptr) {
item.pduSessionId = pdu_session.get()->pdu_session_id;
item.s_nssai.sst = pdu_session.get()->snssai.sST;
item.s_nssai.sd = pdu_session.get()->snssai.sD;
item.pduSessionNAS_PDU = NULL;
bstring n2sm = pdu_session.get()->n2sm;
if (blength(pdu_session.get()->n2sm) != 0) {
item.pduSessionResourceSetupRequestTransfer.buf =
(uint8_t*) bdata(pdu_session.get()->n2sm);
item.pduSessionResourceSetupRequestTransfer.size =
blength(pdu_session.get()->n2sm);
} else {
Logger::amf_n2().error("n2sm empty!");
}
list.push_back(item);
}
}
*/
// TODO: Handover Response supervision // TODO: Handover Response supervision
// Wait until receiving all responses from SMFs before sending Handover // Wait until receiving all responses from SMFs before sending Handover
bool result = true; bool result = true;
...@@ -1303,16 +1282,33 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) { ...@@ -1303,16 +1282,33 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
assert(curl_responses.begin()->second.has_value()); assert(curl_responses.begin()->second.has_value());
assert(!curl_responses.begin()->second.has_exception()); assert(!curl_responses.begin()->second.has_exception());
// Wait for the result from APP and send reply to AMF // Wait for the result from APP and send reply to AMF
uint32_t response_code = curl_responses.begin()->second.get(); std::string n2_sm = curl_responses.begin()->second.get();
Logger::ngap().debug(
if (static_cast<http_response_codes_e>(response_code) == "Got result for PDU Session ID %d", curl_responses.begin()->first);
http_response_codes_e::HTTP_RESPONSE_CODE_200_OK) { if (n2_sm.size() > 0) {
result = result && true; result = result && true;
std::shared_ptr<pdu_session_context> psc = {};
if (amf_app_inst->find_pdu_session_context(
supi, curl_responses.begin()->first, psc)) {
item.pduSessionId = psc.get()->pdu_session_id;
item.s_nssai.sst = psc.get()->snssai.sST;
item.s_nssai.sd = psc.get()->snssai.sD;
item.pduSessionNAS_PDU = nullptr;
unsigned int data_len = n2_sm.length();
unsigned char* data = (unsigned char*) malloc(data_len + 1);
memset(data, 0, data_len + 1);
memcpy((void*) data, (void*) n2_sm.c_str(), data_len);
item.pduSessionResourceSetupRequestTransfer.buf = data;
item.pduSessionResourceSetupRequestTransfer.size = data_len;
list.push_back(item);
// free memory
free_wrapper((void**) &data);
}
} else { } else {
result = false; result = false;
} }
Logger::ngap().debug(
"Got result for promise ID %d", curl_responses.begin()->first);
} else { } else {
result = true; result = true;
} }
...@@ -1407,19 +1403,19 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) { ...@@ -1407,19 +1403,19 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) {
Logger::ngap().debug("QFI %lu", qosflowidentifiervalue); Logger::ngap().debug("QFI %lu", qosflowidentifiervalue);
// Send PDUSessionUpdateSMContextRequest to SMF for each active PDU sessions // Send PDUSessionUpdateSMContextRequest to SMF for each active PDU sessions
std::map<uint32_t, boost::shared_future<GtpTunnel_t>> curl_responses; std::map<uint8_t, boost::shared_future<std::string>> curl_responses;
for (auto pdu_session_resource : list) { for (auto pdu_session_resource : list) {
// Generate a promise and associate this promise to the curl handle // Generate a promise and associate this promise to the curl handle
uint32_t promise_id = amf_app_inst->generate_promise_id(); uint32_t promise_id = amf_app_inst->generate_promise_id();
Logger::amf_n2().debug("Promise ID generated %d", promise_id); Logger::amf_n2().debug("Promise ID generated %d", promise_id);
boost::shared_ptr<boost::promise<GtpTunnel_t>> p = boost::shared_ptr<boost::promise<std::string>> p =
boost::make_shared<boost::promise<GtpTunnel_t>>(); boost::make_shared<boost::promise<std::string>>();
boost::shared_future<GtpTunnel_t> f = p->get_future(); boost::shared_future<std::string> f = p->get_future();
amf_app_inst->add_promise(promise_id, p); amf_app_inst->add_promise(promise_id, p);
curl_responses.emplace(promise_id, f); curl_responses.emplace(pdu_session_resource.pduSessionId, f);
Logger::amf_n2().debug( Logger::amf_n2().debug(
"Sending ITTI to trigger PDUSessionUpdateSMContextRequest to SMF to " "Sending ITTI to trigger PDUSessionUpdateSMContextRequest to SMF to "
...@@ -1445,9 +1441,22 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) { ...@@ -1445,9 +1441,22 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) {
i->get_msg_name()); i->get_msg_name());
} }
} }
// send HandoverCommandMsg to Source gnb
std::unique_ptr<HandoverCommandMsg> handovercommand =
std::make_unique<HandoverCommandMsg>();
handovercommand->setMessageType();
handovercommand->setAmfUeNgapId(amf_ue_ngap_id);
handovercommand->setRanUeNgapId(unc.get()->ran_ue_ngap_id);
handovercommand->setHandoverType(Ngap_HandoverType_intra5gs);
std::shared_ptr<nas_context> nc =
amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id);
std::vector<PDUSessionResourceHandoverItem_t> handover_list;
PDUSessionResourceHandoverItem_t item = {};
// TODO: wait for response from SMF and transfer T-RAN N3 information/ or // TODO: wait for response from SMF and transfer T-RAN N3 information/ or
// T-UPF to the source gNB // T-UPF to the source gNB
bool result = true; bool result = true;
while (!curl_responses.empty()) { while (!curl_responses.empty()) {
boost::future_status status; boost::future_status status;
...@@ -1459,62 +1468,66 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) { ...@@ -1459,62 +1468,66 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) {
assert(curl_responses.begin()->second.has_value()); assert(curl_responses.begin()->second.has_value());
assert(!curl_responses.begin()->second.has_exception()); assert(!curl_responses.begin()->second.has_exception());
// Wait for the result from APP and send reply to AMF // Wait for the result from APP and send reply to AMF
GtpTunnel_t gtp_info = curl_responses.begin()->second.get(); std::string n2_sm = curl_responses.begin()->second.get();
// TODO: process gtp_info
Logger::ngap().debug( Logger::ngap().debug(
"Got result for promise ID %d", curl_responses.begin()->first); "Got result for PDU Session ID %d", curl_responses.begin()->first);
if (n2_sm.size() > 0) {
result = result && true;
item.pduSessionId = curl_responses.begin()->first;
unsigned int data_len = n2_sm.length();
unsigned char* data = (unsigned char*) malloc(data_len + 1);
memset(data, 0, data_len + 1);
memcpy((void*) data, (void*) n2_sm.c_str(), data_len);
item.HandoverCommandTransfer.buf = data;
item.HandoverCommandTransfer.size = data_len;
handover_list.push_back(item);
// free memory
free_wrapper((void**) &data);
} else {
result = false;
}
} else { } else {
result = true; result = true;
} }
curl_responses.erase(curl_responses.begin()); curl_responses.erase(curl_responses.begin());
} }
// TODO: process result /*
item.pduSessionId = list[0].pduSessionId;
// send HandoverCommandMsg to Source gnb // qosFLowtobeforwardedlist
std::unique_ptr<HandoverCommandMsg> handovercommand = std::vector<QosFlowToBeForwardedItem_t> forward_list;
std::make_unique<HandoverCommandMsg>(); QosFlowToBeForwardedItem_t forward_item;
handovercommand->setMessageType(); forward_item.QFI = qosflowidentifiervalue;
handovercommand->setAmfUeNgapId(amf_ue_ngap_id); forward_list.push_back(forward_item);
handovercommand->setRanUeNgapId(unc.get()->ran_ue_ngap_id); // set dlforwardingup_tnlinformation
handovercommand->setHandoverType(Ngap_HandoverType_intra5gs); // TransportLayerAddress *transportlayeraddress = new
std::shared_ptr<nas_context> nc = TransportLayerAddress();
amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id); // transportlayeraddress->setTransportLayerAddress(n3_ip_address);
// GtpTeid *gtpTeid = new GtpTeid();
std::vector<PDUSessionResourceHandoverItem_t> handover_list; // gtpTeid->setGtpTeid(teid);
PDUSessionResourceHandoverItem_t item = {}; PDUSessionResourceHandoverCommandTransfer* handovercommandtransfer =
item.pduSessionId = list[0].pduSessionId; new PDUSessionResourceHandoverCommandTransfer();
// qosFLowtobeforwardedlist handovercommandtransfer->setQosFlowToBeForwardedList(forward_list);
std::vector<QosFlowToBeForwardedItem_t> forward_list; GtpTunnel_t uptlinfo = {};
QosFlowToBeForwardedItem_t forward_item; uptlinfo.gtp_teid = teid;
forward_item.QFI = qosflowidentifiervalue; uptlinfo.ip_address = n3_ip_address;
forward_list.push_back(forward_item); handovercommandtransfer->setUPTransportLayerInformation(uptlinfo);
// set dlforwardingup_tnlinformation
// TransportLayerAddress *transportlayeraddress = new TransportLayerAddress(); uint8_t buffer_ho_cmd_transfer[BUFFER_SIZE_512];
// transportlayeraddress->setTransportLayerAddress(n3_ip_address); int encoded_size =
// GtpTeid *gtpTeid = new GtpTeid(); handovercommandtransfer->encodePDUSessionResourceHandoverCommandTransfer(
// gtpTeid->setGtpTeid(teid); buffer_ho_cmd_transfer, BUFFER_SIZE_512);
PDUSessionResourceHandoverCommandTransfer* handovercommandtransfer = item.HandoverCommandTransfer.buf = buffer_ho_cmd_transfer;
new PDUSessionResourceHandoverCommandTransfer(); item.HandoverCommandTransfer.size = encoded_size;
handovercommandtransfer->setQosFlowToBeForwardedList(forward_list); handover_list.push_back(item);
GtpTunnel_t uptlinfo = {}; */
uptlinfo.gtp_teid = teid;
uptlinfo.ip_address = n3_ip_address;
handovercommandtransfer->setUPTransportLayerInformation(uptlinfo);
uint8_t buffer_ho_cmd_transfer[BUFFER_SIZE_512];
int encoded_size =
handovercommandtransfer->encodePDUSessionResourceHandoverCommandTransfer(
buffer_ho_cmd_transfer, BUFFER_SIZE_512);
item.HandoverCommandTransfer.buf = buffer_ho_cmd_transfer;
item.HandoverCommandTransfer.size = encoded_size;
handover_list.push_back(item);
handovercommand->setPduSessionResourceHandoverList(handover_list); handovercommand->setPduSessionResourceHandoverList(handover_list);
handovercommand->setTargetToSource_TransparentContainer(targetTosource); handovercommand->setTargetToSource_TransparentContainer(targetTosource);
uint8_t buffer[BUFFER_SIZE_1024]; uint8_t buffer[BUFFER_SIZE_1024];
encoded_size = handovercommand->encode2buffer(buffer, BUFFER_SIZE_1024); int encoded_size = handovercommand->encode2buffer(buffer, BUFFER_SIZE_1024);
bstring b = blk2bstr(buffer, encoded_size); bstring b = blk2bstr(buffer, encoded_size);
sctp_s_38412.sctp_send_msg(unc.get()->gnb_assoc_id, 0, &b); sctp_s_38412.sctp_send_msg(unc.get()->gnb_assoc_id, 0, &b);
} }
......
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