Implementation E1 Setup Failure (8.2.3.3 of 3GPP TS 38.463)
- CU-CP replying to the CU-UP with a Setup Failure message in case of unsuccessfull E1 Setup Request - message is decoded by the CU-UP, and stops the process
This commit is contained in:
committed by
Robert Schmidt
parent
47c069347d
commit
7faabc6b45
+9
-4
@@ -17,17 +17,22 @@ connection setup only in split-mode, the rest is the same for CU):
|
|||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
participant c as CUCP
|
participant c as CUCP
|
||||||
participant u as CUUP
|
participant u as CUUP
|
||||||
u->c: SCTP connection setup (in split mode)
|
|
||||||
u->>c: E1AP Setup Request
|
|
||||||
Note over c: Execute rrc_gNB_process_e1_setup_req()
|
|
||||||
c->>u: E1AP Setup Response
|
|
||||||
|
|
||||||
|
Note over c,u: E1 Setup Procedure
|
||||||
|
u->c: SCTP connection setup (in split mode)
|
||||||
|
u->>c: E1 Setup Request
|
||||||
|
Note over c: Execute rrc_gNB_process_e1_setup_req()
|
||||||
|
c->>u: E1 Setup Response
|
||||||
|
c-->>u: E1 Setup Failure
|
||||||
|
|
||||||
|
Note over c,u: E1 Bearer Context Setup Procedure
|
||||||
Note over c: Receives PDU session setup request from AMF
|
Note over c: Receives PDU session setup request from AMF
|
||||||
c->>u: Bearer Context Setup Request
|
c->>u: Bearer Context Setup Request
|
||||||
Note over u: Execute e1_bearer_context_setup()<br/>Configure DRBs and create GTP Tunnels for F1-U and N3
|
Note over u: Execute e1_bearer_context_setup()<br/>Configure DRBs and create GTP Tunnels for F1-U and N3
|
||||||
u->>c: Bearer Context Setup Response
|
u->>c: Bearer Context Setup Response
|
||||||
Note over c: Execute rrc_gNB_process_e1_setup_req()<br/>Sends F1-U UL TNL info to DU and receives DL TNL info
|
Note over c: Execute rrc_gNB_process_e1_setup_req()<br/>Sends F1-U UL TNL info to DU and receives DL TNL info
|
||||||
|
|
||||||
|
Note over c,u: E1 Bearer Context Modification (CU-CP Initiated) Procedure
|
||||||
c->>u: Bearer Context Modification Request
|
c->>u: Bearer Context Modification Request
|
||||||
Note over u: Execute e1_bearer_context_modif()<br/>Updates GTP Tunnels with received info
|
Note over u: Execute e1_bearer_context_modif()<br/>Updates GTP Tunnels with received info
|
||||||
u->>c: Bearer Context Modification Response
|
u->>c: Bearer Context Modification Response
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_set
|
|||||||
|
|
||||||
/* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */
|
/* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */
|
||||||
MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp)
|
MESSAGE_DEF(E1AP_SETUP_RESP , MESSAGE_PRIORITY_MED, e1ap_setup_resp_t , e1ap_setup_resp)
|
||||||
|
/* E1AP Setup Failure: gNB-CU-CP -> gNB-CU-UP */
|
||||||
|
MESSAGE_DEF(E1AP_SETUP_FAIL, MESSAGE_PRIORITY_MED, e1ap_setup_fail_t, e1ap_setup_fail)
|
||||||
|
|
||||||
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req)
|
MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_setup_req)
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#define E1AP_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_register_req
|
#define E1AP_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_register_req
|
||||||
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
|
#define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req
|
||||||
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
|
#define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp
|
||||||
|
#define E1AP_SETUP_FAIL(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_fail
|
||||||
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
|
#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
|
||||||
#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
|
#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
|
||||||
#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
|
#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
|
||||||
@@ -94,6 +95,11 @@ typedef struct e1ap_setup_resp_s {
|
|||||||
long transac_id;
|
long transac_id;
|
||||||
} e1ap_setup_resp_t;
|
} e1ap_setup_resp_t;
|
||||||
|
|
||||||
|
/* E1AP Setup Failure */
|
||||||
|
typedef struct e1ap_setup_fail_s {
|
||||||
|
long transac_id;
|
||||||
|
} e1ap_setup_fail_t;
|
||||||
|
|
||||||
typedef struct cell_group_s {
|
typedef struct cell_group_s {
|
||||||
long id;
|
long id;
|
||||||
} cell_group_t;
|
} cell_group_t;
|
||||||
|
|||||||
+34
-2
@@ -257,25 +257,36 @@ void e1ap_send_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_setup_resp_t *e1
|
|||||||
e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
|
e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief E1 Setup Failure ASN1 messager builder
|
||||||
|
* @ref 9.2.1.6 GNB-CU-UP E1 SETUP FAILURE of 3GPP TS 38.463
|
||||||
|
*/
|
||||||
static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu)
|
static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu)
|
||||||
{
|
{
|
||||||
/* Create */
|
/* Create */
|
||||||
/* 0. pdu Type */
|
/* 0. pdu Type */
|
||||||
pdu->present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome;
|
pdu->present = E1AP_E1AP_PDU_PR_unsuccessfulOutcome;
|
||||||
asn1cCalloc(pdu->choice.unsuccessfulOutcome, initMsg);
|
asn1cCalloc(pdu->choice.unsuccessfulOutcome, initMsg);
|
||||||
|
/* mandatory */
|
||||||
|
/**
|
||||||
|
* Message Type IE
|
||||||
|
* - procedureCode (integer)
|
||||||
|
* - Type of Message (choice)
|
||||||
|
* @ref clause 9.3.1.1 of 3GPP TS 38.463
|
||||||
|
*/
|
||||||
initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup;
|
initMsg->procedureCode = E1AP_ProcedureCode_id_gNB_CU_UP_E1Setup;
|
||||||
initMsg->criticality = E1AP_Criticality_reject;
|
initMsg->criticality = E1AP_Criticality_reject;
|
||||||
initMsg->value.present = E1AP_UnsuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupFailure;
|
initMsg->value.present = E1AP_UnsuccessfulOutcome__value_PR_GNB_CU_UP_E1SetupFailure;
|
||||||
E1AP_GNB_CU_UP_E1SetupFailure_t *out = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
|
E1AP_GNB_CU_UP_E1SetupFailure_t *out = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
/* c1. Transaction ID (integer value) */
|
/* c1. Transaction ID (integer value), clause 9.3.1.53 of 3GPP TS 38.463 */
|
||||||
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC1);
|
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC1);
|
||||||
ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID;
|
ieC1->id = E1AP_ProtocolIE_ID_id_TransactionID;
|
||||||
ieC1->criticality = E1AP_Criticality_reject;
|
ieC1->criticality = E1AP_Criticality_reject;
|
||||||
ieC1->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_TransactionID;
|
ieC1->value.present = E1AP_GNB_CU_UP_E1SetupFailureIEs__value_PR_TransactionID;
|
||||||
ieC1->value.choice.TransactionID = transac_id;
|
ieC1->value.choice.TransactionID = transac_id;
|
||||||
/* mandatory */
|
/* mandatory */
|
||||||
/* c2. cause (integer value) */
|
/* c2. cause (integer value), clause 9.3.1.2 of 3GPP TS 38.463 */
|
||||||
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC2);
|
asn1cSequenceAdd(out->protocolIEs.list, E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ieC2);
|
||||||
ieC2->id = E1AP_ProtocolIE_ID_id_Cause;
|
ieC2->id = E1AP_ProtocolIE_ID_id_Cause;
|
||||||
ieC2->criticality = E1AP_Criticality_ignore;
|
ieC2->criticality = E1AP_Criticality_ignore;
|
||||||
@@ -284,8 +295,12 @@ static void fill_SETUP_FAILURE(long transac_id, E1AP_E1AP_PDU_t *pdu)
|
|||||||
ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified;
|
ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief E1 Setup Failure ASN1 messager encoder
|
||||||
|
*/
|
||||||
void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id)
|
void e1apCUCP_send_SETUP_FAILURE(sctp_assoc_t assoc_id, long transac_id)
|
||||||
{
|
{
|
||||||
|
LOG_D(E1AP, "CU-CP: Encoding E1AP Setup Failure for transac_id %ld...\n", transac_id);
|
||||||
E1AP_E1AP_PDU_t pdu = {0};
|
E1AP_E1AP_PDU_t pdu = {0};
|
||||||
fill_SETUP_FAILURE(transac_id, &pdu);
|
fill_SETUP_FAILURE(transac_id, &pdu);
|
||||||
e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
|
e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
|
||||||
@@ -404,18 +419,31 @@ int e1apCUUP_handle_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief E1 Setup Failure ASN1 messager decoder on CU-UP
|
||||||
|
*/
|
||||||
int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
|
int e1apCUUP_handle_SETUP_FAILURE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
|
||||||
{
|
{
|
||||||
|
LOG_D(E1AP, "CU-UP: Decoding E1AP Setup Failure...\n");
|
||||||
E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie;
|
E1AP_GNB_CU_UP_E1SetupFailureIEs_t *ie;
|
||||||
DevAssert(pdu != NULL);
|
DevAssert(pdu != NULL);
|
||||||
E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
|
E1AP_GNB_CU_UP_E1SetupFailure_t *in = &pdu->choice.unsuccessfulOutcome->value.choice.GNB_CU_UP_E1SetupFailure;
|
||||||
/* Transaction ID */
|
/* Transaction ID */
|
||||||
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in,
|
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in,
|
||||||
E1AP_ProtocolIE_ID_id_TransactionID, true);
|
E1AP_ProtocolIE_ID_id_TransactionID, true);
|
||||||
|
long transaction_id;
|
||||||
|
long old_transaction_id = inst->cuup.setupReq.transac_id;
|
||||||
|
transaction_id = ie->value.choice.TransactionID;
|
||||||
|
if (old_transaction_id != transaction_id)
|
||||||
|
LOG_E(E1AP, "Transaction IDs do not match %ld != %ld\n", old_transaction_id, transaction_id);
|
||||||
|
E1AP_free_transaction_identifier(transaction_id);
|
||||||
|
|
||||||
/* Cause */
|
/* Cause */
|
||||||
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in,
|
F1AP_FIND_PROTOCOLIE_BY_ID(E1AP_GNB_CU_UP_E1SetupFailureIEs_t, ie, in,
|
||||||
E1AP_ProtocolIE_ID_id_Cause, true);
|
E1AP_ProtocolIE_ID_id_Cause, true);
|
||||||
|
|
||||||
|
LOG_E(E1AP, "received E1 Setup Failure, please check the CU-CP output and the CU-UP parameters\n");
|
||||||
|
exit(1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1875,6 +1903,10 @@ void *E1AP_CUCP_task(void *arg) {
|
|||||||
e1ap_send_SETUP_RESPONSE(assoc_id, &E1AP_SETUP_RESP(msg));
|
e1ap_send_SETUP_RESPONSE(assoc_id, &E1AP_SETUP_RESP(msg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case E1AP_SETUP_FAIL:
|
||||||
|
e1apCUCP_send_SETUP_FAILURE(assoc_id, E1AP_SETUP_FAIL(msg).transac_id);
|
||||||
|
break;
|
||||||
|
|
||||||
case E1AP_BEARER_CONTEXT_SETUP_REQ:
|
case E1AP_BEARER_CONTEXT_SETUP_REQ:
|
||||||
e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
|
e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -122,6 +122,19 @@ sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue
|
|||||||
return ue_data.e1_assoc_id;
|
return ue_data.e1_assoc_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void e1ap_setup_failure(sctp_assoc_t assoc_id, uint64_t transac_id)
|
||||||
|
{
|
||||||
|
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, E1AP_SETUP_FAIL);
|
||||||
|
msg_p->ittiMsgHeader.originInstance = assoc_id;
|
||||||
|
e1ap_setup_fail_t *setup_fail = &E1AP_SETUP_FAIL(msg_p);
|
||||||
|
setup_fail->transac_id = transac_id;
|
||||||
|
LOG_I(NR_RRC, "Triggering E1AP Setup Failure for transac_id %ld (%ld), assoc_id %ld\n",
|
||||||
|
transac_id,
|
||||||
|
E1AP_SETUP_FAIL(msg_p).transac_id,
|
||||||
|
msg_p->ittiMsgHeader.originInstance);
|
||||||
|
itti_send_msg_to_task(TASK_CUCP_E1, 0 /*unused by callee*/, msg_p);
|
||||||
|
}
|
||||||
|
|
||||||
int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
|
int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
|
||||||
{
|
{
|
||||||
AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n");
|
AssertFatal(req->supported_plmns <= PLMN_LIST_MAX_SIZE, "Supported PLMNs is more than PLMN_LIST_MAX_SIZE\n");
|
||||||
@@ -138,6 +151,7 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
|
|||||||
c->setup_req->gNB_cu_up_id,
|
c->setup_req->gNB_cu_up_id,
|
||||||
c->setup_req->gNB_cu_up_name,
|
c->setup_req->gNB_cu_up_name,
|
||||||
c->assoc_id);
|
c->assoc_id);
|
||||||
|
e1ap_setup_failure(assoc_id, req->transac_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,11 +165,12 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req)
|
|||||||
id->mnc,
|
id->mnc,
|
||||||
rrc->configuration.mcc[i],
|
rrc->configuration.mcc[i],
|
||||||
rrc->configuration.mnc[i]);
|
rrc->configuration.mnc[i]);
|
||||||
|
e1ap_setup_failure(assoc_id, req->transac_id);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(RRC, "Accepting new CU-UP ID %ld name %s (assoc_id %d)\n", req->gNB_cu_up_id, req->gNB_cu_up_name, assoc_id);
|
LOG_I(NR_RRC, "Accepting new CU-UP ID %ld name %s (assoc_id %d)\n", req->gNB_cu_up_id, req->gNB_cu_up_name, assoc_id);
|
||||||
nr_rrc_cuup_container_t *cuup = malloc(sizeof(*cuup));
|
nr_rrc_cuup_container_t *cuup = malloc(sizeof(*cuup));
|
||||||
AssertFatal(cuup, "out of memory\n");
|
AssertFatal(cuup, "out of memory\n");
|
||||||
cuup->setup_req = malloc(sizeof(*cuup->setup_req));
|
cuup->setup_req = malloc(sizeof(*cuup->setup_req));
|
||||||
|
|||||||
Reference in New Issue
Block a user