Commit 05081de8 authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Merge branch 'fix_n2_handover' into 'develop'

Fix N2 handover

See merge request oai/cn5g/oai-cn5g-amf!206
parents 2fd90593 be14c0f3
......@@ -1309,6 +1309,28 @@ void amf_n2::handle_itti_message(itti_ue_context_release_complete& itti_msg) {
return;
}
std::shared_ptr<ue_ngap_context> unc = {};
if (!amf_ue_id_2_ue_ngap_context(amf_ue_ngap_id, unc)) {
Logger::amf_app().error(
"No UE NGAP context for amf_ngap_id %s, exit", amf_ue_ngap_id);
return;
}
std::shared_ptr<gnb_context> gc = {};
if (!assoc_id_2_gnb_context(itti_msg.assoc_id, gc)) {
Logger::amf_n2().error(
"gNB with assoc_id (%d) is illegal", itti_msg.assoc_id);
return;
}
//verify release cause -> if HandoverSuccessful no further operations required
if(unc->release_cause == Ngap_CauseRadioNetwork_successful_handover && gc->gnb_id == unc->release_gnb){
remove_ran_ue_ngap_id_2_ngap_context(ran_ue_ngap_id, gc->gnb_id);
unc->release_cause = 0;
return;
}
// Change UE status from CM-CONNECTED to CM-IDLE
std::shared_ptr<nas_context> nc = {};
if (!amf_n1_inst->amf_ue_id_2_nas_context(amf_ue_ngap_id, nc)) {
......@@ -1722,8 +1744,8 @@ bool amf_n2::handle_itti_message(itti_handover_required& itti_msg) {
// Request to Target RAN
handover_request->setPduSessionResourceSetupList(list);
uint8_t buffer[BUFFER_SIZE_4096];
int encoded_size = handover_request->Encode(buffer, BUFFER_SIZE_4096);
uint8_t buffer[BUFFER_SIZE_8192];
int encoded_size = handover_request->Encode(buffer, BUFFER_SIZE_8192);
bstring b = blk2bstr(buffer, encoded_size);
std::shared_ptr<gnb_context> gc_target = {};
if (!gnb_id_2_gnb_context(gnb_id_value, gc_target)) {
......@@ -1819,7 +1841,7 @@ void amf_n2::handle_itti_message(itti_handover_request_Ack& itti_msg) {
itti_msg->n2sm_info_type = "HANDOVER_REQ_ACK";
itti_msg->ho_state = "PREPARED";
itti_msg->amf_ue_ngap_id = amf_ue_ngap_id;
itti_msg->ran_ue_ngap_id = ran_ue_ngap_id;
itti_msg->ran_ue_ngap_id = unc.get()->ran_ue_ngap_id;
itti_msg->promise_id = promise_id;
int ret = itti_inst->send_msg(itti_msg);
......@@ -2031,17 +2053,30 @@ void amf_n2::handle_itti_message(itti_handover_notify& itti_msg) {
sctp_s_38412.sctp_send_msg(unc->gnb_assoc_id, 0, &b);
bdestroy_wrapper(&b);
if (!amf_ue_id_2_ue_ngap_context(amf_ue_ngap_id, unc)) {
Logger::amf_n2().error(
"No UE NGAP context with amf_ue_ngap_id (" AMF_UE_NGAP_ID_FMT ")",
amf_ue_ngap_id);
string ue_context_key =
conv::get_ue_context_key(unc->ran_ue_ngap_id, amf_ue_ngap_id);
std::shared_ptr<ue_context> uc = {};
if (!amf_app_inst->ran_amf_id_2_ue_context(ue_context_key, uc)) {
Logger::amf_app().error(
"No UE context for ran_amf_id %s, exit", ue_context_key.c_str());
return;
}
//update the NGAP Context
unc->release_cause = Ngap_CauseRadioNetwork_successful_handover;
unc->release_gnb = uc->gnb_id;
unc->ran_ue_ngap_id = ran_ue_ngap_id; // store new RAN ID
unc->target_ran_ue_ngap_id = 0; // Clear target RAN ID
unc->ng_ue_state = NGAP_UE_CONNECTED;
unc->gnb_assoc_id = itti_msg.assoc_id; // update serving gNB
//update NAS Context
nc->ran_ue_ngap_id = ran_ue_ngap_id;
//update User Context
uc->ran_ue_ngap_id = ran_ue_ngap_id;
uc->gnb_id = gc->gnb_id;
set_ran_ue_ngap_id_2_ue_ngap_context(ran_ue_ngap_id, gc->gnb_id, unc);
}
......
......@@ -71,7 +71,7 @@ void octet_stream_2_hex_stream(uint8_t* buf, int len, std::string& out) {
}
tmp[2 * len] = '\0';
out = tmp;
Logger::amf_sbi().debug("n1sm buffer: %s", out.c_str());
Logger::amf_sbi().debug("Buffer: %s", out.c_str());
}
//------------------------------------------------------------------------------
......
......@@ -31,6 +31,7 @@
constexpr auto CURL_MIME_BOUNDARY = "----Boundary";
#define CURL_TIMEOUT_MS 1000L
#define BUFFER_SIZE_8192 8192
#define BUFFER_SIZE_4096 4096
#define BUFFER_SIZE_2048 2048
#define BUFFER_SIZE_1024 1024
......
......@@ -303,10 +303,10 @@ bool conv::octet_string_2_bit_string(
//------------------------------------------------------------------------------
bool conv::bstring_2_bit_string(const bstring& b_str, BIT_STRING_t& bit_str) {
OCTET_STRING_t octet_str;
bstring_2_octet_string(b_str, octet_str);
octet_string_2_bit_string(octet_str, bit_str, 0);
/*
//OCTET_STRING_t octet_str;
//bstring_2_octet_string(b_str, octet_str);
// octet_string_2_bit_string(octet_str, bit_str, 0);
int size = blength(b_str);
if (!b_str or size <= 0) return false;
......@@ -315,13 +315,13 @@ bool conv::bstring_2_bit_string(const bstring& b_str, BIT_STRING_t& bit_str) {
bit_str.buf = (uint8_t*) calloc(size + 1, sizeof(uint8_t));
if (!bit_str.buf) return false;
if (check_bstring (b_str)) memcpy((void*) bit_str.buf, (char*)octet_str.buf,
if (check_bstring (b_str)) memcpy((void*) bit_str.buf, (char*)b_str->data,
blength(b_str));
((uint8_t*) bit_str.buf)[size] = '\0';
bit_str.size = size;
bit_str.bits_unused = 0;
*/
return true;
}
......
......@@ -39,20 +39,24 @@ class ue_ngap_context {
ran_ue_ngap_id = 0;
amf_ue_ngap_id = 0;
target_ran_ue_ngap_id = 0;
sctp_stream_recv = {};
sctp_stream_send = {};
gnb_assoc_id = {};
target_gnb_assoc_id = {};
ue_context_request = false;
s_tmsi_5g = {};
s_setid = {};
s_pointer = {};
s_tmsi = {};
tai = {};
ng_ue_state = NGAP_UE_INVALID_STATE;
ncc = 0;
initial_ue_msg.buf = new uint8_t[BUFFER_SIZE_1024];
initial_ue_msg.size = 0;
sctp_stream_recv = {};
sctp_stream_send = {};
release_gnb = {};
release_cause = {};
gnb_assoc_id = {};
target_gnb_assoc_id = {};
ue_context_request = false;
s_tmsi_5g = {};
s_setid = {};
s_pointer = {};
s_tmsi = {};
tai = {};
ng_ue_state = NGAP_UE_INVALID_STATE;
ncc = 0;
initial_ue_msg.buf = new uint8_t[BUFFER_SIZE_1024];
initial_ue_msg.size = 0;
}
virtual ~ue_ngap_context() {
......@@ -85,6 +89,10 @@ class ue_ngap_context {
uint8_t ncc; // Next Hop Chaining Counter
OCTET_STRING_t initial_ue_msg; // for AMF re-allocation
// Release Command Cause and source gNB ID in case of HO
Ngap_CauseRadioNetwork_t release_cause;
uint32_t release_gnb;
};
#endif
......@@ -221,7 +221,7 @@ bool HandoverCommandMsg::getPDUSessionResourceToReleaseListHOCmd(
//------------------------------------------------------------------------------
void HandoverCommandMsg::setTargetToSource_TransparentContainer(
const OCTET_STRING_t& targetTosource) {
targetToSource_TransparentContainer = targetTosource;
conv::octet_string_copy(targetToSource_TransparentContainer, targetTosource);
Ngap_HandoverCommandIEs_t* ie =
(Ngap_HandoverCommandIEs_t*) calloc(1, sizeof(Ngap_HandoverCommandIEs_t));
......@@ -229,7 +229,9 @@ void HandoverCommandMsg::setTargetToSource_TransparentContainer(
ie->criticality = Ngap_Criticality_reject;
ie->value.present =
Ngap_HandoverCommandIEs__value_PR_TargetToSource_TransparentContainer;
ie->value.choice.TargetToSource_TransparentContainer = targetTosource;
conv::octet_string_copy(
ie->value.choice.TargetToSource_TransparentContainer, targetTosource);
int ret = ASN_SEQUENCE_ADD(&handoverCommandIEs->protocolIEs.list, ie);
if (ret != 0) Logger::ngap().error("Encode HandoverType IE error");
}
......
......@@ -36,6 +36,17 @@ HandoverRequest::HandoverRequest() : NgapMessage() {
mobilityRestrictionList = std::nullopt;
handoverRequestIEs = nullptr;
amfUeNgapId = {};
handoverType = {};
cause = {};
ueAggregateMaximumBitRate = {};
ueSecurityCapabilities = {};
securityContext = {};
pDUSessionResourceSetupList = {};
allowedNSSAI = {};
SourceToTarget_TransparentContainer = {};
guami = {};
setMessageType(NgapMessageType::HANDOVER_REQUEST);
initialize();
}
......@@ -341,7 +352,9 @@ void HandoverRequest::setSourceToTarget_TransparentContainer(
ie->criticality = Ngap_Criticality_reject;
ie->value.present =
Ngap_HandoverRequestIEs__value_PR_SourceToTarget_TransparentContainer;
ie->value.choice.SourceToTarget_TransparentContainer = sourceTotarget;
conv::octet_string_copy(
ie->value.choice.SourceToTarget_TransparentContainer, sourceTotarget);
int ret = ASN_SEQUENCE_ADD(&handoverRequestIEs->protocolIEs.list, ie);
if (ret != 0)
Logger::ngap().error("Encode SourceToTarget_TransparentContainer IE error");
......
......@@ -20,6 +20,7 @@
*/
#include "HandoverRequestAck.hpp"
#include "conversions.hpp"
#include "logger.hpp"
......@@ -107,7 +108,8 @@ void HandoverRequestAck::setTargetToSource_TransparentContainer(
ie->criticality = Ngap_Criticality_reject;
ie->value.present =
Ngap_HandoverRequestAcknowledgeIEs__value_PR_TargetToSource_TransparentContainer;
ie->value.choice.TargetToSource_TransparentContainer = targetTosource;
conv::octet_string_copy(
ie->value.choice.TargetToSource_TransparentContainer, targetTosource);
int ret = ASN_SEQUENCE_ADD(&handoverRequestAckIEs->protocolIEs.list, ie);
if (ret != 0)
Logger::ngap().error(
......@@ -313,9 +315,10 @@ bool HandoverRequestAck::decodeFromPdu(Ngap_NGAP_PDU_t* ngapMsgPdu) {
Ngap_Criticality_reject &&
handoverRequestAckIEs->protocolIEs.list.array[i]->value.present ==
Ngap_HandoverRequestAcknowledgeIEs__value_PR_TargetToSource_TransparentContainer) {
TargetToSource_TransparentContainer =
conv::octet_string_copy(
TargetToSource_TransparentContainer,
handoverRequestAckIEs->protocolIEs.list.array[i]
->value.choice.TargetToSource_TransparentContainer;
->value.choice.TargetToSource_TransparentContainer);
} else {
Logger::ngap().error(
"Decoded NGAP TargetToSource_TransparentContainer IE error");
......
......@@ -20,6 +20,8 @@
*/
#include "HandoverRequiredMsg.hpp"
#include "conversions.hpp"
#include "logger.hpp"
extern "C" {
......@@ -269,9 +271,10 @@ bool HandoverRequiredMsg::decodeFromPdu(Ngap_NGAP_PDU_t* ngapMsgPdu) {
Ngap_Criticality_reject &&
handoverRequiredIEs->protocolIEs.list.array[i]->value.present ==
Ngap_HandoverRequiredIEs__value_PR_SourceToTarget_TransparentContainer) {
sourceToTarget_TransparentContainer =
conv::octet_string_copy(
sourceToTarget_TransparentContainer,
handoverRequiredIEs->protocolIEs.list.array[i]
->value.choice.SourceToTarget_TransparentContainer;
->value.choice.SourceToTarget_TransparentContainer);
} else {
Logger::ngap().error(
"Decoded NGAP SourceToTarget_TransparentContainer IE error");
......
......@@ -41,6 +41,7 @@ NgapMessage::NgapMessage() {
//------------------------------------------------------------------------------
NgapMessage::~NgapMessage() {
ASN_STRUCT_FREE(asn_DEF_Ngap_NGAP_PDU, ngapPdu);
Logger::ngap().debug("Free NGAP Message PDU");
}
......
......@@ -814,6 +814,7 @@ int handover_notification(
int handover_request(
const sctp_assoc_id_t assoc_id, const sctp_stream_id_t stream,
struct Ngap_NGAP_PDU* message_p) {
// TODO: To be verified
Logger::ngap().debug(
"Sending ITTI Handover Resource Allocation (HandoverRequest) to "
"TASK_AMF_N2");
......@@ -846,7 +847,27 @@ int handover_request_ack(
const sctp_assoc_id_t assoc_id, const sctp_stream_id_t stream,
struct Ngap_NGAP_PDU* message_p) {
Logger::ngap().debug("Handling Handover Request Ack (AMF->AN)");
// TODO:
output_wrapper::print_asn_msg(&asn_DEF_Ngap_NGAP_PDU, message_p);
HandoverRequestAck* handover_request_ack = new HandoverRequestAck();
if (!handover_request_ack->decodeFromPdu(message_p)) {
Logger::ngap().error("Decoding Handover Request Acknowledge message error");
return RETURNerror;
}
auto itti_msg =
std::make_shared<itti_handover_request_Ack>(TASK_NGAP, TASK_AMF_N2);
itti_msg->assoc_id = assoc_id;
itti_msg->stream = stream;
itti_msg->handoverrequestAck = handover_request_ack;
int ret = itti_inst->send_msg(itti_msg);
if (0 != ret) {
Logger::ngap().error(
"Could not send ITTI message %s to task TASK_AMF_N2",
itti_msg->get_msg_name());
return RETURNerror;
}
return RETURNok;
}
......
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