Add NGAP Handover Request Acknowledge encoder and RRC callback

This commit completes the NG Mobility Management Procedure known as
Handover Resource Allocation. The outbound message is sent by the
target NG-RAN and is known as Handover Request Acknowledge.

Major changes:

* add RRC callback to trigger the generation of NG Handover
  Request Acknowledge on the target NG-RAN
* add NG Handover Request Acknowledge encoder

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 461cfb7911
commit fa75484e13
7 changed files with 215 additions and 3 deletions
+1
View File
@@ -73,6 +73,7 @@ MESSAGE_DEF(NGAP_PDUSESSION_MODIFY_RESP , MESSAGE_PRIORITY_MED, ngap_pd
MESSAGE_DEF(NGAP_PDUSESSION_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, ngap_pdusession_release_resp_t , ngap_pdusession_release_resp)
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)
/* NGAP -> RRC messages */
MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas )
+31
View File
@@ -68,6 +68,7 @@
#define NGAP_HANDOVER_REQUIRED(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_required
#define NGAP_HANDOVER_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_failure
#define NGAP_HANDOVER_REQUEST(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_request
#define NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.ngap_handover_request_ack
#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
@@ -617,6 +618,36 @@ typedef struct {
nr_guami_t guami;
} ngap_handover_request_t;
/* 9.3.4.11 3GPP TS 38.413 */
typedef struct {
// QoS Flow Setup Response List
uint8_t nb_of_qos_flow;
pdusession_associate_qosflow_t qos_setup_list[QOSFLOW_MAX_VALUE];
// DL NG-U UP TNL Information
uint32_t gtp_teid;
transport_layer_addr_t gNB_addr;
} ho_request_ack_transfer_t;
/* 9.2.3.5 3GPP TS 38.413 */
typedef struct {
// PDU Session ID (M)
uint8_t pdu_session_id;
// Handover Request Acknowledge Transfer (M)
ho_request_ack_transfer_t ack_transfer;
} pdu_session_resource_admitted_t;
typedef struct {
// AMF UE NGAP ID
uint32_t gNB_ue_ngap_id;
// RAN UE NGAP ID
uint64_t amf_ue_ngap_id;
// PDU Session Resource Admitted List
pdu_session_resource_admitted_t pdusessions[NGAP_MAX_PDU_SESSION];
uint8_t nb_of_pdusessions;
// Target to Source Transparent Container
byte_array_t target2source;
} ngap_handover_request_ack_t;
typedef struct ngap_ue_cap_info_ind_s {
uint32_t gNB_ue_ngap_id;
byte_array_t ue_radio_cap;
+36
View File
@@ -1270,6 +1270,42 @@ void rrc_gNB_send_NGAP_UE_CAPABILITIES_IND(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE,
LOG_I(NR_RRC,"Send message to ngap: NGAP_UE_CAPABILITIES_IND\n");
}
void rrc_gNB_send_NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, byte_array_t ho_command)
{
LOG_D(NR_RRC, "Sending Handover Request Acknowledge\n");
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_HANDOVER_REQUEST_ACKNOWLEDGE);
ngap_handover_request_ack_t *msg = &NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(msg_p);
memset(msg, 0, sizeof(*msg));
// RAN UE NGAP ID
msg->gNB_ue_ngap_id = UE->rrc_ue_id;
// AMF UE NGAP ID
msg->amf_ue_ngap_id = UE->amf_ue_ngap_id;
// PDU Session Resource Admitted List
msg->nb_of_pdusessions = UE->nb_of_pdusessions;
for (int i = 0; i < UE->nb_of_pdusessions; i++) {
rrc_pdu_session_param_t *session = &UE->pduSession[i];
session->status = PDU_SESSION_STATUS_ESTABLISHED;
// PDU Session ID
msg->pdusessions[i].pdu_session_id = session->param.pdusession_id;
// Handover Request Acknowledge Transfer
ho_request_ack_transfer_t *transfer = &msg->pdusessions[i].ack_transfer;
transfer->gtp_teid = session->param.n3_outgoing.teid;
memcpy(transfer->gNB_addr.buffer, session->param.n3_outgoing.addr.buffer, session->param.n3_outgoing.addr.length);
transfer->gNB_addr.length = session->param.n3_outgoing.addr.length;
transfer->nb_of_qos_flow = session->param.nb_qos;
for (int q = 0; q < transfer->nb_of_qos_flow; q++) {
transfer->qos_setup_list[q].qfi = session->param.qos[q].qfi;
transfer->qos_setup_list[q].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
}
}
// Target to Source Transparent Container
msg->target2source = copy_byte_array(ho_command);
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
@@ -99,4 +99,6 @@ void rrc_gNB_send_NGAP_HANDOVER_FAILURE(gNB_RRC_INST *rrc, ngap_handover_failure
int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, ngap_handover_request_t *msg);
void rrc_gNB_free_Handover_Request(ngap_handover_request_t *msg);
void rrc_gNB_send_NGAP_HANDOVER_REQUEST_ACKNOWLEDGE(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, byte_array_t ho_command);
#endif