Commit 7faabc6b authored by Guido Casati's avatar Guido Casati Committed by Robert Schmidt

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
parent 47c06934
...@@ -17,17 +17,22 @@ connection setup only in split-mode, the rest is the same for CU): ...@@ -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
Note over c,u: E1 Setup Procedure
u->c: SCTP connection setup (in split mode) u->c: SCTP connection setup (in split mode)
u->>c: E1AP Setup Request u->>c: E1 Setup Request
Note over c: Execute rrc_gNB_process_e1_setup_req() Note over c: Execute rrc_gNB_process_e1_setup_req()
c->>u: E1AP Setup Response 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 ...@@ -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 @@ ...@@ -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 { ...@@ -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;
......
...@@ -257,25 +257,36 @@ void e1ap_send_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_setup_resp_t *e1 ...@@ -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) ...@@ -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 ...@@ -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) { ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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));
......
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