Add NGAP Handover Notify encoder and trigger on the target NG-RAN

This commit introduces the NG Mobility Management Procedure known as
Handover Notification. The outbound message is sent by the target NG-RAN
and is known as Handover Notify. The procedure is used to indicate to
the AMF that the UE has arrived to the target cell and the NG-based
handover has been successfully completed

* after RRCReconfiguration complete, in the N2 callback for HO success
* add NGAP encoder for the message
* RRC callback to trigger Handover Notify message

Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit is contained in:
Guido Casati
2025-09-18 11:34:30 +02:00
co-authored by batuhan duyuler
parent f66524879d
commit e611d092e9
10 changed files with 159 additions and 1 deletions
+1
View File
@@ -74,6 +74,7 @@ MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_pdu
MESSAGE_DEF(NGAP_HANDOVER_REQUIRED, MESSAGE_PRIORITY_MED, ngap_handover_required_t, ngap_handover_required)
MESSAGE_DEF(NGAP_HANDOVER_FAILURE, MESSAGE_PRIORITY_MED, ngap_handover_failure_t, ngap_handover_failure)
MESSAGE_DEF(NGAP_HANDOVER_REQUEST_ACKNOWLEDGE, MESSAGE_PRIORITY_MED, ngap_handover_request_ack_t, ngap_handover_request_ack)
MESSAGE_DEF(NGAP_HANDOVER_NOTIFY, MESSAGE_PRIORITY_MED, ngap_handover_notify_t, ngap_handover_notify)
/* NGAP -> RRC messages */
MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas )
+18
View File
@@ -70,6 +70,7 @@
#define NGAP_HANDOVER_REQUEST(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_request
#define NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_request_ack
#define NGAP_HANDOVER_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_command
#define NGAP_HANDOVER_NOTIFY(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_notify
#define NGAP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.ngap_ue_release_req
#define NGAP_PDUSESSION_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.ngap_pdusession_release_command
@@ -680,6 +681,23 @@ typedef struct {
byte_array_t handoverCommand;
} ngap_handover_command_t;
/* 9.3.1.16 3GPP TS 38.413 */
typedef struct {
// NR user location information
target_ran_node_id_t target_ng_ran;
uint32_t nrCellIdentity;
} user_location_information_t;
/* 9.2.3.7 3GPP TS 38.413 */
typedef struct {
// RAN UE NGAP ID
uint32_t gNB_ue_ngap_id;
// AMF UE NGAP ID
uint64_t amf_ue_ngap_id;
// User Location Information
user_location_information_t user_info;
} ngap_handover_notify_t;
typedef struct ngap_ue_cap_info_ind_s {
uint32_t gNB_ue_ngap_id;
byte_array_t ue_radio_cap;
+22
View File
@@ -1334,6 +1334,28 @@ void rrc_gNB_send_NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(gNB_RRC_INST *rrc, gNB_RRC_U
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
}
/** @brief Prepare NG Handover Notify message and inform NGAP */
void rrc_gNB_send_NGAP_HANDOVER_NOTIFY(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
{
LOG_I(NR_RRC, "Triggering NGAP Handover Notify\n");
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_HANDOVER_NOTIFY);
ngap_handover_notify_t *ho_notify = &NGAP_HANDOVER_NOTIFY(msg_p);
memset(ho_notify, 0, sizeof(*ho_notify));
nr_rrc_du_container_t *du = get_du_by_cell_id(rrc, rrc->nr_cellid);
ho_notify->gNB_ue_ngap_id = UE->rrc_ue_id;
ho_notify->amf_ue_ngap_id = UE->amf_ue_ngap_id;
ho_notify->user_info.nrCellIdentity = rrc->nr_cellid;
ho_notify->user_info.target_ng_ran.tac = *du->setup_req->cell->info.tac;
ho_notify->user_info.target_ng_ran.targetgNBId = rrc->node_id;
ho_notify->user_info.target_ng_ran.plmn_identity.mcc = du->setup_req->cell->info.plmn.mcc;
ho_notify->user_info.target_ng_ran.plmn_identity.mnc = du->setup_req->cell->info.plmn.mnc;
ho_notify->user_info.target_ng_ran.plmn_identity.mnc_digit_length = du->setup_req->cell->info.plmn.mnc_digit_length;
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
}
void rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t xid)
{
int pdu_sessions_released = 0;
+2
View File
@@ -104,4 +104,6 @@ void rrc_gNB_send_NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(gNB_RRC_INST *rrc, gNB_RRC_U
void rrc_gNB_process_HandoverCommand(gNB_RRC_INST *rrc, const ngap_handover_command_t *msg);
void rrc_gNB_free_Handover_Command(ngap_handover_command_t *msg);
void rrc_gNB_send_NGAP_HANDOVER_NOTIFY(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
#endif
+7
View File
@@ -476,6 +476,13 @@ static void nr_rrc_n2_ho_acknowledge(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
free_byte_array(hoCommand);
}
/** @brief This callback is used by the target gNB
* to trigger the Handover Notify towards the AMF */
static void nr_rrc_n2_ho_complete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
{
rrc_gNB_send_NGAP_HANDOVER_NOTIFY(rrc, UE);
}
/** @brief Callback function to trigger NG Handover Failure on the target gNB, to inform the AMF
* that the preparation of resources has failed (e.g. unsatisfied criteria, gNB is already loaded).
* This message represents an Unsuccessful Outcome of the Handover Resource Allocation */