Split out E1AP net config from Setup Request
The E1AP Setup Request contained the network configuration (IP address, ports) as well as the actual E1AP Setup Request application data (Supported PLMNs, ...). This has the drawbacks that - The E1AP Setup Request is stored to retrieve IP addresses in the E1AP module, which is confusing as the Setup Request, per standard, has no IP info - The CU-CP received an E1 Setup Request for configuration during start up, but it did not actually receive such Setup Request, but merely the IP configuration to set up the socket This commit splits the E1AP Setup Request into a "real" Setup Request for application data, and creates a new type e1ap_net_config_t to group all IP configuration data. Further, a new ITTI message type E1AP_REGISTER_REQ is introduced to group both types. What happens is - RCconfig_NR_CU_E1() reads both E1AP application-level data and IP configuration, as previously - The data is sent to the CU-CP. It discards the E1AP Setup Request data, and only uses the network configuration to set up the socket - The data is sent to the CU-UP. It uses the network configuration to connect to the CU-CP, and then sends the E1AP Setup Request to the CU-CP. Currently, the CU-CP still stores the Setup Request locally, which will be changed in the next commit to send it to the RRC.
This commit is contained in:
@@ -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 !!!*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
+29
-26
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+13
-11
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user