Commit 01a87a1f authored by Xue Song's avatar Xue Song

split gNB into CU and DU

parent 28168f13
......@@ -133,7 +133,7 @@ task_list_t tasks[TASK_MAX];
LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s );
if ( s > 50 )
LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1);
LOG_I(TMR,"Queue for %s task size: %ld from %s task\n",itti_get_task_name(destination_task_id), s+1, itti_get_task_name(message->ittiMsgHeader.originTaskId));
t->message_queue.insert(t->message_queue.begin(), message);
eventfd_t sem_counter = 1;
......
......@@ -85,6 +85,9 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "x2ap_eNB.h"
#include "ngap_gNB.h"
#include "gnb_paramdef.h"
#include "f1ap_cu_task.h"
#include "f1ap_du_task.h"
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
......@@ -457,12 +460,30 @@ int create_gNB_tasks(uint32_t gnb_nb) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
}
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
}
if(gnb_nb > 0) {
if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) {
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n");
return -1;
}
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
printf("####### node is CU \n");
if (itti_create_task(TASK_CU_F1, F1AP_CU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP CU failed\n");
return -1;
}
}
} else {
printf("####### node is DU \n");
if (itti_create_task(TASK_DU_F1, F1AP_DU_task, NULL) < 0) {
LOG_E(F1AP, "Create task for F1AP DU failed\n");
return -1;
}
}
}
return 0;
......@@ -793,33 +814,38 @@ static void wait_nfapi_init(char *thread_name) {
}
void init_pdcp(void) {
//if (!NODE_IS_DU(RC.rrc[0]->node_type)) {
pdcp_layer_init();
if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) {
// pdcp_layer_init();
pdcp_layer_init_for_CU();
uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ?
(PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT;
if (IS_SOFTMODEM_NOS1) {
printf("IS_SOFTMODEM_NOS1 option enabled \n");
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ;
pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT;
}
pdcp_module_init(pdcp_initmask);
/*if (NODE_IS_CU(RC.rrc[0]->node_type)) {
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n");
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req);
} else {*/
} else {
LOG_I(PDCP, "node is gNB \n");
pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req);
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind);
//}
/*} else {
}
} else {
LOG_I(PDCP, "node is DU, rlc send pdcp_data_ind by proto_agent \n");
pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind);
}*/
}
}
int main( int argc, char **argv )
{
int ru_id, CC_id = 0;
int node_type = ngran_gNB;
start_background_system();
///static configuration for NR at the moment
......@@ -884,17 +910,33 @@ if(!IS_SOFTMODEM_NOS1)
#endif
LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);
if(IS_SOFTMODEM_NOS1)
init_pdcp();
// if(IS_SOFTMODEM_NOS1)
// init_pdcp();
if (RC.nb_nr_inst > 0) {
// don't create if node doesn't connect to RRC/S1/GTP
AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
nr_read_config_and_init();
} else {
printf("No ITTI, Initializing L1\n");
RCconfig_L1();
}
if (RC.nb_nr_inst > 0) {
if(IS_SOFTMODEM_NOS1)
init_pdcp();
// don't create if node doesn't connect to RRC/S1/GTP
AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
for (int gnb_id = 0; gnb_id < RC.nb_nr_inst; gnb_id++) {
MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, NRRRC_CONFIGURATION_REQ);
NRRRC_CONFIGURATION_REQ(msg_p) = RC.nrrrc[gnb_id]->configuration;
LOG_I(GNB_APP, "Sending configuration message to NR_RRC task\n");
itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p);
}
node_type = RC.nrrrc[0]->node_type;
}
/* Start the agent. If it is turned off in the configuration, it won't start */
/*
RCconfig_nr_flexran();
......@@ -974,6 +1016,7 @@ if(!IS_SOFTMODEM_NOS1)
wait_nfapi_init("main?");
}
if (NODE_IS_DU(node_type) || (node_type == ngran_gNB)) {
printf("wait RUs\n");
wait_RUs();
printf("ALL RUs READY!\n");
......@@ -1004,6 +1047,7 @@ if(!IS_SOFTMODEM_NOS1)
sync_var=0;
pthread_cond_broadcast(&sync_cond);
pthread_mutex_unlock(&sync_mutex);
}
printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
end_configmodule();
printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
......@@ -1041,7 +1085,10 @@ if(!IS_SOFTMODEM_NOS1)
printf("stopping MODEM threads\n");
// cleanup
stop_gNB(NB_gNB_INST);
if (NODE_IS_DU(node_type) || (node_type == ngran_gNB)) {
stop_RU(NB_RU);
}
/* release memory used by the RU/gNB threads (incomplete), after all
* threads have been stopped (they partially use the same memory) */
......
......@@ -159,30 +159,6 @@ void *gNB_app_task(void *args_p)
LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__);
RCconfig_NR_L1();
RCconfig_nr_macrlc();
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
AssertFatal (gnb_nb <= RC.nb_nr_inst,
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
gnb_nb, RC.nb_nr_inst);
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
for (gnb_id = gnb_id_start; (gnb_id < gnb_id_end) ; gnb_id++) {
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)malloc(sizeof(gNB_RRC_INST));
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, gnb_id_end);
memset((void *)RC.nrrrc[gnb_id],0,sizeof(gNB_RRC_INST));
configure_nr_rrc(gnb_id);
}
if (is_x2ap_enabled() ) { //&& !NODE_IS_DU(RC.rrc[0]->node_type)
LOG_I(X2AP, "X2AP enabled \n");
__attribute__((unused)) uint32_t x2_register_gnb_pending = gNB_app_register_x2 (gnb_id_start, gnb_id_end);
......
......@@ -76,8 +76,11 @@
#include "NR_ControlResourceSet.h"
#include "NR_EUTRA-MBSFN-SubframeConfig.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
extern uint16_t sf_ahead;
int macrlc_has_f1 = 0;
ngran_node_t node_type = ngran_gNB;
extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency,
int32_t uplink_frequency_offset, uint32_t frame_type);
......@@ -1424,6 +1427,22 @@ int du_check_plmn_identity(rrc_gNB_carrier_data_t *carrier,uint16_t mcc,uint16_t
return (1);
}
void configure_gnb_du_mac(int inst) {
gNB_RRC_INST *rrc = RC.nrrrc[inst];
// LOG_I(GNB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n", inst, &carrier->sib2->radioResourceConfigCommon);
LOG_I(GNB_APP,"Configuring gNB DU MAC/L1 %d \n", inst);
rrc_mac_config_req_gNB(rrc->module_id,
rrc->configuration.ssb_SubcarrierOffset,
rrc->configuration.pdsch_AntennaPorts,
rrc->configuration.pusch_TargetSNRx10,
rrc->configuration.pucch_TargetSNRx10,
rrc->configuration.scc,
0,
0, // rnti
(NR_CellGroupConfig_t *)NULL
);
}
void gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
int i, j, si_ind;
LOG_I(GNB_APP, "cells_to_activated %d, RRC instances %d\n",
......@@ -1448,10 +1467,87 @@ void gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp) {
}
// perform MAC/L1 common configuration
// configure_du_mac(i);
configure_gnb_du_mac(i);
} else {
LOG_E(GNB_APP, "F1 Setup Response not matching\n");
}
}
}
}
void set_node_type(void) {
int j;
// ngran_node_t node_type;
paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
paramdef_t GNBParams[] = GNBPARAMS_DESC;
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);
config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL);
if ( MacRLC_ParamList.numelt > 0) {
RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt;
for (j=0;j<RC.nb_nr_macrlc_inst;j++) {
if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) {
macrlc_has_f1 = 1;
}
}
}
if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) {
node_type = ngran_gNB_CU;
} else {
if (macrlc_has_f1 == 0) {
node_type = ngran_gNB;
LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n");
} else {
node_type = ngran_gNB_DU;
LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n");
}
}
}
void nr_read_config_and_init(void) {
MessageDef *msg_p = NULL;
uint32_t gnb_id;
uint32_t gnb_nb = RC.nb_nr_inst;
RCconfig_NR_L1();
set_node_type();
RCconfig_nr_macrlc();
LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst);
if (RC.nb_nr_L1_inst>0) AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n");
AssertFatal (gnb_nb <= RC.nb_nr_inst,
"Number of gNB is greater than gNB defined in configuration file (%d/%d)!",
gnb_nb, RC.nb_nr_inst);
LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst);
RC.nrrrc = (gNB_RRC_INST **)malloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *));
LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc);
for (gnb_id = 0; gnb_id < RC.nb_nr_inst ; gnb_id++) {
RC.nrrrc[gnb_id] = (gNB_RRC_INST*)malloc(sizeof(gNB_RRC_INST));
LOG_I(PHY, "%s() Creating RRC instance RC.nrrrc[%d]:%p (%d of %d)\n", __FUNCTION__, gnb_id, RC.nrrrc[gnb_id], gnb_id+1, RC.nb_nr_inst);
memset((void *)RC.nrrrc[gnb_id],0,sizeof(gNB_RRC_INST));
msg_p = itti_alloc_new_message (TASK_GNB_APP, NRRRC_CONFIGURATION_REQ);
RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]);
}
if (NODE_IS_DU(RC.nrrrc[0]->node_type)) {
RC.nrrrc[0]->carrier.servingcellconfigcommon = RC.nrrrc[0]->configuration.scc;
RC.nrrrc[0]->carrier.MIB = (uint8_t *) malloc16(4);
RC.nrrrc[0]->carrier.sizeof_MIB = do_MIB_NR(RC.nrrrc[0], 0);
RC.nrrrc[0]->carrier.sizeof_SIB1 = do_SIB1_NR(&RC.nrrrc[0]->carrier, &RC.nrrrc[0]->configuration);
}
if (NODE_IS_CU(RC.nrrrc[0]->node_type)) {
pdcp_layer_init();
nr_DRB_preconfiguration(0x1234);
rrc_init_nr_global_param();
}
}
......@@ -108,6 +108,7 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i);
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i);
int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i);
void gNB_app_handle_f1ap_setup_resp(f1ap_setup_resp_t *resp);
void nr_read_config_and_init(void);
#endif /* GNB_CONFIG_H_ */
/** @} */
......@@ -357,7 +357,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
void nr_rlc_tick(int frame, int subframe);
nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
// nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
}
const uint64_t dlsch_in_slot_bitmap = (1 << 1) | (1 << 2);
......
......@@ -44,6 +44,9 @@ static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
/* necessary globals for OAI, not used internally */
hash_table_t *pdcp_coll_p;
static uint64_t pdcp_optmask;
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
extern ngran_node_t node_type;
/****************************************************************************/
/* rlc_data_req queue - begin */
......@@ -397,9 +400,26 @@ void pdcp_layer_init(void)
if (pthread_mutex_unlock(&m) != 0) abort();
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
init_nr_rlc_data_req_queue();
}
void pdcp_layer_init_for_CU(void)
{
/* hack: be sure to initialize only once */
static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static int initialized = 0;
if (pthread_mutex_lock(&m) != 0) abort();
if (initialized) {
if (pthread_mutex_unlock(&m) != 0) abort();
return;
}
initialized = 1;
if (pthread_mutex_unlock(&m) != 0) abort();
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
}
#include "nfapi/oai_integration/vendor_ext.h"
#include "targets/RT/USER/lte-softmodem.h"
#include "openair2/RRC/NAS/nas_config.h"
......@@ -980,6 +1000,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, crnti, 0, 0,0);
}
if (!NODE_IS_DU(node_type)) {
nr_rrc_pdcp_config_asn1_req(
&ctxt,
rbconfig->srb_ToAddModList,
......@@ -992,13 +1013,16 @@ void nr_DRB_preconfiguration(uint16_t crnti)
NULL,
NULL,
Rlc_Bearer_ToAdd_list);
}
if (!NODE_IS_CU(node_type)) {
nr_rrc_rlc_config_asn1_req (&ctxt,
rbconfig->srb_ToAddModList,
rbconfig->drb_ToAddModList,
rbconfig->drb_ToReleaseList,
(LTE_PMCH_InfoList_r9_t *) NULL,
Rlc_Bearer_ToAdd_list);
}
LOG_D(PDCP, "%s:%d: done RRC PDCP/RLC ASN1 request for UE rnti %x\n", __FUNCTION__, __LINE__, ctxt.rnti);
......
......@@ -35,6 +35,8 @@
#include "NR_DRB-ToReleaseList.h"
#include "NR_CellGroupConfig.h"
#include "NR_RLC-Config.h"
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
#include <stdint.h>
......@@ -460,6 +462,20 @@ rb_found:
T(T_ENB_RLC_UL,
T_INT(0 /*ctxt_pP->module_id*/),
T_INT(ue->rnti), T_INT(rb_id), T_INT(size));
const ngran_node_t type = RC.nrrrc[0 /*ctxt_pP->module_id*/]->node_type;
AssertFatal(type != ngran_eNB_CU && type != ngran_ng_eNB_CU && type != ngran_gNB_CU,
"Can't be CU, bad node type %d\n", type);
if (NODE_IS_DU(type) && is_srb == 1) {
MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, F1AP_UL_RRC_MESSAGE);
F1AP_UL_RRC_MESSAGE(msg).rnti = ue->rnti;
F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_id;
F1AP_UL_RRC_MESSAGE(msg).rrc_container = (unsigned char *)buf;
F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = size;
itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(0 /*ctxt_pP->module_id*/), msg);
return;
}
}
if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) {
......
......@@ -218,6 +218,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
rrc->carrier.sizeof_SIB1 = do_SIB1_NR(&rrc->carrier,configuration);
LOG_I(NR_RRC,"Done init_NR_SI\n");
if (!NODE_IS_CU(RC.nrrrc[0]->node_type)){
printf("################ init_NR_SI rrc_mac_config_req_gNB \n");
rrc_mac_config_req_gNB(rrc->module_id,
rrc->carrier.ssb_SubcarrierOffset,
rrc->carrier.pdsch_AntennaPorts,
......@@ -276,7 +277,7 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
} else {
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
rrc_add_nsa_user(rrc,ue_context_p,NULL);
// rrc_add_nsa_user(rrc,ue_context_p,NULL);
}
}
}
......@@ -2442,8 +2443,10 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) {
itti_send_msg_to_task (TASK_CU_F1, GNB_MODULE_ID_TO_INSTANCE(j), msg_p);
break;
} else {// setup_req mcc/mnc match rrc internal list element
LOG_W(NR_RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d \n",
j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],rrc->configuration.mnc[0], f1_setup_req->mnc[i]);
LOG_W(NR_RRC,"[Inst %d] No matching MCC/MNC: rrc->mcc/f1_setup_req->mcc %d/%d rrc->mnc/f1_setup_req->mnc %d/%d rrc->nr_cellid/f1_setup_req->nr_cellid %d/%d \n",
j, rrc->configuration.mcc[0], f1_setup_req->mcc[i],
rrc->configuration.mnc[0], f1_setup_req->mnc[i],
rrc->nr_cellid, f1_setup_req->nr_cellid[i]);
}
}// for (int j=0;j<RC.nb_inst;j++)
......
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