diff --git a/executables/nr-ue-ru.c b/executables/nr-ue-ru.c index daedc1b02e..f439374e5b 100644 --- a/executables/nr-ue-ru.c +++ b/executables/nr-ue-ru.c @@ -311,6 +311,7 @@ void nrue_init_openair0(void) cfg->duplex_mode = duplex_mode_FDD; cfg->Mod_id = 0; + cfg->ru_id = ru_id; cfg->num_rb_dl = frame_parms->N_RB_DL; cfg->tx_num_channels = min(4, frame_parms->nb_antennas_tx); cfg->rx_num_channels = min(4, frame_parms->nb_antennas_rx); diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index 8d6a43beaf..6dfaf9c57f 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -212,6 +212,8 @@ typedef struct split7_config { typedef struct openair0_config { //! Module ID for this configuration int Mod_id; + //! RU ID of this device + int ru_id; //! duplexing mode duplex_mode_t duplex_mode; //! number of downlink resource blocks diff --git a/radio/rfsimulator/simulator.cpp b/radio/rfsimulator/simulator.cpp index eb49dd6320..876b75249a 100644 --- a/radio/rfsimulator/simulator.cpp +++ b/radio/rfsimulator/simulator.cpp @@ -81,7 +81,19 @@ typedef enum { SIMU_ROLE_SERVER = 1, SIMU_ROLE_CLIENT } simuRole; // #define RFSIMU_SECTION "rfsimulator" +#define RFSIMU_SERVER_ADDR "serveraddr" +#define RFSIMU_SERVER_PORT "serverport" #define RFSIMU_OPTIONS_PARAMNAME "options" +#define RFSIMU_IQFILE "IQfile" +#define RFSIMU_MODELNAME "modelname" +#define RFSIMU_PLOSS "ploss" +#define RFSIMU_FORGETFACT "forgetfact" +#define RFSIMU_OFFSET "offset" +#define RFSIMU_PROP_DELAY "prop_delay" +#define RFSIMU_WAIT_TIMEOUT "wait_timeout" +#define RFSIMU_ENABLE_BEAMS "enable_beams" +#define RFSIMU_NUM_CONCURRENT_BEAMS "num_concurrent_beams" +#define RFSIMU_BEAM_MAP "beam_map" #define RFSIMU_BEAM_GAINS "beam_gains" #define RFSIMU_BEAM_IDS "beam_ids" @@ -98,19 +110,19 @@ typedef enum { SIMU_ROLE_SERVER = 1, SIMU_ROLE_CLIENT } simuRole; /* optname helpstr paramflags XXXptr defXXXval */ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define RFSIMULATOR_PARAMS_DESC { \ - STRINGPARAM("serveraddr", "\n", simOpt, &rfsimulator->ip, "127.0.0.1"), \ - UINT16PARAM("serverport", "\n", simOpt, &rfsimulator->port, PORT), \ + STRINGPARAM(RFSIMU_SERVER_ADDR, "\n", simOpt, NULL, "127.0.0.1"), \ + UINT16PARAM(RFSIMU_SERVER_PORT, "\n", simOpt, NULL, PORT), \ STRLISTPARAM(RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, simOpt, NULL, NULL), \ - STRINGPARAM("IQfile", "\n", simOpt, &saveF, "/tmp/rfsimulator.iqs"),\ - STRINGPARAM("modelname", "\n", simOpt, &modelname, "AWGN"), \ - DOUBLEPARAM("ploss", "\n", simOpt, &rfsimulator->chan_pathloss, 0), \ - DOUBLEPARAM("forgetfact", "\n", simOpt, &rfsimulator->chan_forgetfact, 0), \ - UINT64PARAM("offset", "\n", simOpt, &rfsimulator->chan_offset, 0L), \ - DOUBLEPARAM("prop_delay", "\n", simOpt, &(rfsimulator->prop_delay_ms), 0.0), \ - INTPARAM("wait_timeout", "\n", simOpt, &rfsimulator->wait_timeout, 1), \ - BOOLPARAM("enable_beams", "\n", simBool,&(beam_ctrl->enable_beams), 0), \ - INTPARAM("num_concurrent_beams", "\n", simOpt, &beam_ctrl->num_concurrent_beams, 1), \ - UINT64PARAM("beam_map", "\n", simOpt, &beam_map, 1), \ + STRINGPARAM(RFSIMU_IQFILE, "\n", simOpt, NULL, "/tmp/rfsimulator.iqs"),\ + STRINGPARAM(RFSIMU_MODELNAME, "\n", simOpt, NULL, "AWGN"), \ + DOUBLEPARAM(RFSIMU_PLOSS, "\n", simOpt, NULL, 0), \ + DOUBLEPARAM(RFSIMU_FORGETFACT, "\n", simOpt, NULL, 0), \ + UINT64PARAM(RFSIMU_OFFSET, "\n", simOpt, NULL, 0L), \ + DOUBLEPARAM(RFSIMU_PROP_DELAY, "\n", simOpt, NULL, 0.0), \ + INTPARAM(RFSIMU_WAIT_TIMEOUT, "\n", simOpt, NULL, 1), \ + BOOLPARAM(RFSIMU_ENABLE_BEAMS, "\n", simBool,NULL, 0), \ + INTPARAM(RFSIMU_NUM_CONCURRENT_BEAMS, "\n", simOpt, NULL, 1), \ + UINT64PARAM(RFSIMU_BEAM_MAP, "\n", simOpt, NULL, 1), \ STRINGPARAM(RFSIMU_BEAM_IDS, "\n", simOpt, NULL, NULL), \ STRINGPARAM(RFSIMU_BEAM_GAINS, "\n", simOpt, NULL, NULL), \ }; @@ -182,6 +194,7 @@ typedef struct { typedef struct { int listen_sock, epollfd; pthread_mutex_t Sockmutex; + int ru_id; unsigned int nb_cnx; openair0_timestamp_t nextRxTstamp; openair0_timestamp_t lastWroteTS; @@ -354,7 +367,7 @@ static buffer_t *allocCirBuf(rfsimulator_state_t *bridge, int sock) sizeofArray(modelname), "rfsimu_channel_%s%d", (bridge->role == SIMU_ROLE_SERVER) ? "ue" : "enB", - bridge->nb_cnx - 1); + (bridge->role == SIMU_ROLE_SERVER) ? bridge->nb_cnx - 1 : bridge->ru_id); ptr->channel_model = find_channel_desc_fromname(modelname); // path_loss in dB if (!ptr->channel_model) { // Use legacy method to find channel model - this will use the same channel model for all clients @@ -520,19 +533,45 @@ static void process_gains(char *str, rfsim_beam_ctrl_t *beam_ctrl) static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { - char *saveF = NULL; - char *modelname = NULL; + configmodule_interface_t *cfg = config_get_if(); + paramdef_t *rfsimuParam; + paramdef_t rfsimuParams[] = RFSIMULATOR_PARAMS_DESC; + paramlist_def_t rfsimuParamList = {RFSIMU_SECTION, NULL, 0}; + int ret = config_getlist(cfg, &rfsimuParamList, rfsimuParams, sizeofArray(rfsimuParams), NULL); + if (ret < 0 || rfsimuParamList.numelt <= 0) { + ret = config_get(cfg, rfsimuParams, sizeofArray(rfsimuParams), RFSIMU_SECTION); + AssertFatal(ret >= 0, "configuration couldn't be performed\n"); + LOG_W(HW, "Warning: rfsimulator parameters should be provided as array elements!\n"); + rfsimuParam = rfsimuParams; + } else { + int ru_id = rfsimulator->ru_id; + AssertFatal(rfsimuParamList.numelt > ru_id, + "no rfsimulator parameters (numelt %d) specified for card %d\n", + rfsimuParamList.numelt, + ru_id); + rfsimuParam = rfsimuParamList.paramarray[ru_id]; + } + + rfsimulator->ip = strdup(*(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_SERVER_ADDR)->strptr)); + rfsimulator->port = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_SERVER_PORT)->u16ptr); + char *saveF = strdup(*(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_IQFILE)->strptr)); +//char *modelname = strdup(*(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_MODELNAME)->strptr)); + rfsimulator->chan_pathloss = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_PLOSS)->dblptr); + rfsimulator->chan_forgetfact = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_FORGETFACT)->dblptr); + rfsimulator->chan_offset = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_OFFSET)->u64ptr); + rfsimulator->prop_delay_ms = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_PROP_DELAY)->dblptr); + rfsimulator->wait_timeout = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_WAIT_TIMEOUT)->iptr); + rfsim_beam_ctrl_t *beam_ctrl = rfsimulator->beam_ctrl; - uint64_t beam_map = 1; - paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC; - int p = config_paramidx_fromname(rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_OPTIONS_PARAMNAME); - int ret = config_get(config_get_if(), rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_SECTION); - AssertFatal(ret >= 0, "configuration couldn't be performed\n"); + beam_ctrl->enable_beams = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_ENABLE_BEAMS)->iptr); + beam_ctrl->num_concurrent_beams = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_NUM_CONCURRENT_BEAMS)->iptr); + uint64_t beam_map = *(gpd(rfsimuParam, sizeofArray(rfsimuParams), RFSIMU_BEAM_MAP)->u64ptr); rfsimulator->saveIQfile = -1; - for (int i = 0; i < rfsimu_params[p].numelt; i++) { - if (strcmp(rfsimu_params[p].strlistptr[i], "saviq") == 0) { + int p = config_paramidx_fromname(rfsimuParams, sizeofArray(rfsimuParams), RFSIMU_OPTIONS_PARAMNAME); + for (int i = 0; i < rfsimuParam[p].numelt; i++) { + if (strcmp(rfsimuParam[p].strlistptr[i], "saviq") == 0) { rfsimulator->saveIQfile = open(saveF, O_APPEND | O_CREAT | O_TRUNC | O_WRONLY, 0666); if (rfsimulator->saveIQfile != -1) @@ -543,7 +582,7 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) } break; - } else if (strcmp(rfsimu_params[p].strlistptr[i], "chanmod") == 0) { + } else if (strcmp(rfsimuParam[p].strlistptr[i], "chanmod") == 0) { init_channelmod(); load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, @@ -552,24 +591,24 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) rfsimulator->tx_bw); rfsimulator->channelmod = true; } else { - fprintf(stderr, "unknown rfsimulator option: %s\n", rfsimu_params[p].strlistptr[i]); + fprintf(stderr, "unknown rfsimulator option: %s\n", rfsimuParam[p].strlistptr[i]); exit(-1); } } - int beam_gains_param_index = config_paramidx_fromname(rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_BEAM_GAINS); - if (rfsimu_params[beam_gains_param_index].strptr) { - process_gains(*rfsimu_params[beam_gains_param_index].strptr, beam_ctrl); + int beam_gains_param_index = config_paramidx_fromname(rfsimuParams, sizeofArray(rfsimuParams), RFSIMU_BEAM_GAINS); + if (rfsimuParam[beam_gains_param_index].strptr) { + process_gains(*rfsimuParam[beam_gains_param_index].strptr, beam_ctrl); } std::vector initial_beams = beam_map_to_beams(beam_map); beam_ctrl->rx.beams = initial_beams; beam_ctrl->tx.beams = initial_beams; - int beam_ids_param_index = config_paramidx_fromname(rfsimu_params, sizeofArray(rfsimu_params), RFSIMU_BEAM_IDS); - if (rfsimu_params[beam_ids_param_index].strptr) { + int beam_ids_param_index = config_paramidx_fromname(rfsimuParams, sizeofArray(rfsimuParams), RFSIMU_BEAM_IDS); + if (rfsimuParam[beam_ids_param_index].strptr) { std::vector beam_ids; - std::stringstream ss(*rfsimu_params[beam_ids_param_index].strptr); + std::stringstream ss(*rfsimuParam[beam_ids_param_index].strptr); std::string token; while (std::getline(ss, token, ',')) { beam_ids.push_back(std::stoi(token)); @@ -1563,6 +1602,7 @@ extern "C" __attribute__((__visibility__("default"))) int device_init(openair0_d // --log_config.hw_log_level debug rfsimulator_state_t *rfsimulator = static_cast(calloc(sizeof(rfsimulator_state_t), 1)); // initialize channel simulation + rfsimulator->ru_id = openair0_cfg->ru_id; rfsimulator->tx_num_channels = openair0_cfg->tx_num_channels; rfsimulator->rx_num_channels = openair0_cfg->rx_num_channels; rfsimulator->sample_rate = openair0_cfg->sample_rate; @@ -1596,8 +1636,8 @@ extern "C" __attribute__((__visibility__("default"))) int device_init(openair0_d } /* let's pretend to be a b2x0 */ device->type = RFSIMULATOR; - openair0_cfg[0].rx_gain[0] = 0; - device->openair0_cfg = &openair0_cfg[0]; + openair0_cfg->rx_gain[0] = 0; + device->openair0_cfg = openair0_cfg; device->priv = rfsimulator; device->trx_write_init = rfsimulator_write_init; device->trx_set_beams = rfsimulator_set_beams;