diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 08e5c1c7f6..a1a97373e8 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -403,7 +403,7 @@ static int create_gNB_tasks(ngran_node_t node_type) if (node_type == ngran_gNB_CU || node_type == ngran_gNB) { MessageDef *msg = RCconfig_NR_CU_E1(false); instance_t inst = 0; - createE1inst(UPtype, inst, &E1AP_SETUP_REQ(msg)); + createE1inst(UPtype, inst, &E1AP_REGISTER_REQ(msg).net_config, NULL); cuup_init_n3(inst); itti_free(TASK_UNKNOWN, msg); RC.nrrrc[gnb_id_start]->e1_inst = inst; // stupid instance !!!*/ diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index 70533f8add..fdfa071a7f 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -20,6 +20,9 @@ */ /* gNB_CUUP application layer -> E1AP messages */ +MESSAGE_DEF(E1AP_REGISTER_REQ, MESSAGE_PRIORITY_MED, e1ap_register_req_t, e1ap_register_req) + +/* E1AP messages -> RRC (CU-CP) */ MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req) /* E1AP -> eNB_DU or eNB_CU_RRC -> E1AP application layer messages */ diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 0a9cb302d2..0fe07ea910 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -40,6 +40,7 @@ #define E1AP_MAX_NUM_DRBS 4 #define E1AP_MAX_NUM_UP_PARAM 4 +#define E1AP_REGISTER_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_register_req #define E1AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_req #define E1AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_setup_resp #define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_setup_req @@ -54,13 +55,7 @@ typedef struct PLMN_ID_s { int mnc_digit_length; } PLMN_ID_t; -typedef struct e1ap_setup_req_s { - uint64_t gNB_cu_up_id; - char * gNB_cu_up_name; - uint64_t transac_id; - int supported_plmns; - PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; - +typedef struct e1ap_net_config_t { net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; uint16_t remotePortF1U; @@ -69,8 +64,21 @@ typedef struct e1ap_setup_req_s { char* localAddressN3; uint16_t localPortN3; uint16_t remotePortN3; +} e1ap_net_config_t; + +typedef struct e1ap_setup_req_s { + uint64_t gNB_cu_up_id; + char * gNB_cu_up_name; + uint64_t transac_id; + int supported_plmns; + PLMN_ID_t plmns[E1AP_MAX_NUM_PLMNS]; } e1ap_setup_req_t; +typedef struct e1ap_register_req_t { + e1ap_setup_req_t setup_req; + e1ap_net_config_t net_config; +} e1ap_register_req_t; + typedef struct e1ap_setup_resp_s { long transac_id; } e1ap_setup_resp_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 08901b0e04..73b804cddf 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1499,9 +1499,9 @@ static instance_t cuup_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) { return gtpv1Init(tmp); } -static void e1_task_send_sctp_association_req(long task_id, instance_t instance, e1ap_setup_req_t *e1ap_setup_req) +static void e1_task_send_sctp_association_req(long task_id, instance_t instance, e1ap_net_config_t *e1ap_nc) { - DevAssert(e1ap_setup_req != NULL); + DevAssert(e1ap_nc != NULL); getCxtE1(instance)->sockState = SCTP_STATE_CLOSED; MessageDef *message_p = itti_alloc_new_message(task_id, 0, SCTP_NEW_ASSOCIATION_REQ); sctp_new_association_req_t *sctp_new_req = &message_p->ittiMsg.sctp_new_association_req; @@ -1509,9 +1509,9 @@ static void e1_task_send_sctp_association_req(long task_id, instance_t instance, sctp_new_req->port = E1AP_PORT_NUMBER; sctp_new_req->ppid = E1AP_SCTP_PPID; // remote - sctp_new_req->remote_address = e1ap_setup_req->CUCP_e1_ip_address; + sctp_new_req->remote_address = e1ap_nc->CUCP_e1_ip_address; // local - sctp_new_req->local_address = e1ap_setup_req->CUUP_e1_ip_address; + sctp_new_req->local_address = e1ap_nc->CUUP_e1_ip_address; itti_send_msg_to_task(TASK_SCTP, instance, message_p); } @@ -1540,10 +1540,10 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, e1ap_upcp_inst_t *inst = getCxtE1(instance); inst->assoc_id = sctp_new_association_resp->assoc_id; - e1ap_setup_req_t *e1ap_cuup_setup_req = &inst->setupReq; + e1ap_net_config_t *nc = &inst->net_config; eth_params_t IPaddr; - IPaddr.my_addr = e1ap_cuup_setup_req->localAddressF1U; - IPaddr.my_portd = e1ap_cuup_setup_req->localPortF1U; + IPaddr.my_addr = nc->localAddressF1U; + IPaddr.my_portd = nc->localPortF1U; if (getCxtE1(instance)->gtpInstF1U < 0) getCxtE1(instance)->gtpInstF1U = cuup_task_create_gtpu_instance_to_du(&IPaddr); if (getCxtE1(instance)->gtpInstF1U < 0) @@ -1551,18 +1551,18 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, extern instance_t CUuniqInstance; CUuniqInstance = getCxtE1(instance)->gtpInstF1U; cuup_init_n3(instance); - e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, e1ap_cuup_setup_req); + e1apCUUP_send_SETUP_REQUEST(inst->assoc_id, &inst->setupReq); } } void cuup_init_n3(instance_t instance) { if (getCxtE1(instance)->gtpInstN3 < 0) { - e1ap_setup_req_t *setup = &getCxtE1(instance)->setupReq; + e1ap_net_config_t *nc = &getCxtE1(instance)->net_config; openAddr_t tmp = {0}; - strcpy(tmp.originHost, setup->localAddressN3); - sprintf(tmp.originService, "%d", setup->localPortN3); - sprintf(tmp.destinationService, "%d", setup->remotePortN3); + strcpy(tmp.originHost, nc->localAddressN3); + sprintf(tmp.originService, "%d", nc->localPortN3); + sprintf(tmp.destinationService, "%d", nc->remotePortN3); LOG_I(GTPU, "Configuring GTPu address : %s, port : %s\n", tmp.originHost, tmp.originService); // Fixme: fully inconsistent instances management // dirty global var is a bad fix @@ -1599,7 +1599,7 @@ void e1_task_handle_sctp_association_ind(E1_t type, instance_t instance, sctp_ne if (getCxtE1(instance)) LOG_W(E1AP, "CUCP incoming call, re-use older socket context, finish implementation required\n"); else - createE1inst(type, instance, NULL); + createE1inst(type, instance, NULL, NULL); e1ap_upcp_inst_t *inst = getCxtE1(instance); inst->sockState = SCTP_STATE_ESTABLISHED; inst->assoc_id = sctp_new_ind->assoc_id; @@ -1609,7 +1609,7 @@ void e1apHandleTimer(instance_t myInstance) { LOG_W(E1AP, "Try to reconnect to CP\n"); if (getCxtE1(myInstance)->sockState != SCTP_STATE_ESTABLISHED) - e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->setupReq); + e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, &getCxtE1(myInstance)->net_config); } void *E1AP_CUCP_task(void *arg) { @@ -1635,15 +1635,19 @@ void *E1AP_CUCP_task(void *arg) { e1_task_handle_sctp_association_resp(CPtype, ITTI_MSG_ORIGIN_INSTANCE(msg), &msg->ittiMsg.sctp_new_association_resp); break; - case E1AP_SETUP_REQ: { - e1ap_setup_req_t *req = &E1AP_SETUP_REQ(msg); - if (req->CUCP_e1_ip_address.ipv4 == 0) { - LOG_E(E1AP, "No IPv4 address configured\n"); - return NULL; - } - cucp_task_send_sctp_init_req(0, req->CUCP_e1_ip_address.ipv4_address); + case E1AP_REGISTER_REQ: { + // note: we use E1AP_REGISTER_REQ only to set up sockets, the + // E1AP_SETUP_REQ is not used and comes through the socket from the + // CU-UP later! + e1ap_net_config_t *nc = &E1AP_REGISTER_REQ(msg).net_config; + AssertFatal(nc->CUCP_e1_ip_address.ipv4 != 0, "No IPv4 address configured\n"); + cucp_task_send_sctp_init_req(0, nc->CUCP_e1_ip_address.ipv4_address); } break; + case E1AP_SETUP_REQ: + AssertFatal(false, "should not receive E1AP_SETUP_REQ in CU-CP!\n"); + break; + case SCTP_DATA_IND: e1_task_handle_sctp_data_ind(myInstance, &msg->ittiMsg.sctp_data_ind); break; @@ -1685,11 +1689,10 @@ void *E1AP_CUUP_task(void *arg) { const int msgType = ITTI_MSG_ID(msg); LOG_D(E1AP, "CUUP received %s for instance %ld\n", messages_info[msgType].name, myInstance); switch (msgType) { - case E1AP_SETUP_REQ: { - e1ap_setup_req_t *msgSetup = &E1AP_SETUP_REQ(msg); - createE1inst(UPtype, myInstance, msgSetup); - - e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, msgSetup); + case E1AP_REGISTER_REQ: { + e1ap_register_req_t *reg_req = &E1AP_REGISTER_REQ(msg); + createE1inst(UPtype, myInstance, ®_req->net_config, ®_req->setup_req); + e1_task_send_sctp_association_req(TASK_CUUP_E1, myInstance, ®_req->net_config); } break; case SCTP_NEW_ASSOCIATION_RESP: diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index b6fb023780..9096a9faf7 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -149,9 +149,9 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg); in_addr_t my_addr; - if (inet_pton(AF_INET, inst->setupReq.localAddressF1U, &my_addr) != 1) - LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->setupReq.localAddressF1U); - fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->setupReq.remotePortF1U, my_addr); + if (inet_pton(AF_INET, inst->net_config.localAddressF1U, &my_addr) != 1) + LOG_E(E1AP, "can't use the F1-U local interface: %s\n", inst->net_config.localAddressF1U); + fill_e1ap_bearer_setup_resp(resp, req, inst->gtpInstF1U, req->gNB_cu_cp_ue_id, inst->net_config.remotePortF1U, my_addr); resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id; resp->gNB_cu_up_ue_id = gNB_cu_up_ue_id; @@ -161,8 +161,8 @@ void process_e1_bearer_context_setup_req(instance_t instance, e1ap_bearer_setup_ pdu_session_to_setup_t *pdu2Setup = req->pduSession + i; pduSetup->id = pdu2Setup->sessionId; - if (inet_pton(AF_INET, inst->setupReq.localAddressN3, &pduSetup->tlAddress) != 1) - LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->setupReq.localAddressN3); + if (inet_pton(AF_INET, inst->net_config.localAddressN3, &pduSetup->tlAddress) != 1) + LOG_E(E1AP, "can't use the N3 local interface: %s\n", inst->net_config.localAddressN3); pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i]; pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup; diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c index 51ff6744c2..71e93221ab 100644 --- a/openair2/E1AP/e1ap_common.c +++ b/openair2/E1AP/e1ap_common.c @@ -37,12 +37,15 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance) return e1ap_inst[instance]; } -void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) { +void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_setup_req_t *req) +{ AssertFatal(e1ap_inst[instance] == NULL, "Double call to E1 instance %d\n", (int)instance); e1ap_inst[instance] = calloc(1, sizeof(e1ap_upcp_inst_t)); e1ap_inst[instance]->type = type; e1ap_inst[instance]->instance = instance; e1ap_inst[instance]->assoc_id = -1; + if (nc) + memcpy(&e1ap_inst[instance]->net_config, nc, sizeof(*nc)); if (req) memcpy(&e1ap_inst[instance]->setupReq, req, sizeof(*req)); e1ap_inst[instance]->gtpInstN3 = -1; diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h index 82f5c8cd57..0159b92a97 100644 --- a/openair2/E1AP/e1ap_common.h +++ b/openair2/E1AP/e1ap_common.h @@ -36,6 +36,7 @@ typedef struct e1ap_upcp_inst_s { instance_t gtpInstN3; instance_t gtpInstF1U; e1ap_setup_req_t setupReq; + e1ap_net_config_t net_config; } e1ap_upcp_inst_t; extern int asn1_xer_print; @@ -46,7 +47,7 @@ e1ap_upcp_inst_t *getCxtE1(instance_t instance); E1AP_TransactionID_t E1AP_get_next_transaction_identifier(); -void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req); +void createE1inst(E1_t type, instance_t instance, e1ap_net_config_t *nc, e1ap_setup_req_t *req); int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uint16_t stream, const char *func); diff --git a/openair2/E1AP/e1ap_setup.c b/openair2/E1AP/e1ap_setup.c index 324f5b87e2..64b9ebab80 100644 --- a/openair2/E1AP/e1ap_setup.c +++ b/openair2/E1AP/e1ap_setup.c @@ -68,7 +68,7 @@ static void get_NGU_S1U_addr(char **addr, uint16_t *port) MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) { - MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_SETUP_REQ); + MessageDef *msgConfig = itti_alloc_new_message(TASK_GNB_APP, 0, E1AP_REGISTER_REQ); if (!msgConfig) return NULL; @@ -85,7 +85,7 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) config_getlist(&GNBParamList, GNBParams, sizeofArray(GNBParams), NULL); paramdef_t *gnbParms = GNBParamList.paramarray[0]; AssertFatal(gnbParms[GNB_GNB_ID_IDX].uptr != NULL, "gNB id %d is not defined in configuration file\n", 0); - e1ap_setup_req_t *e1Setup = &E1AP_SETUP_REQ(msgConfig); + e1ap_setup_req_t *e1Setup = &E1AP_REGISTER_REQ(msgConfig).setup_req; msgConfig->ittiMsgHeader.destinationInstance = 0; e1Setup->gNB_cu_up_id = *(gnbParms[GNB_GNB_ID_IDX].uptr); @@ -106,22 +106,24 @@ MessageDef *RCconfig_NR_CU_E1(bool separate_CUUP_process) e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MOBILE_NETWORK_CODE_IDX].uptr; e1Setup->plmns[I].mnc = *PLMNParamList.paramarray[I][GNB_MNC_DIGIT_LENGTH].u8ptr; } + /* TODO add NSSAIs */ - e1Setup->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr); - e1Setup->localAddressF1U = strdup(*(GNBParamList.paramarray[0][GNB_LOCAL_S_ADDRESS_IDX].strptr)); - e1Setup->localPortF1U = *(GNBParamList.paramarray[0][GNB_LOCAL_S_PORTD_IDX].uptr); - get_NGU_S1U_addr(&e1Setup->localAddressN3, &e1Setup->localPortN3); - e1Setup->remotePortN3 = e1Setup->localPortN3 ; + e1ap_net_config_t *e1ap_nc = &E1AP_REGISTER_REQ(msgConfig).net_config; + e1ap_nc->remotePortF1U = *(GNBParamList.paramarray[0][GNB_REMOTE_S_PORTD_IDX].uptr); + e1ap_nc->localAddressF1U = strdup(*(GNBParamList.paramarray[0][GNB_LOCAL_S_ADDRESS_IDX].strptr)); + e1ap_nc->localPortF1U = *(GNBParamList.paramarray[0][GNB_LOCAL_S_PORTD_IDX].uptr); + get_NGU_S1U_addr(&e1ap_nc->localAddressN3, &e1ap_nc->localPortN3); + e1ap_nc->remotePortN3 = e1ap_nc->localPortN3 ; if (separate_CUUP_process) { paramlist_def_t GNBE1ParamList = {GNB_CONFIG_STRING_E1_PARAMETERS, NULL, 0}; paramdef_t GNBE1Params[] = GNBE1PARAMS_DESC; config_getlist(&GNBE1ParamList, GNBE1Params, sizeofArray(GNBE1Params), aprefix); paramdef_t *e1Parms = GNBE1ParamList.paramarray[0]; - strcpy(e1Setup->CUCP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr)); - e1Setup->CUCP_e1_ip_address.ipv4 = 1; - strcpy(e1Setup->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr)); - e1Setup->CUUP_e1_ip_address.ipv4 = 1; + strcpy(e1ap_nc->CUCP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUCP].strptr)); + e1ap_nc->CUCP_e1_ip_address.ipv4 = 1; + strcpy(e1ap_nc->CUUP_e1_ip_address.ipv4_address, *(e1Parms[GNB_CONFIG_E1_IPV4_ADDRESS_CUUP].strptr)); + e1ap_nc->CUUP_e1_ip_address.ipv4 = 1; } } return msgConfig; diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index cd701f01f5..74a8a997bd 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -147,10 +147,10 @@ void *gNB_app_task(void *args_p) if (itti_create_task(TASK_CUCP_E1, E1AP_CUCP_task, NULL) < 0) AssertFatal(false, "Create task for E1AP CP failed\n"); MessageDef *msg = RCconfig_NR_CU_E1(true); - if (msg) - itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); - else - AssertFatal(false, "Send inti to task for E1AP CP failed\n"); + AssertFatal(msg != NULL, "Send inti to task for E1AP CP failed\n"); + // this sends the E1AP_REGISTER_REQ to CU-CP so it sets up the socket + // it does NOT use the E1AP part + itti_send_msg_to_task(TASK_CUCP_E1, 0, msg); } if (node_type == ngran_gNB_CUUP) {