From a2f41597c7438934a203ccf3cced35b6b65e8cee Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani <velumani@eurecom.fr> Date: Sat, 4 Jun 2022 13:50:55 +0530 Subject: [PATCH] Fixed bugs in E1 setup procedure E1 setup request decoding successful --- ci-scripts/conf_files/gNB_SA_CU.conf | 8 ++-- common/utils/LOG/log.c | 1 + openair2/E1AP/e1ap.c | 57 +++++++++++++++++++++++----- openair2/E1AP/e1ap_common.c | 33 ++++++++++------ openair2/E1AP/e1ap_common.h | 4 +- openair2/GNB_APP/gnb_config.c | 13 +++++-- 6 files changed, 87 insertions(+), 29 deletions(-) diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index 14bf78a43a1..253f4f180b8 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -182,13 +182,13 @@ gNBs = } ); - E1_INTERFACE: + E1_INTERFACE = ( { - type = "cu"; - ipv4_cucp = "192.168.100.1"; + type = "up"; + ipv4_cucp = "127.0.0.100"; port_cucp = 25; - ipv4_cuup = "192.168.100.2"; + ipv4_cuup = "127.0.0.101"; port_cuup = 25; } ) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 043631d706a..b08838a9a79 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -485,6 +485,7 @@ int logInit (void) register_log_component("SDAP","",SDAP); register_log_component("S1AP","",S1AP); register_log_component("F1AP","",F1AP); + register_log_component("E1AP","",E1AP); register_log_component("M2AP","",M2AP); register_log_component("M3AP","",M3AP); register_log_component("SCTP","",SCTP); diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 9cc8173eaaa..8b6665fbfe4 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -92,7 +92,7 @@ int e1ap_handle_message(instance_t instance, uint32_t assoc_id, return ret; } -void cuup_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { +void cuxp_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) { int result; DevAssert(sctp_data_ind != NULL); e1ap_handle_message(instance, sctp_data_ind->assoc_id, @@ -205,7 +205,7 @@ int e1apCUUP_send_SETUP_REQUEST(instance_t instance) { MCC_MNC_TO_PLMNID(setup->plmns[i].mcc, setup->plmns[i].mnc, setup->plmns[i].mnc_digit_length, &supportedPLMN->pLMN_Identity); } - e1ap_encode_send(0, instance, &pdu, 0, __func__); + e1ap_encode_send(UPtype, instance, &pdu, 0, __func__); return 0; } @@ -228,7 +228,7 @@ int e1apCUCP_send_SETUP_RESPONSE(instance_t instance, ieC1->value.present = E1AP_GNB_CU_UP_E1SetupResponseIEs__value_PR_TransactionID; ieC1->value.choice.TransactionID = e1ap_setup_resp->transac_id; - e1ap_encode_send(0, instance, &pdu, 0, __func__); + e1ap_encode_send(CPtype, instance, &pdu, 0, __func__); return 0; } @@ -259,7 +259,7 @@ int e1apCUCP_send_SETUP_FAILURE(instance_t instance, ieC2->value.choice.Cause.present = E1AP_Cause_PR_radioNetwork; //choose this accordingly ieC2->value.choice.Cause.choice.radioNetwork = E1AP_CauseRadioNetwork_unspecified; - e1ap_encode_send(0, instance, &pdu, 0, __func__); + e1ap_encode_send(CPtype, instance, &pdu, 0, __func__); return 0; } @@ -408,7 +408,7 @@ int e1apCUUP_send_CONFIGURATION_UPDATE(instance_t instance) { TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &TNLAtoRemove->tNLAssociationTransportLayerAddress.choice.endpoint_IP_Address); // TODO: correct me } - e1ap_encode_send(0, instance, &pdu, 0, __func__); + e1ap_encode_send(UPtype, instance, &pdu, 0, __func__); return 0; } @@ -632,7 +632,7 @@ int e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(instance_t instance, } } - e1ap_encode_send(0, instance, &pdu, 0, __func__); + e1ap_encode_send(CPtype, instance, &pdu, 0, __func__); return 0; } @@ -757,7 +757,7 @@ int e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance, } } } - e1ap_encode_send(0, instance, &pdu, 0, __func__); + e1ap_encode_send(UPtype, instance, &pdu, 0, __func__); return 0; } @@ -1116,6 +1116,27 @@ void cucp_task_send_sctp_init_req(instance_t instance, char *my_addr) { itti_send_msg_to_task(TASK_SCTP, instance, message_p); } +void cucp_task_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) { + createE1inst(CPtype, instance, NULL); + e1ap_setup_req_t *setup_req = &getCxtE1(CPtype, instance)->setupReq; + setup_req->assoc_id = sctp_new_association_ind->assoc_id; + setup_req->sctp_in_streams = sctp_new_association_ind->in_streams; + setup_req->sctp_out_streams = sctp_new_association_ind->out_streams; + setup_req->default_sctp_stream_id = 0; +} + +void cucp_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { + DevAssert(sctp_new_association_resp != NULL); + + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { + LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", + sctp_new_association_resp->sctp_state, + instance, + sctp_new_association_resp->ulp_cnx_id); + return; + } +} + void *E1AP_CUCP_task(void *arg) { LOG_I(E1AP, "Starting E1AP at CU CP\n"); MessageDef *msg = NULL; @@ -1123,11 +1144,24 @@ void *E1AP_CUCP_task(void *arg) { while (1) { itti_receive_msg(TASK_CUCP_E1, &msg); + instance_t myInstance=ITTI_MSG_DESTINATION_INSTANCE(msg); switch (ITTI_MSG_ID(msg)) { + case SCTP_NEW_ASSOCIATION_IND: + LOG_I(E1AP, "CUCP Task Received SCTP_NEW_ASSOCIATION_IND for instance %ld\n", myInstance); + cucp_task_handle_sctp_association_ind(ITTI_MSG_ORIGIN_INSTANCE(msg), + &msg->ittiMsg.sctp_new_association_ind); + break; + + case SCTP_NEW_ASSOCIATION_RESP: + LOG_I(E1AP, "CUCP Task Received SCTP_NEW_ASSOCIATION_RESP for instance %ld\n", myInstance); + cucp_task_handle_sctp_association_resp(ITTI_MSG_ORIGIN_INSTANCE(msg), + &msg->ittiMsg.sctp_new_association_resp); + break; + case E1AP_SETUP_REQ: LOG_I(E1AP, "CUCP Task Received E1AP_SETUP_REQ for instance %ld. Initializing SCTP listener\n", - ITTI_MSG_DESTINATION_INSTANCE(msg)); + myInstance); e1ap_setup_req_t *req = &E1AP_SETUP_REQ(msg); char *ipaddr; if (req->CUCP_e1_ip_address.ipv4 == 0) { @@ -1139,6 +1173,11 @@ void *E1AP_CUCP_task(void *arg) { cucp_task_send_sctp_init_req(0, ipaddr); break; + case SCTP_DATA_IND: + LOG_I(E1AP, "CUCP Task Received SCTP_DATA_IND\n"); + cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); + break; + default: LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n"); break; @@ -1172,7 +1211,7 @@ void *E1AP_CUUP_task(void *arg) { case SCTP_DATA_IND: LOG_I(E1AP, "CUUP Task Received SCTP_DATA_IND\n"); - cuup_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); + cuxp_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); break; default: diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 8b7d20dc3be..bc5ae0789d6 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -34,18 +34,29 @@ e1ap_upcp_inst_t *getCxtE1(E1_t type, instance_t instance) { return type ? e1ap_up_inst[instance] : e1ap_cp_inst[instance]; } -int e1ap_assoc_id(bool isCu, instance_t instance) { - return 0; +int e1ap_assoc_id(E1_t type, instance_t instance) { + if (type == CPtype) { + AssertFatal(e1ap_cp_inst[instance] != NULL, "Trying to access uninitiated instance of CUCP\n"); + return e1ap_cp_inst[instance]->setupReq.assoc_id; + } else if (type == UPtype) { + AssertFatal(e1ap_up_inst[instance] != NULL, "Trying to access uninitiated instance of CUUP\n"); + return e1ap_up_inst[instance]->setupReq.assoc_id; + } else { + AssertFatal(false, "Unknown CU type\n"); + } + return -1; } void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) { if (type == CPtype) { AssertFatal(e1ap_cp_inst[instance] == NULL, "Double call to E1 CP instance %d\n", (int)instance); e1ap_cp_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t)); - } else { + } else if (type == UPtype) { AssertFatal(e1ap_up_inst[instance] == NULL, "Double call to E1 UP instance %d\n", (int)instance); e1ap_up_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t)); memcpy(&e1ap_up_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t)); + } else { + AssertFatal(false, "Unknown CU type\n"); } } @@ -76,7 +87,7 @@ E1AP_TransactionID_t E1AP_get_next_transaction_identifier() { int freeIdx; while (!isTransacIdValid) { - genTransacId = rand(); + genTransacId = rand() & 255; isTransacIdValid = check_transac_id(genTransacId, &freeIdx); } @@ -143,7 +154,7 @@ int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t asn_dec_rval_t dec_ret; DevAssert(buffer != NULL); dec_ret = aper_decode(NULL, - &asn_DEF_F1AP_F1AP_PDU, + &asn_DEF_E1AP_E1AP_PDU, (void **)&pdu, buffer, length, @@ -151,9 +162,9 @@ int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t 0); if (asn1_xer_print_e1ap) { - LOG_E(F1AP, "----------------- ASN1 DECODER PRINT START----------------- \n"); + LOG_E(E1AP, "----------------- ASN1 DECODER PRINT START----------------- \n"); xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, pdu); - LOG_E(F1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n"); + LOG_E(E1AP, "----------------- ASN1 DECODER PRINT END ----------------- \n"); } if (dec_ret.code != RC_OK) { @@ -179,7 +190,7 @@ int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t return -1; } -int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) { +int e1ap_encode_send(E1_t type, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func) { DevAssert(pdu != NULL); if (asn1_xer_print_e1ap) { @@ -197,15 +208,15 @@ int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint1 } void *buffer = NULL; - ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, buffer); + ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, &buffer); if (encoded < 0) { LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func); return -1; } else { - MessageDef *message = itti_alloc_new_message(isCu?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ); + MessageDef *message = itti_alloc_new_message((type==CPtype)?TASK_CUCP_E1:TASK_CUUP_E1, 0, SCTP_DATA_REQ); sctp_data_req_t *s = &message->ittiMsg.sctp_data_req; - s->assoc_id = e1ap_assoc_id(isCu,instance); + s->assoc_id = e1ap_assoc_id(type, instance); s->buffer = buffer; s->buffer_length = encoded; s->stream = stream; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index c283bb6a1b2..72c4accaecb 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -36,9 +36,9 @@ void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); bool check_transac_id(E1AP_TransactionID_t id, int *freeIdx); -int e1ap_assoc_id(bool isCu, instance_t instance); +int e1ap_assoc_id(E1_t type, instance_t instance); -int e1ap_encode_send(bool isCu, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); +int e1ap_encode_send(E1_t type, instance_t instance, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); void e1ap_common_init(); #endif /* E1AP_COMMON_H_ */ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 52316f8cc44..4d5b2ad6566 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1835,6 +1835,8 @@ int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) { paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0}; config_get(GNBSParams, sizeof(GNBSParams)/sizeof(paramdef_t), NULL); + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; AssertFatal (i < num_gnbs, "Failed to parse config file no %uth element in %s \n",i, GNB_CONFIG_STRING_ACTIVE_GNBS); @@ -1843,8 +1845,9 @@ int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) { config_getlist(&GNBParamList, GNBParams, sizeof(GNBParams)/sizeof(paramdef_t), NULL); AssertFatal(GNBParamList.paramarray[i][GNB_GNB_ID_IDX].uptr != NULL, "gNB id %u is not defined in configuration file\n",i); - config_getlist(&GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), NULL); + config_getlist(&GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), aprefix); e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msg_p); + msg_p->ittiMsgHeader.destinationInstance = 0; e1Setup->gNB_cu_up_id = *(GNBParamList.paramarray[0][GNB_GNB_ID_IDX].uptr); paramdef_t PLMNParams[] = GNBPLMNPARAMS_DESC; @@ -1855,7 +1858,7 @@ int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), NULL); + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); int numPLMNs = PLMNParamList.numelt; e1Setup->supported_plmns = numPLMNs; @@ -1866,8 +1869,10 @@ int RCconfig_NR_CU_E1(MessageDef *msg_p, uint32_t i) { } strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr)); + e1Setup->CUCP_e1_ip_address.ipv4 = 1; e1Setup->port_cucp = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_PORT_CUCP].uptr; strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr)); + e1Setup->CUUP_e1_ip_address.ipv4 = 1; e1Setup->port_cuup = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_PORT_CUUP].uptr; e1Setup->cn_support = *GNBE1ParamList.paramarray[0][GNB_CONFIG_E1_CN_SUPPORT].uptr; @@ -2314,7 +2319,9 @@ static ngran_node_t get_node_type(void) config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); - config_getlist( &GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), NULL); + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); + config_getlist( &GNBE1ParamList, GNBE1Params, sizeof(GNBE1Params)/sizeof(paramdef_t), aprefix); if ( MacRLC_ParamList.numelt > 0) { RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; -- GitLab