add channel model option to rfsimulator and prevent common libraries re-compilation when using both --UE --eNB options in build_oai script
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
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;
|
||||
#define RFSIMULATOR_PARAMS_DESC {\
|
||||
{"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 },\
|
||||
{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 }\
|
||||
{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 },\
|
||||
{"modelname", "<channel model name>\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 }\
|
||||
};
|
||||
|
||||
pthread_mutex_t Sockmutex;
|
||||
@@ -220,6 +221,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
||||
|
||||
void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
||||
char *saveF=NULL;
|
||||
char *modelname=NULL;
|
||||
paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC;
|
||||
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);
|
||||
@@ -237,7 +239,7 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
||||
|
||||
break;
|
||||
} else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) {
|
||||
init_channelmod();
|
||||
init_channelmod(modelname);
|
||||
rfsimulator->enable_channelmod=true;
|
||||
} else {
|
||||
fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]);
|
||||
|
||||
Reference in New Issue
Block a user