Commit d59833fe authored by frtabu's avatar frtabu

add channel model option to rfsimulator and prevent common libraries...

add channel model option to rfsimulator and prevent common libraries re-compilation when using both --UE --eNB options in build_oai script
parent 03c8e0d1
...@@ -1822,7 +1822,7 @@ add_library(LFDS7 ...@@ -1822,7 +1822,7 @@ add_library(LFDS7
# Simulation library # Simulation library
########################## ##########################
add_library(SIMU set (SIMUSRC
${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
...@@ -1833,9 +1833,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c ...@@ -1833,9 +1833,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c
${OPENAIR1_DIR}/SIMULATION/RF/rf.c ${OPENAIR1_DIR}/SIMULATION/RF/rf.c
${OPENAIR1_DIR}/SIMULATION/RF/dac.c ${OPENAIR1_DIR}/SIMULATION/RF/dac.c
${OPENAIR1_DIR}/SIMULATION/RF/adc.c ${OPENAIR1_DIR}/SIMULATION/RF/adc.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/targets/ARCH/rfsimulator/channelmod.c
#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
) )
# Simulation library
##########################
add_library( SIMU SHARED ${SIMUSRC} )
add_library(SIMU_ETH add_library(SIMU_ETH
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
...@@ -2134,7 +2138,6 @@ add_executable(lte-uesoftmodem ...@@ -2134,7 +2138,6 @@ add_executable(lte-uesoftmodem
${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
${OPENAIR_TARGETS}/RT/USER/ru_control.c ${OPENAIR_TARGETS}/RT/USER/ru_control.c
${OPENAIR_TARGETS}/RT/USER/rfsim.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
......
...@@ -515,21 +515,7 @@ function main() { ...@@ -515,21 +515,7 @@ function main() {
$lte_build_dir $lte_exec \ $lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL $lte_exec $dbin/$lte_exec.$REL
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
fi fi
if [ "$UE" = 1 ] ; then if [ "$UE" = 1 ] ; then
...@@ -538,21 +524,6 @@ function main() { ...@@ -538,21 +524,6 @@ function main() {
$lte_build_dir $lte_exec \ $lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL $lte_exec $dbin/$lte_exec.$REL
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
# ue_ip driver compilation # ue_ip driver compilation
compilations \ compilations \
$lte_build_dir ue_ip \ $lte_build_dir ue_ip \
...@@ -665,10 +636,25 @@ function main() { ...@@ -665,10 +636,25 @@ function main() {
fi fi
# build RF device and transport protocol libraries # build RF device, transport protocol libraries and all
# shared libraries common to UE and eNB
##################################### #####################################
if [ "$eNB" = "1" -o "$UE" = "1" ] ; then if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
# build RF device libraries # build RF device libraries
if [ "$HW" != "None" ] ; then if [ "$HW" != "None" ] ; then
rm -f liboai_device.so rm -f liboai_device.so
......
...@@ -250,7 +250,8 @@ struct complex R_sqrt_22_EPA_low_tap[16] = {{1.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0. ...@@ -250,7 +250,8 @@ struct complex R_sqrt_22_EPA_low_tap[16] = {{1.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.
}; };
struct complex *R_sqrt_22_EPA_low[1] = {R_sqrt_22_EPA_low_tap}; struct complex *R_sqrt_22_EPA_low[1] = {R_sqrt_22_EPA_low_tap};
struct complex R_sqrt_22_EPA_high_tap[16] = {{0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0}, struct complex R_sqrt_22_EPA_high_tap[16] = {
{0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0},
{0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0}, {0.2821,0.0}, {0.4500,0.0},
{0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.2821,0.0}, {0.7179,0.0}, {0.4500,0.0},
{0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0} {0.2821,0.0}, {0.4500,0.0}, {0.4500,0.0}, {0.7179,0.0}
...@@ -1496,13 +1497,18 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { ...@@ -1496,13 +1497,18 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
return 0; return 0;
} }
void init_channelmod(void) { int init_channelmod(char *modelname) {
int modelid=map_str_to_int(channelmod_names,modelname);
AssertFatal(modelid>0,
"random_channel.c: Error channel model %s unknown\n",modelname);
/* look for telnet server, if it is loaded, add the coding commands to it */ /* look for telnet server, if it is loaded, add the coding commands to it */
add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
if (addcmd != NULL) { if (addcmd != NULL) {
addcmd("channelmod",channelmod_vardef,channelmod_cmdarray); addcmd("channelmod",channelmod_vardef,channelmod_cmdarray);
} }
return modelid;
} }
#ifdef RANDOM_CHANNEL_MAIN #ifdef RANDOM_CHANNEL_MAIN
......
...@@ -432,7 +432,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si ...@@ -432,7 +432,7 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
uint64_t TS, uint64_t TS,
uint32_t CirSize uint32_t CirSize
); );
void init_channelmod(void) ; int init_channelmod(char *channelname) ;
double N_RB2sampling_rate(uint16_t N_RB); double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB); double N_RB2channel_bandwidth(uint16_t N_RB);
......
/*
Author: Laurent THOMAS, Open Cells for Nokia
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <common/utils/assertions.h>
#include <common/utils/LOG/log.h>
#include <common/config/config_userapi.h>
#include <openair1/SIMULATION/TOOLS/sim.h>
/*
Legacy study:
The parameters are:
gain&loss (decay, signal power, ...)
either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average
=> don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE
will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop)
lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas);
a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain
multi_path (auto convolution, ISI, ...)
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
legacy: we regenerate each sub frame in UL, and each frame only in DL
*/
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
uint64_t TS,
uint32_t CirSize
) {
// channelDesc->path_loss_dB should contain the total path gain
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
// UE and NB gain control to be added
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
// Energy in one sample to calibrate input noise
//Fixme: modified the N0W computation, not understand the origin value
const double KT=1.38e-23*290; //Boltzman*temperature
// sampling rate is linked to acquisition band (the input pass band filter)
const double noise_figure_watt = KT*channelDesc->sampling_rate;
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
// the parameter "-s" is declared as SNR, but the input power is not well defined
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
const double rxGain= 132.24 - snr_dB;
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
// fixme: the last constant is pure trial results to make decent noise
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
// Fixme: we don't fill the offset length samples at begining ?
// anyway, in today code, channel_offset=0
const int dd = abs(channelDesc->channel_offset);
const int nbTx=channelDesc->nb_tx;
for (int i=0; i<((int)nbSamples-dd); i++) {
struct complex16 *out_ptr=after_channel_sig+dd+i;
struct complex rx_tmp= {0};
for (int txAnt=0; txAnt < nbTx; txAnt++) {
const struct complex *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)];
//const struct complex *channelModelEnd=channelModel+channelDesc->channel_length;
for (int l = 0; l<(int)channelDesc->channel_length; l++) {
// let's assume TS+i >= l
// fixme: the rfsimulator current structure is interleaved antennas
// this has been designed to not have to wait a full block transmission
// but it is not very usefull
// it would be better to split out each antenna in a separate flow
// that will allow to mix ru antennas freely
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
rx_tmp.x += tx16.r * channelModel[l].x - tx16.i * channelModel[l].y;
rx_tmp.y += tx16.i * channelModel[l].x + tx16.r * channelModel[l].y;
} //l
}
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr++;
}
if ( (TS*nbTx)%CirSize+nbSamples <= CirSize )
// Cast to a wrong type for compatibility !
LOG_D(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n",
10*log10((double)signal_energy((int32_t *)&input_sig[(TS*nbTx)%CirSize], nbSamples)),
10*log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)),
channelDesc->path_loss_dB,
10*log10(noise_per_sample));
}
...@@ -58,8 +58,9 @@ extern RAN_CONTEXT_t RC; ...@@ -58,8 +58,9 @@ extern RAN_CONTEXT_t RC;
#define RFSIMULATOR_PARAMS_DESC {\ #define RFSIMULATOR_PARAMS_DESC {\
{"serveraddr", "<ip address to connect to>\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ {"serveraddr", "<ip address to connect to>\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
{"serverport", "<port to connect to>\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ {"serverport", "<port to connect to>\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
{RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0}, \ {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0},\
{"IQfile", "<file path to use when saving IQs>\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 }\ {"IQfile", "<file path to use when saving IQs>\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
{"modelname", "<channel model name>\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 }\
}; };
pthread_mutex_t Sockmutex; pthread_mutex_t Sockmutex;
...@@ -220,6 +221,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) { ...@@ -220,6 +221,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
char *saveF=NULL; char *saveF=NULL;
char *modelname=NULL;
paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC; paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC;
int p = config_paramidx_fromname(rfsimu_params,sizeof(rfsimu_params)/sizeof(paramdef_t), RFSIMU_OPTIONS_PARAMNAME) ; int p = config_paramidx_fromname(rfsimu_params,sizeof(rfsimu_params)/sizeof(paramdef_t), RFSIMU_OPTIONS_PARAMNAME) ;
int ret = config_get( rfsimu_params,sizeof(rfsimu_params)/sizeof(paramdef_t),RFSIMU_SECTION); int ret = config_get( rfsimu_params,sizeof(rfsimu_params)/sizeof(paramdef_t),RFSIMU_SECTION);
...@@ -237,7 +239,7 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { ...@@ -237,7 +239,7 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
break; break;
} else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) { } else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) {
init_channelmod(); init_channelmod(modelname);
rfsimulator->enable_channelmod=true; rfsimulator->enable_channelmod=true;
} else { } else {
fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]); fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]);
......
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