Merge remote-tracking branch 'origin/sim-channels' into integration_2020_wk15

This commit is contained in:
hardy
2021-04-14 14:37:09 +02:00
59 changed files with 1534 additions and 1114 deletions
+2 -11
View File
@@ -65,17 +65,8 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
// 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 - channelmod_get_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;
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256;
// 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);
+49 -35
View File
@@ -69,7 +69,9 @@ extern RAN_CONTEXT_t RC;
#define RFSIMU_SECTION "rfsimulator"
#define RFSIMU_OPTIONS_PARAMNAME "options"
# define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\
#define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\
" chanmod: enable channel modelisation\n"\
" saviq: enable saving written iqs to a file\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -78,21 +80,21 @@ extern RAN_CONTEXT_t RC;
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
#define RFSIMULATOR_PARAMS_DESC { \
{"serveraddr", "<ip address to connect to>\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
{"serverport", "<port to connect to>\n", simOpt, 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",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
{"modelname", "<channel model name>\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
{"ploss", "<channel path loss in dB>\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
{"forgetfact", "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
{"offset", "<channel offset in samps>\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
{"serveraddr", "<ip address to connect to>\n", simOpt, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
{"serverport", "<port to connect to>\n", simOpt, 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",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
{"modelname", "<channel model name>\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
{"ploss", "<channel path loss in dB>\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
{"forgetfact", "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
{"offset", "<channel offset in samps>\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
};
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
static telnetshell_cmddef_t rfsimu_cmdarray[] = {
{"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
{"setmodel","<model name> <model type>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
{"","",NULL},
};
@@ -133,6 +135,7 @@ typedef struct {
double chan_pathloss;
double chan_forgetfact;
int chan_offset;
float noise_power_dB;
void *telnetcmd_qid;
poll_telnetcmdq_func_t poll_telnetcmdq;
} rfsimulator_state_t;
@@ -182,15 +185,9 @@ static void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
tableNor(rand);
init_done=true;
}
ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
bridge->channelmod,
bridge->sample_rate,
bridge->tx_bw,
30e-9, // TDL delay-spread parameter
bridge->chan_forgetfact, // forgetting_factor
bridge->chan_offset, // maybe used for TA
bridge->chan_pathloss); // path_loss in dB
char *modelname = (bridge->typeStamp == ENB_MAGICDL) ? "rfsimu_channel_ue0":"rfsimu_channel_enB0";
ptr->channel_model=find_channel_desc_fromname(modelname); // path_loss in dB
AssertFatal((ptr->channel_model!= NULL),"Channel model %s not found, check config file\n",modelname);
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
random_channel(ptr->channel_model,false);
}
@@ -299,7 +296,8 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
break;
} else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) {
init_channelmod();
rfsimulator->channelmod=modelid_fromname(modelname);
load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->tx_bw);
rfsimulator->channelmod=true;
} else {
fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]);
exit(-1);
@@ -320,20 +318,27 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
char *modelname=NULL;
int s = sscanf(buff,"%ms\n",&modelname);
char *modeltype=NULL;
if (debug)
prnt("rfsimu_setchanmod_cmd buffer \"%s\"\n",buff);
int s = sscanf(buff,"%m[^ ] %ms\n",&modelname, &modeltype);
if (s == 1) {
int channelmod=modelid_fromname(modelname);
if (s == 2) {
int channelmod=modelid_fromstrtype(modeltype);
if (channelmod<0)
prnt("ERROR: model %s unknown\n",modelname);
prnt("ERROR: model type %s unknown\n",modeltype);
else {
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
int found=0;
for (int i=0; i<FD_SETSIZE; i++) {
buffer_t *b=&t->buf[i];
if ( b->channel_model==NULL)
continue;
if (b->channel_model->model_name==NULL)
continue;
if (b->conn_sock >= 0 && (strcmp(b->channel_model->model_name,modelname)==0)) {
if (b->conn_sock >= 0 ) {
channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels,
channelmod,
t->sample_rate,
@@ -341,21 +346,29 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
30e-9, // TDL delay-spread parameter
t->chan_forgetfact, // forgetting_factor
t->chan_offset, // maybe used for TA
t->chan_pathloss); // path_loss in dB
t->chan_pathloss,
t->noise_power_dB
); // path_loss in dB
set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
set_channeldesc_name(newmodel,modelname);
random_channel(newmodel,false);
channel_desc_t *oldmodel=b->channel_model;
b->channel_model=newmodel;
free_channel_desc_scm(oldmodel);
prnt("New model %s applied to channel connected to sock %d\n",modelname,i);
prnt("New model type %s applied to channel %s connected to sock %d\n",modeltype,modelname,i);
found=1;
break;
}
}
} /* for */
if (found==0)
prnt("Channel %s not found or not currently used\n",modelname);
}
} else {
prnt("ERROR: no model specified\n");
prnt("ERROR: 2 parameters required: model name and model type (%i found)\n",s);
}
free(modelname);
free(modeltype);
return CMDSTATUS_FOUND;
}
@@ -774,6 +787,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// to change the log level, use this on command line
// --log_config.hw_log_level debug
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
// initialize channel simulation
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;
rfsimulator->tx_bw=openair0_cfg->tx_bw;
rfsimulator_readconfig(rfsimulator);
pthread_mutex_init(&Sockmutex, NULL);
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side");
@@ -798,11 +816,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->buf[i].conn_sock=-1;
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
// initialize channel simulation
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;
rfsimulator->tx_bw=openair0_cfg->tx_bw;
//randominit(0);
set_taus_seed(0);
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
-1
View File
@@ -201,7 +201,6 @@ int main(int argc, char *argv[]) {
void *buff=malloc(bufSize);
uint64_t timestamp=0;
const int blockSize=1920;
// If fileSize is not multiple of blockSize*4 then discard remaining samples
fileSize = (fileSize/(blockSize<<2))*(blockSize<<2);
-1
View File
@@ -869,7 +869,6 @@ static void *ru_thread_asynch_rxtx( void *param ) {
LOG_I(PHY, "devices ok (ru_thread_asynch_rxtx)\n");
while (!oai_exit) {
if (oai_exit) break;
if (ru->state != RU_RUN) {
subframe=0;
+2
View File
@@ -361,6 +361,7 @@ void init_ocm(void) {
DS_TDL,
0.0,
0,
0,
0);
random_channel(sim.RU2UE[ru_id][UE_id][CC_id],0);
LOG_D(OCM,"[SIM] Initializing channel (%s) from UE %d to ru %d\n", "AWGN", UE_id, ru_id);
@@ -374,6 +375,7 @@ void init_ocm(void) {
DS_TDL,
0.0,
0,
0,
0);
random_channel(sim.UE2RU[UE_id][ru_id][CC_id],0);
// to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed.