Add NGAP Handover Failure message
This message is sent from the Target NG-RAN to the AMF. The commit introduces: * NGAP encoding function * N2 callback for the target gNB * handle the failure in RRC, inform NGAP * send NGAP message to AMF via SCTP Note: UE context in NGAP is fetched from the amf_ue_ngap_id Co-authored-by: batuhan duyuler <batuhan.duyuler@firecell.io>
This commit is contained in:
co-authored by
batuhan duyuler
parent
6e4f1b7b31
commit
92abefb815
@@ -334,6 +334,46 @@ void ngap_gNB_init(void) {
|
||||
itti_mark_task_ready(TASK_NGAP);
|
||||
}
|
||||
|
||||
static int ngap_gNB_handover_failure(instance_t instance, const ngap_handover_failure_t *msg)
|
||||
{
|
||||
ngap_gNB_ue_context_t *ue_context_p = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
uint32_t length;
|
||||
|
||||
ngap_gNB_instance_t *ngap_gNB_instance_p = ngap_gNB_get_instance(instance);
|
||||
DevAssert(msg != NULL);
|
||||
DevAssert(ngap_gNB_instance_p != NULL);
|
||||
|
||||
NGAP_NGAP_PDU_t *pdu = encode_ng_handover_failure(msg);
|
||||
if (!pdu) {
|
||||
NGAP_ERROR("Failed to encode NG Handover Failure\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ngap_gNB_encode_pdu(pdu, &buffer, &length) < 0) {
|
||||
NGAP_ERROR("Failed to encode HANDOVER FAILURE MESSAGE\n");
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ngap_gNB_amf_data_t *amf = ngap_gNB_get_AMF_from_instance(ngap_gNB_instance_p);
|
||||
if ((ue_context_p = ngap_get_ue_context_from_amf_ue_ngap_id(msg->amf_ue_ngap_id)) == NULL) {
|
||||
//The context for this gNB ue ngap id doesn't exist in the map of gNB UEs
|
||||
NGAP_WARN("Failed to find UE context associated with amf_ue_ngap_id=%ld\n", msg->amf_ue_ngap_id);
|
||||
/*In this case there is no ue context since HO REQ might be failed at preprocessing stage itself.
|
||||
* so sctp message send to AMF based on its assoc_id */
|
||||
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, amf->assoc_id, buffer, length, 0);
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_NGAP_PDU, pdu);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, amf->assoc_id, buffer, length, amf->nextstream);
|
||||
ASN_STRUCT_FREE(asn_DEF_NGAP_NGAP_PDU, &pdu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
@@ -415,6 +455,10 @@ void *ngap_gNB_process_itti_msg(void *notUsed) {
|
||||
}
|
||||
break;
|
||||
|
||||
case NGAP_HANDOVER_FAILURE:
|
||||
ngap_gNB_handover_failure(instance, &NGAP_HANDOVER_FAILURE(received_msg));
|
||||
break;
|
||||
|
||||
default:
|
||||
NGAP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
|
||||
break;
|
||||
|
||||
@@ -191,3 +191,36 @@ NGAP_NGAP_PDU_t *encode_ng_handover_required(const ngap_handover_required_t *msg
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
NGAP_NGAP_PDU_t *encode_ng_handover_failure(const ngap_handover_failure_t *msg)
|
||||
{
|
||||
NGAP_NGAP_PDU_t *pdu = malloc_or_fail(sizeof(*pdu));
|
||||
|
||||
/* Prepare the NGAP message to encode */
|
||||
pdu->present = NGAP_NGAP_PDU_PR_unsuccessfulOutcome;
|
||||
asn1cCalloc(pdu->choice.unsuccessfulOutcome, head);
|
||||
head->procedureCode = NGAP_ProcedureCode_id_HandoverResourceAllocation;
|
||||
head->criticality = NGAP_Criticality_reject;
|
||||
head->value.present = NGAP_UnsuccessfulOutcome__value_PR_HandoverFailure;
|
||||
NGAP_HandoverFailure_t *out = &head->value.choice.HandoverFailure;
|
||||
|
||||
// AMF_UE_NGAP_ID (M)
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_HandoverFailureIEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_HandoverFailureIEs__value_PR_AMF_UE_NGAP_ID;
|
||||
asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, msg->amf_ue_ngap_id);
|
||||
}
|
||||
|
||||
// Cause (M)
|
||||
{
|
||||
asn1cSequenceAdd(out->protocolIEs.list, NGAP_HandoverFailureIEs_t, ie);
|
||||
ie->id = NGAP_ProtocolIE_ID_id_Cause;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_HandoverFailureIEs__value_PR_Cause;
|
||||
encode_ngap_cause(&ie->value.choice.Cause, &msg->cause);
|
||||
}
|
||||
|
||||
return pdu;
|
||||
}
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
#include "ngap_messages_types.h"
|
||||
|
||||
NGAP_NGAP_PDU_t *encode_ng_handover_required(const ngap_handover_required_t *msg);
|
||||
NGAP_NGAP_PDU_t *encode_ng_handover_failure(const ngap_handover_failure_t *msg);
|
||||
|
||||
#endif /* NGAP_GNB_MOBILITY_MANAGEMENT_H_ */
|
||||
|
||||
@@ -76,6 +76,12 @@ struct ngap_gNB_ue_context_s *ngap_get_ue_context(uint32_t gNB_ue_ngap_id)
|
||||
return RB_FIND(ngap_ue_map, &ngap_ue_head, &temp);
|
||||
}
|
||||
|
||||
ngap_gNB_ue_context_t *ngap_get_ue_context_from_amf_ue_ngap_id(uint32_t amf_ue_ngap_id)
|
||||
{
|
||||
ngap_gNB_ue_context_t temp = {.amf_ue_ngap_id = amf_ue_ngap_id};
|
||||
return RB_FIND(ngap_ue_map, &ngap_ue_head, &temp);
|
||||
}
|
||||
|
||||
struct ngap_gNB_ue_context_s *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id)
|
||||
{
|
||||
struct ngap_gNB_ue_context_s *tmp = ngap_get_ue_context(gNB_ue_ngap_id);
|
||||
|
||||
@@ -81,6 +81,7 @@ typedef struct ngap_gNB_ue_context_s {
|
||||
void ngap_store_ue_context(const ngap_gNB_ue_context_t *ue_desc_p);
|
||||
|
||||
ngap_gNB_ue_context_t *ngap_get_ue_context(uint32_t gNB_ue_ngap_id);
|
||||
ngap_gNB_ue_context_t *ngap_get_ue_context_from_amf_ue_ngap_id(uint32_t amf_ue_ngap_id);
|
||||
ngap_gNB_ue_context_t *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id);
|
||||
|
||||
#endif /* NGAP_GNB_UE_CONTEXT_H_ */
|
||||
|
||||
Reference in New Issue
Block a user