Commit 1f0e8266 authored by frtabu's avatar frtabu

enhance channel model configuration

parent 3b1b74cf
/* configuration for channel modelisation */
/* To be included in main config file when */
/* channel modelisation is used (rfsimulator with chanmod options enabled) */
channelmod = {
max_chan=10;
modellist="modellist_rfsimu_1";
modellist_rfsimu_1 = (
{
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 0;
noise_power_dB = 0;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
},
{
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 0;
noise_power_dB = 0;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
},
);
modellist_rfsimu_2 = (
{
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 0;
noise_power_dB = 0;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
},
{
model_name = "rfsimu_channel_ue0"
type = "AWGN";
ploss_dB = 0;
noise_power_dB = 0;
forgetfact = 0;
offset = 0;
ds_tdl = 0;
},
);
};
...@@ -255,7 +255,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) ...@@ -255,7 +255,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */ if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */ ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */
((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) || ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ||
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) { ((strlen(oneargv) > 2) && (strcmp(oneargv + 2, cfgoptions[n].optname) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
char *valptr=NULL; char *valptr=NULL;
int ret; int ret;
config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED;
......
...@@ -495,7 +495,7 @@ int process_command(char *buf) { ...@@ -495,7 +495,7 @@ int process_command(char *buf) {
memset(cmdb,0,sizeof(cmdb)); memset(cmdb,0,sizeof(cmdb));
bufbck=strdup(buf); bufbck=strdup(buf);
rt=CMDSTATUS_NOTFOUND; rt=CMDSTATUS_NOTFOUND;
j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb); j = sscanf(buf,"%19s %19s %[^\t\n]",modulename,cmd,cmdb);
if (telnetparams.telnetdbg > 0) if (telnetparams.telnetdbg > 0)
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb); printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
......
...@@ -61,7 +61,9 @@ static telnetshell_vardef_t channelmod_vardef[] = { ...@@ -61,7 +61,9 @@ static telnetshell_vardef_t channelmod_vardef[] = {
static double snr_dB=25; static double snr_dB=25;
static double sinr_dB=0; static double sinr_dB=0;
static unsigned int max_chan; static unsigned int max_chan;
static channel_desc_t** defined_channels; static channel_desc_t **defined_channels;
static char modellist_name[MAX_OPTNAME_SIZE]="";
void fill_channel_desc(channel_desc_t *chan_desc, void fill_channel_desc(channel_desc_t *chan_desc,
uint8_t nb_tx, uint8_t nb_tx,
uint8_t nb_rx, uint8_t nb_rx,
...@@ -494,16 +496,17 @@ struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap}; ...@@ -494,16 +496,17 @@ struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap};
//Rayleigh1_orth_eff_ch_TM4 //Rayleigh1_orth_eff_ch_TM4
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx, uint8_t nb_rx,
SCM_t channel_model, SCM_t channel_model,
double sampling_rate, double sampling_rate,
double channel_bandwidth, double channel_bandwidth,
double DS_TDL, double DS_TDL,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
double path_loss_dB, double path_loss_dB,
float noise_power_dB) { float noise_power_dB) {
channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t)); channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
for(int i=0; i<max_chan;i++) { for(int i=0; i<max_chan;i++) {
if (defined_channels[i] == NULL) { if (defined_channels[i] == NULL) {
...@@ -540,6 +543,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -540,6 +543,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double *tdl_amps_dB; double *tdl_amps_dB;
double *tdl_delays; double *tdl_delays;
/* Spatial Channel Models (SCM) channel model from TR 38.901 Section 7.7.2 */
switch (channel_model) { switch (channel_model) {
case SCM_A: case SCM_A:
LOG_W(OCM,"channel model not yet supported\n"); LOG_W(OCM,"channel model not yet supported\n");
...@@ -670,6 +674,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -670,6 +674,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
break; break;
/* tapped delay line (TDL) channel model from TR 38.901 Section 7.7.2 */
case TDL_A: case TDL_A:
case TDL_B: case TDL_B:
case TDL_C: case TDL_C:
...@@ -1631,8 +1636,21 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -1631,8 +1636,21 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->nb_paths = 10; chan_desc->nb_paths = 10;
return(chan_desc); return(chan_desc);
} } /* channel_desc_t *new_channel_desc_scm */
channel_desc_t * find_channel_desc_fromname( char *modelname ) {
for(int i=0; i<max_chan;i++) {
if (defined_channels[i] != NULL) {
if (strcmp(defined_channels[i]->model_name,modelname) == 0)
return defined_channels[i];
}
}
LOG_E(OCM,"Model %s not found \n", modelname);
return NULL;
} /* channel_desc_t * new_channel_desc_fromconfig */
void free_channel_desc_scm(channel_desc_t *ch) { void free_channel_desc_scm(channel_desc_t *ch) {
// Must be made cleanly, a lot of leaks... // Must be made cleanly, a lot of leaks...
defined_channels[ch->chan_idx]=NULL; defined_channels[ch->chan_idx]=NULL;
...@@ -1657,7 +1675,8 @@ void free_channel_desc_scm(channel_desc_t *ch) { ...@@ -1657,7 +1675,8 @@ void free_channel_desc_scm(channel_desc_t *ch) {
free(ch->R_sqrt); free(ch->R_sqrt);
free(ch->ch); free(ch->ch);
free(ch->chF); free(ch->chF);
free(ch->a); free(ch->a);
free(ch->model_name);
free(ch); free(ch);
} }
...@@ -1665,6 +1684,12 @@ void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) { ...@@ -1665,6 +1684,12 @@ void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) {
cdesc->module_id=module_id; cdesc->module_id=module_id;
} }
void set_channeldesc_name(channel_desc_t *cdesc,char *modelname) {
if(cdesc->model_name != NULL)
free(cdesc->model_name);
cdesc->model_name=strdup(modelname);
}
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
double s; double s;
int i,k,l,aarx,aatx; int i,k,l,aarx,aatx;
...@@ -1851,7 +1876,7 @@ double N_RB2channel_bandwidth(uint16_t N_RB) { ...@@ -1851,7 +1876,7 @@ double N_RB2channel_bandwidth(uint16_t N_RB) {
break; break;
default: default:
LOG_E(PHY,"Unknown N_PRB\n"); LOG_E(OCM,"Unknown N_PRB\n");
return(-1); return(-1);
} }
return(channel_bandwidth); return(channel_bandwidth);
...@@ -1871,9 +1896,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ...@@ -1871,9 +1896,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt
static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) { static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) {
char *module_id_str[]=MODULEID_STR_INIT; char *module_id_str[]=MODULEID_STR_INIT;
if (cd->module_id != 0) { prnt("model owner: %s\n",(cd->module_id != 0)?module_id_str[cd->module_id]:"not set");
prnt("model owner: %s\n",module_id_str[cd->module_id]);
}
prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate); prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate);
prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n", prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n",
cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No")); cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No"));
...@@ -1899,7 +1922,8 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { ...@@ -1899,7 +1922,8 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
} else if ( strcmp(subcmd,"current") == 0) { } else if ( strcmp(subcmd,"current") == 0) {
for (int i=0; i < max_chan ; i++) { for (int i=0; i < max_chan ; i++) {
if (defined_channels[i] != NULL) { if (defined_channels[i] != NULL) {
prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid)); prnt("model %i %s type %s: \n----------------\n", i, (defined_channels[i]->model_name !=NULL)?defined_channels[i]->model_name:"(no name set)",
map_int_to_str(channelmod_names,defined_channels[i]->modelid));
display_channelmodel(defined_channels[i],debug,prnt); display_channelmodel(defined_channels[i],debug,prnt);
} }
} }
...@@ -1972,10 +1996,10 @@ static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) ...@@ -1972,10 +1996,10 @@ static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt)
return CMDSTATUS_FOUND; return CMDSTATUS_FOUND;
} }
int modelid_fromname(char *modelname) { int modelid_fromstrtype(char *modeltype) {
int modelid=map_str_to_int(channelmod_names,modelname); int modelid=map_str_to_int(channelmod_names,modeltype);
if (modelid < 0) if (modelid < 0)
LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname); LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modeltype);
return modelid; return modelid;
} }
...@@ -1989,18 +2013,59 @@ double channelmod_get_sinr_dB(void) { ...@@ -1989,18 +2013,59 @@ double channelmod_get_sinr_dB(void) {
void init_channelmod(void) { void init_channelmod(void) {
paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC; paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC;
int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION);
int numparams=sizeof(channelmod_params)/sizeof(paramdef_t);
int ret = config_get( channelmod_params,numparams,CHANNELMOD_SECTION);
AssertFatal(ret >= 0, "configuration couldn't be performed"); AssertFatal(ret >= 0, "configuration couldn't be performed");
defined_channels=calloc(max_chan,sizeof( channel_desc_t*)); defined_channels=calloc(max_chan,sizeof( channel_desc_t*));
AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan); AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan);
/* look for telnet server, if it is loaded, add the channel modeling commands to it */ /* look for telnet server, if it is loaded, add the channel modeling 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);
} }
} } /* init_channelmod */
int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) {
paramdef_t achannel_params[] = CHANNELMOD_MODEL_PARAMS_DESC;
paramlist_def_t channel_list;
memset(&channel_list,0,sizeof(paramlist_def_t));
strncpy(channel_list.listname,modellist_name,MAX_OPTNAME_SIZE-1);
int numparams = sizeof(achannel_params)/sizeof(paramdef_t);
config_getlist( &channel_list,achannel_params,numparams, CHANNELMOD_SECTION);
AssertFatal(channel_list.numelt>0, "List %s.%s not found in config file\n",CHANNELMOD_SECTION,channel_list.listname);
int pindex_NAME = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NAME_PNAME);
int pindex_DT = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_DT_PNAME );
int pindex_FF = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_FF_PNAME );
int pindex_CO = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_CO_PNAME );
int pindex_PL = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_PL_PNAME );
int pindex_NP = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NP_PNAME );
int pindex_TYPE = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_TYPE_PNAME);
for (int i=0; i<channel_list.numelt; i++) {
int modid = modelid_fromstrtype( *(channel_list.paramarray[i][pindex_TYPE].strptr) );
if (modid <0) {
LOG_E(OCM,"Valid channel model types:\n");
for (int m=0; channelmod_names[i].name != NULL ; m++) {
printf(" %s ", map_int_to_str(channelmod_names,m ));
}
AssertFatal(0, "\n Choose a valid model type\n");
}
channel_desc_t *channeldesc_p = new_channel_desc_scm(nb_tx,nb_rx,modid,sampling_rate,channel_bandwidth,
*(channel_list.paramarray[i][pindex_DT].dblptr), *(channel_list.paramarray[i][pindex_FF].dblptr),
*(channel_list.paramarray[i][pindex_CO].iptr), *(channel_list.paramarray[i][pindex_PL].dblptr),
*(channel_list.paramarray[i][pindex_NP].dblptr) );
AssertFatal( (channeldesc_p!= NULL), "Could not allocate channel %s type %s \n",*(channel_list.paramarray[i][pindex_NAME].strptr), *(channel_list.paramarray[i][pindex_TYPE].strptr));
channeldesc_p->model_name = strdup(*(channel_list.paramarray[i][pindex_NAME].strptr));
LOG_I(OCM,"Model %s type %s allocated from config file, list %s\n",*(channel_list.paramarray[i][pindex_NAME].strptr),
*(channel_list.paramarray[i][pindex_TYPE].strptr), modellist_name);
} /* for loop on channel_list */
return channel_list.numelt;
} /* load_channelist */
#ifdef RANDOM_CHANNEL_MAIN #ifdef RANDOM_CHANNEL_MAIN
#define sampling_rate 5.0 #define sampling_rate 5.0
......
...@@ -107,8 +107,10 @@ typedef struct { ...@@ -107,8 +107,10 @@ typedef struct {
unsigned int chan_idx; unsigned int chan_idx;
/// id of the channel modeling algorithm /// id of the channel modeling algorithm
int modelid; int modelid;
/// identifies channel descriptor owner (the module which created this descriptor) /// identifies channel descriptor owner (the module which created this descriptor
channelmod_moduleid_t module_id; channelmod_moduleid_t module_id;
/// name of this descriptor,used for model created from config file at init time
char *model_name;
/// flags to properly trigger memory free /// flags to properly trigger memory free
unsigned int free_flags; unsigned int free_flags;
} channel_desc_t; } channel_desc_t;
...@@ -242,12 +244,37 @@ typedef enum { ...@@ -242,12 +244,37 @@ typedef enum {
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CHANNELMOD_SECTION "channelmod" #define CHANNELMOD_SECTION "channelmod"
/* global channel modelization parameters */
#define CHANNELMOD_MODELLIST_PARANAME "modellist"
#define CHANNELMOD_HELP_MODELLIST "<list name> channel list name in config file describing the model type and its parameters\n"
#define CHANNELMOD_PARAMS_DESC { \ #define CHANNELMOD_PARAMS_DESC { \
{"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\ {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\
{"sinr_dB", NULL, 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\ {"sinr_dB", NULL, 0, dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\
{"max_chan, CONFIG_HLP_MAX_CHAN", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\ {"max_chan", "Max number of runtime models", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\
{CHANNELMOD_MODELLIST_PARANAME, CHANNELMOD_HELP_MODELLIST, 0, strptr:(char **)&modellist_name, defstrval:"DefaultChannelList", TYPE_STRING, 60 },\
} }
/* parameters for one model */
#define CHANNELMOD_MODEL_NAME_PNAME "model_name"
#define CHANNELMOD_MODEL_TYPE_PNAME "type"
#define CHANNELMOD_MODEL_PL_PNAME "ploss_dB"
#define CHANNELMOD_MODEL_NP_PNAME "noise_power_dB"
#define CHANNELMOD_MODEL_FF_PNAME "forgetfact"
#define CHANNELMOD_MODEL_CO_PNAME "offset"
#define CHANNELMOD_MODEL_DT_PNAME "ds_tdl"
#define CHANNELMOD_MODEL_PARAMS_DESC { \
{CHANNELMOD_MODEL_NAME_PNAME, "name of the model\n", 0, strptr:NULL , defstrval:"", TYPE_STRING, 0 },\
{CHANNELMOD_MODEL_TYPE_PNAME, "name of the model type\n", 0, strptr:NULL , defstrval:"AWGN", TYPE_STRING, 0 },\
{CHANNELMOD_MODEL_PL_PNAME, "channel path loss in dB\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\
{CHANNELMOD_MODEL_NP_PNAME, "channel noise in dB\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\
{CHANNELMOD_MODEL_FF_PNAME, "channel forget factor ((0 to 1)\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\
{CHANNELMOD_MODEL_CO_PNAME, "channel offset in samps\n", 0, iptr:NULL, defintval:0, TYPE_INT, 0 },\
{CHANNELMOD_MODEL_DT_PNAME, "delay spread for TDL models\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 }\
}
#include "platform_constants.h" #include "platform_constants.h"
typedef struct { typedef struct {
...@@ -276,13 +303,17 @@ typedef struct { ...@@ -276,13 +303,17 @@ typedef struct {
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx, uint8_t nb_rx,
SCM_t channel_model, SCM_t channel_model,
double sampling_rate, double sampling_rate,
double channel_bandwidth, double channel_bandwidth,
double TDL_DS, double TDL_DS,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
double path_loss_dB, double path_loss_dB,
float noise_power_dB); float noise_power_dB);
channel_desc_t *find_channel_desc_fromname( char *modelname );
/** /**
\brief free memory allocated for a model descriptor \brief free memory allocated for a model descriptor
\param ch points to the model, which cannot be used after calling this fuction \param ch points to the model, which cannot be used after calling this fuction
...@@ -295,6 +326,12 @@ void free_channel_desc_scm(channel_desc_t *ch); ...@@ -295,6 +326,12 @@ void free_channel_desc_scm(channel_desc_t *ch);
\param module_id identifies the channel model. should be define as a macro in simu.h \param module_id identifies the channel model. should be define as a macro in simu.h
*/ */
void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id); void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id);
/**
\brief This function set a model name to a model descriptor, can be later used to identify a allocated channel model
\param cdesc points to the model descriptor
\param module_name is the C string to use as model name for the channel pointed by cdesc
*/
void set_channeldesc_name(channel_desc_t *cdesc,char *modelname);
/** \fn void random_channel(channel_desc_t *desc) /** \fn void random_channel(channel_desc_t *desc)
\brief This routine generates a random channel response (time domain) according to a tapped delay line model. \brief This routine generates a random channel response (time domain) according to a tapped delay line model.
\param desc Pointer to the channel descriptor \param desc Pointer to the channel descriptor
...@@ -454,11 +491,11 @@ void multipath_tv_channel(channel_desc_t *desc, ...@@ -454,11 +491,11 @@ void multipath_tv_channel(channel_desc_t *desc,
/**@} */ /**@} */
/**@} */ /**@} */
int modelid_fromname(char *modelname); int modelid_fromstrtype(char *modeltype);
double channelmod_get_snr_dB(void); double channelmod_get_snr_dB(void);
double channelmod_get_sinr_dB(void); double channelmod_get_sinr_dB(void);
void init_channelmod(void) ; void init_channelmod(void) ;
int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) ;
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);
......
...@@ -69,7 +69,9 @@ extern RAN_CONTEXT_t RC; ...@@ -69,7 +69,9 @@ extern RAN_CONTEXT_t RC;
#define RFSIMU_SECTION "rfsimulator" #define RFSIMU_SECTION "rfsimulator"
#define RFSIMU_OPTIONS_PARAMNAME "options" #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"\ " chanmod: enable channel modelisation\n"\
" saviq: enable saving written iqs to a file\n" " saviq: enable saving written iqs to a file\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
...@@ -78,21 +80,21 @@ extern RAN_CONTEXT_t RC; ...@@ -78,21 +80,21 @@ extern RAN_CONTEXT_t RC;
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED #define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
#define RFSIMULATOR_PARAMS_DESC { \ #define RFSIMULATOR_PARAMS_DESC { \
{"serveraddr", "<ip address to connect to>\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 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 },\ {"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 },\ {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 },\ {"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 },\ {"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 },\ {"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 },\ {"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 }\ {"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 int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
static telnetshell_cmddef_t rfsimu_cmdarray[] = { 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}, {"","",NULL},
}; };
...@@ -183,16 +185,9 @@ static void allocCirBuf(rfsimulator_state_t *bridge, int sock) { ...@@ -183,16 +185,9 @@ static void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
tableNor(rand); tableNor(rand);
init_done=true; init_done=true;
} }
char *modelname = (bridge->typeStamp == ENB_MAGICDL) ? "rfsimu_channel_ue0":"rfsimu_channel_enB0";
ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, ptr->channel_model=find_channel_desc_fromname(modelname); // path_loss in dB
bridge->channelmod, AssertFatal((ptr->channel_model!= NULL),"Channel model %s not found, check config file\n",modelname);
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,
bridge->noise_power_dB); // path_loss in dB
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID); set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
random_channel(ptr->channel_model,false); random_channel(ptr->channel_model,false);
} }
...@@ -301,7 +296,8 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { ...@@ -301,7 +296,8 @@ static 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();
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 { } 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]);
exit(-1); exit(-1);
...@@ -322,20 +318,27 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { ...@@ -322,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) { static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
char *modelname=NULL; 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) { if (s == 2) {
int channelmod=modelid_fromname(modelname); int channelmod=modelid_fromstrtype(modeltype);
if (channelmod<0) if (channelmod<0)
prnt("ERROR: model %s unknown\n",modelname); prnt("ERROR: model type %s unknown\n",modeltype);
else { else {
rfsimulator_state_t *t = (rfsimulator_state_t *)arg; rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
int found=0;
for (int i=0; i<FD_SETSIZE; i++) { for (int i=0; i<FD_SETSIZE; i++) {
buffer_t *b=&t->buf[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, channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels,
channelmod, channelmod,
t->sample_rate, t->sample_rate,
...@@ -343,23 +346,29 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, ...@@ -343,23 +346,29 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
30e-9, // TDL delay-spread parameter 30e-9, // TDL delay-spread parameter
t->chan_forgetfact, // forgetting_factor t->chan_forgetfact, // forgetting_factor
t->chan_offset, // maybe used for TA t->chan_offset, // maybe used for TA
t->chan_pathloss, t->chan_pathloss,
t->noise_power_dB t->noise_power_dB
); // path_loss in dB ); // path_loss in dB
set_channeldesc_owner(newmodel, RFSIMU_MODULEID); set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
set_channeldesc_name(newmodel,modelname);
random_channel(newmodel,false); random_channel(newmodel,false);
channel_desc_t *oldmodel=b->channel_model; channel_desc_t *oldmodel=b->channel_model;
b->channel_model=newmodel; b->channel_model=newmodel;
free_channel_desc_scm(oldmodel); 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 { } else {
prnt("ERROR: no model specified\n"); prnt("ERROR: 2 parameters required: model name and model type (%i found)\n",s);
} }
free(modelname); free(modelname);
free(modeltype);
return CMDSTATUS_FOUND; return CMDSTATUS_FOUND;
} }
...@@ -778,6 +787,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -778,6 +787,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// to change the log level, use this on command line // to change the log level, use this on command line
// --log_config.hw_log_level debug // --log_config.hw_log_level debug
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1); 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); rfsimulator_readconfig(rfsimulator);
pthread_mutex_init(&Sockmutex, NULL); 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"); 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");
...@@ -802,11 +816,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -802,11 +816,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->buf[i].conn_sock=-1; rfsimulator->buf[i].conn_sock=-1;
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -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); //randominit(0);
set_taus_seed(0); set_taus_seed(0);
/* look for telnet server, if it is loaded, add the channel modeling commands to it */ /* look for telnet server, if it is loaded, add the channel modeling commands to it */
......
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