Merge remote-tracking branch 'origin/beams-to-rf-board' into integration_2025_w52 (!3656)
Rfsimulator beam reception/transmission
A simplified beam switching simulation for rfsimulator. This works
mainly in 1 gNB - N UEs scenarios. This is not a real beamformer with
antenna, channel and propagation model. The way it works is that the
peers inform each other about the beams they transmit in, and on
reception before channel modelling, the beam data is combined based on
preconfigured rx_beam/tx_beam gain matrix.
Usage:
- Add --rfsimulator.enable_beams to enable beam simulation
- Add --rfsimulator.beam_gains .
Example list: 0,-5,-10
Resulting matrix:
[[0, -5, -10] [-5, 0, -5]] [-10, -5, 0]]
- Add --telnetsrv if you want to control the beams manually. The command
in telnet is "rfsimu setbeam <beam_map>", where beam_map is a uint64_t
controling the reception beam and transmission beam. If the
application is switching the beams automatically the beams will be
overwritten as soon as the application chooses to switch beams.
Supports up to 64 concurrent TX and RX beams.
This commit is contained in:
@@ -213,7 +213,7 @@ int config_check_unknown_cmdlineopt(configmodule_interface_t *cfg, char *prefix)
|
||||
return unknowndetected;
|
||||
} /* config_check_unknown_cmdlineopt */
|
||||
|
||||
int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix)
|
||||
int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, const char *prefix)
|
||||
{
|
||||
int c = cfg->argc;
|
||||
int i,j;
|
||||
|
||||
@@ -118,7 +118,7 @@ void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->iptr), 1);
|
||||
@@ -132,7 +132,7 @@ int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions,
|
||||
return status;
|
||||
}
|
||||
|
||||
int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->i64ptr), 1);
|
||||
@@ -150,7 +150,7 @@ int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoption
|
||||
return status;
|
||||
}
|
||||
|
||||
int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
@@ -167,7 +167,7 @@ int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgopti
|
||||
return status;
|
||||
}
|
||||
|
||||
int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
@@ -190,7 +190,7 @@ int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptio
|
||||
return status;
|
||||
}
|
||||
|
||||
int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
@@ -210,7 +210,7 @@ int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgo
|
||||
return status;
|
||||
}
|
||||
|
||||
int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->dblptr), 1);
|
||||
@@ -224,7 +224,7 @@ int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptio
|
||||
return status;
|
||||
}
|
||||
|
||||
int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *ipv4addr)
|
||||
int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *ipv4addr)
|
||||
{
|
||||
config_check_valptr(cfg, cfgoptions, sizeof(*cfgoptions->uptr), 1);
|
||||
int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr );
|
||||
@@ -246,7 +246,7 @@ int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix)
|
||||
int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
@@ -322,7 +322,7 @@ void config_assign_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, ch
|
||||
* @param[in] prefix Optional prefix for the parameter name (can be NULL).
|
||||
* @return 1 if the default value was set, 0 if ignored, or -1 on error/unsupported type.
|
||||
*/
|
||||
int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, char *prefix)
|
||||
int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, const char *prefix)
|
||||
{
|
||||
if( (cfgoption->paramflags & PARAMFLAG_DONOTREAD) != 0) {
|
||||
return 0;
|
||||
|
||||
@@ -41,16 +41,16 @@ extern "C"
|
||||
#endif
|
||||
void config_check_valptr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int elt_sz, int nb_elt);
|
||||
/* functions to set a parameter to its default value */
|
||||
int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *prefix);
|
||||
int config_setdefault_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
int config_setdefault_int64(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
int config_setdefault_intlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
int config_setdefault_string(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
int config_setdefault_stringlist(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
int config_setdefault_double(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
int config_setdefault_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *prefix);
|
||||
void *config_allocate_new(configmodule_interface_t *cfg, int sz, bool autoFree);
|
||||
void config_assign_int(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *fullname, int val);
|
||||
int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, char *prefix);
|
||||
int config_common_getdefault(configmodule_interface_t *cfg, paramdef_t *cfgoption, const char *prefix);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ int config_cmdlineonly_getlist(configmodule_interface_t *cfg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_cmdlineonly_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, char *prefix)
|
||||
int config_cmdlineonly_get(configmodule_interface_t *cfg, paramdef_t *cfgoptions, int numoptions, const char *prefix)
|
||||
{
|
||||
int defval;
|
||||
int fatalerror=0;
|
||||
|
||||
@@ -59,10 +59,10 @@
|
||||
#define CONFIG_ABORT (1<<21) // config failed,abort execution
|
||||
#define CONFIG_NOOOPT (1<<22) // no -O option found when parsing command line
|
||||
struct configmodule_interface;
|
||||
typedef int (*configmodule_getfunc_t)(struct configmodule_interface *, paramdef_t *, int numparams, char *prefix);
|
||||
typedef int (*configmodule_getfunc_t)(struct configmodule_interface *, paramdef_t *, int numparams, const char *prefix);
|
||||
typedef int (
|
||||
*configmodule_getlistfunc_t)(struct configmodule_interface *, paramlist_def_t *, paramdef_t *, int numparams, char *prefix);
|
||||
typedef int (*configmodule_setfunc_t)(paramdef_t *cfgoptions, int numoptions, char *prefix);
|
||||
typedef int (*configmodule_setfunc_t)(paramdef_t *cfgoptions, int numoptions, const char *prefix);
|
||||
typedef void (*configmodule_endfunc_t)(struct configmodule_interface *cfg);
|
||||
|
||||
typedef int (*configmodule_initfunc_t)(struct configmodule_interface *cfg);
|
||||
|
||||
@@ -105,7 +105,7 @@ typedef union checkedparam {
|
||||
#define DEFAULT_EXTRA_SZ 256
|
||||
typedef struct paramdef {
|
||||
char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */
|
||||
char *helpstr; /* help string */
|
||||
const char *helpstr; /* help string */
|
||||
unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */
|
||||
union { /* pointer to the parameter value, completed by the config module */
|
||||
char **strptr;
|
||||
@@ -122,7 +122,7 @@ typedef struct paramdef {
|
||||
void *voidptr;
|
||||
} ;
|
||||
union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */
|
||||
char *defstrval;
|
||||
const char *defstrval;
|
||||
char **defstrlistval;
|
||||
uint32_t defuintval;
|
||||
int defintval;
|
||||
@@ -161,6 +161,50 @@ typedef struct paramdef {
|
||||
#define TYPE_LIST 55
|
||||
|
||||
#define ANY_IPV4ADDR_STRING "0.0.0.0"
|
||||
|
||||
// Macros to simplify defining parameters in paramdef_t arrays in C++ source code
|
||||
#define OPTNAME(x) .optname = x
|
||||
#define HELPSTR(x) .helpstr = x
|
||||
#define PARAMFLAG(x) .paramflags = x
|
||||
#define PARAMTYPE(x) .type = x
|
||||
#define STRINGPARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .strptr = ptr, .defstrval = defval, PARAMTYPE(TYPE_STRING), .numelt = 0 \
|
||||
}
|
||||
#define DOUBLEPARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .dblptr = ptr, .defdblval = defval, PARAMTYPE(TYPE_DOUBLE), .numelt = 0 \
|
||||
}
|
||||
#define INTPARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .iptr = ptr, .defintval = defval, PARAMTYPE(TYPE_INT), .numelt = 0 \
|
||||
}
|
||||
#define UINT16PARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .u16ptr = ptr, .defuintval = defval, PARAMTYPE(TYPE_UINT16), .numelt = 0 \
|
||||
}
|
||||
#define STRLISTPARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .strlistptr = ptr, .defstrlistval = defval, PARAMTYPE(TYPE_STRINGLIST), \
|
||||
.numelt = 0 \
|
||||
}
|
||||
#define INT64PARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .i64ptr = ptr, .defint64val = defval, PARAMTYPE(TYPE_INT64), .numelt = 0 \
|
||||
}
|
||||
#define INTPARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .iptr = ptr, .defintval = defval, PARAMTYPE(TYPE_INT), .numelt = 0 \
|
||||
}
|
||||
#define BOOLPARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .iptr = ptr, .defintval = defval, PARAMTYPE(TYPE_INT), .numelt = 0 \
|
||||
}
|
||||
#define UINT64PARAM(name, help, flags, ptr, defval) \
|
||||
{ \
|
||||
OPTNAME(name), HELPSTR(help), PARAMFLAG(flags), .u64ptr = ptr, .defuintval = defval, PARAMTYPE(TYPE_UINT64), .numelt = 0 \
|
||||
}
|
||||
|
||||
typedef struct paramlist_def {
|
||||
char listname[MAX_OPTNAME_SIZE];
|
||||
paramdef_t **paramarray;
|
||||
|
||||
@@ -71,7 +71,7 @@ int config_get_processedint(configmodule_interface_t *cfg, paramdef_t *cfgoption
|
||||
|
||||
return ret;
|
||||
}
|
||||
void config_printhelp(paramdef_t *params,int numparams, char *prefix) {
|
||||
void config_printhelp(paramdef_t *params,int numparams, const char *prefix) {
|
||||
printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix,numparams);
|
||||
|
||||
for (int i=0 ; i<numparams ; i++) {
|
||||
@@ -84,7 +84,7 @@ void config_printhelp(paramdef_t *params,int numparams, char *prefix) {
|
||||
printf("--------------------------------------------------------------------\n\n");
|
||||
}
|
||||
|
||||
int config_execcheck(configmodule_interface_t *cfg, paramdef_t *params, int numparams, char *prefix)
|
||||
int config_execcheck(configmodule_interface_t *cfg, paramdef_t *params, int numparams, const char *prefix)
|
||||
{
|
||||
int st=0;
|
||||
|
||||
@@ -105,7 +105,7 @@ int config_execcheck(configmodule_interface_t *cfg, paramdef_t *params, int nump
|
||||
return st;
|
||||
}
|
||||
|
||||
int config_paramidx_fromname(paramdef_t *params, int numparams, char *name) {
|
||||
int config_paramidx_fromname(paramdef_t *params, int numparams, const char *name) {
|
||||
for (int i=0; i<numparams ; i++) {
|
||||
if (strcmp(name,params[i].optname) == 0)
|
||||
return i;
|
||||
@@ -115,7 +115,7 @@ int config_paramidx_fromname(paramdef_t *params, int numparams, char *name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int config_get(configmodule_interface_t *cfgif, paramdef_t *params, int numparams, char *prefix)
|
||||
int config_get(configmodule_interface_t *cfgif, paramdef_t *params, int numparams, const char *prefix)
|
||||
{
|
||||
int ret= -1;
|
||||
|
||||
|
||||
@@ -49,17 +49,17 @@ extern configmodule_interface_t *uniqCfg;
|
||||
#define CONFIG_SETRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags |= P; }
|
||||
#define CONFIG_CLEARRTFLAG(P) if (config_get_if()) { config_get_if()->rtflags &= (~P); }
|
||||
#define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F))
|
||||
int config_paramidx_fromname(paramdef_t *params, int numparams, char *name);
|
||||
int config_paramidx_fromname(paramdef_t *params, int numparams, const char *name);
|
||||
|
||||
/* utility functions, to be used by configuration module and/or configuration libraries */
|
||||
void config_printhelp(paramdef_t *, int numparams, char *prefix);
|
||||
int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *params, int numparams, char *prefix);
|
||||
int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, char *ipv4addr);
|
||||
void config_printhelp(paramdef_t *, int numparams, const char *prefix);
|
||||
int config_process_cmdline(configmodule_interface_t *cfg, paramdef_t *params, int numparams, const char *prefix);
|
||||
int config_assign_ipv4addr(configmodule_interface_t *cfg, paramdef_t *cfgoptions, const char *ipv4addr);
|
||||
|
||||
/* apis to get/check parameters, to be used by oai modules, at configuration time */
|
||||
#define CONFIG_CHECKALLSECTIONS "ALLSECTIONS"
|
||||
int config_check_unknown_cmdlineopt(configmodule_interface_t *cfg, char *prefix);
|
||||
int config_get(configmodule_interface_t *cfg, paramdef_t *params, int numparams, char *prefix);
|
||||
int config_get(configmodule_interface_t *cfg, paramdef_t *params, int numparams, const char *prefix);
|
||||
int config_getlist(configmodule_interface_t *cfg, paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix);
|
||||
|
||||
/* apis to set some of the paramdef_t fields before using the get/getlist api's */
|
||||
|
||||
@@ -411,7 +411,7 @@ TEST(yaml_config, test_read_ipv4) {
|
||||
config_yaml_get(cfg, &p, 1, prefix);
|
||||
printf("%x\n", addr);
|
||||
|
||||
p.defstrval = strdup("10.0.0.1");
|
||||
p.defstrval = "10.0.0.1";
|
||||
strncpy(p.optname, "ipv4_3", sizeof(p.optname) - 1);
|
||||
config_yaml_get(cfg, &p, 1, prefix);
|
||||
printf("%x\n", addr);
|
||||
@@ -419,7 +419,6 @@ TEST(yaml_config, test_read_ipv4) {
|
||||
config_yaml_end(cfg);
|
||||
free(cfg->cfgP[0]);
|
||||
end_configmodule(cfg);
|
||||
free(p.defstrval);
|
||||
}
|
||||
|
||||
TEST(yaml_config, yaml_read_str_as_int) {
|
||||
|
||||
@@ -252,7 +252,7 @@ load_module_shlib_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void * get_shlibmodule_fptr(char *modname, char *fname)
|
||||
void * get_shlibmodule_fptr(const char *modname, const char *fname)
|
||||
{
|
||||
for (int i=0; i<loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) {
|
||||
if ( strcmp(loader_data.shlibs[i].name, modname) == 0) {
|
||||
|
||||
@@ -82,7 +82,7 @@ extern loader_data_t loader_data;
|
||||
// clang-format on
|
||||
|
||||
int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *farray, int numf, void *initfunc_arg);
|
||||
void *get_shlibmodule_fptr(char *modname, char *fname);
|
||||
void *get_shlibmodule_fptr(const char *modname, const char *fname);
|
||||
#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
|
||||
void loader_reset();
|
||||
#endif
|
||||
|
||||
@@ -76,7 +76,7 @@ typedef struct webdatadef {
|
||||
typedef void(*telnet_printfunc_t)(const char* format, ...);
|
||||
typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt);
|
||||
typedef int (*webfunc_t)(char *cmdbuff, int debug, telnet_printfunc_t prnt, ...);
|
||||
typedef int (*webfunc_getdata_t)(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt);
|
||||
typedef int (*webfunc_getdata_t)(const char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt);
|
||||
typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg);
|
||||
|
||||
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1 << 0) // ask the telnet server to push the command in a thread pool queue
|
||||
@@ -195,7 +195,7 @@ VT escape sequence definition, for smarter display....
|
||||
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
|
||||
#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq"
|
||||
#define TELNET_PUSHCMD_FNAME "telnet_pushcmd"
|
||||
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
|
||||
typedef int(*add_telnetcmd_func_t)(const char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
|
||||
typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg);
|
||||
typedef void (*push_telnetcmd_func_t)(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
|
||||
#ifdef TELNETSERVERCODE
|
||||
|
||||
@@ -48,8 +48,8 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt);
|
||||
int get_modchannel_index(char *buf, int debug, void *vdata, telnet_printfunc_t prnt);
|
||||
int get_channel_params(char *buf, int debug, void *tdata, telnet_printfunc_t prnt);
|
||||
int get_currentchannels_type(char *buf, int debug, void *vdata, telnet_printfunc_t prnt);
|
||||
int get_channel_params(const char *buf, int debug, void *tdata, telnet_printfunc_t prnt);
|
||||
int get_currentchannels_type(const char *buf, int debug, void *vdata, telnet_printfunc_t prnt);
|
||||
|
||||
#define HELP_WEBIF_MODIFCHAN_STRING "<channel index>"
|
||||
static telnetshell_cmddef_t channelmod_cmdarray[] = {
|
||||
@@ -1696,7 +1696,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
return(chan_desc);
|
||||
} /* channel_desc_t *new_channel_desc_scm */
|
||||
|
||||
channel_desc_t *find_channel_desc_fromname( char *modelname ) {
|
||||
channel_desc_t *find_channel_desc_fromname(const char *modelname) {
|
||||
for(int i=0; i<max_chan; i++) {
|
||||
if (defined_channels[i] != NULL) {
|
||||
if (strcmp(defined_channels[i]->model_name,modelname) == 0)
|
||||
@@ -2029,7 +2029,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt
|
||||
|
||||
static char *pnames[] = {"riceanf", "aoa", "randaoa", "ploss", "noise_power_dB", "offset", "forgetf", NULL};
|
||||
static char *pformat[] = {"%lf", "%lf", "%i", "%lf", "%lf", "%i", "%lf", NULL};
|
||||
int get_channel_params(char *buf, int debug, void *vdata, telnet_printfunc_t prnt)
|
||||
int get_channel_params(const char *buf, int debug, void *vdata, telnet_printfunc_t prnt)
|
||||
{
|
||||
if (buf == NULL) {
|
||||
LOG_I(UTIL, "%s received NULL buffer\n", __FUNCTION__);
|
||||
@@ -2111,7 +2111,7 @@ static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_
|
||||
}
|
||||
}
|
||||
|
||||
int get_currentchannels_type(char *buf, int debug, void *vdata, telnet_printfunc_t prnt)
|
||||
int get_currentchannels_type(const char *buf, int debug, void *vdata, telnet_printfunc_t prnt)
|
||||
{
|
||||
webdatadef_t *tdata;
|
||||
if (buf == NULL) {
|
||||
|
||||
@@ -347,7 +347,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
|
||||
double path_loss_dB,
|
||||
float noise_power_dB);
|
||||
|
||||
channel_desc_t *find_channel_desc_fromname( char *modelname );
|
||||
channel_desc_t *find_channel_desc_fromname(const char *modelname);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -493,12 +493,29 @@ struct openair0_device_t {
|
||||
/*! \brief Called to send samples to the RF target
|
||||
@param device pointer to the device structure specific to the RF hardware target
|
||||
@param timestamp The timestamp at whicch the first sample MUST be sent
|
||||
@param buff Buffer which holds the samples (2 dimensional)
|
||||
@param buff Buffer which holds the samples (3 dimensional)
|
||||
@param nsamps number of samples to be sent
|
||||
@param number of antennas
|
||||
@param nb_antennas_tx number of antennas
|
||||
@param num_beams number of beams
|
||||
@param flags flags must be set to true if timestamp parameter needs to be applied
|
||||
*/
|
||||
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
|
||||
int (*trx_write_beams_func)(openair0_device *device,
|
||||
openair0_timestamp timestamp,
|
||||
void ***buff,
|
||||
int nsamps,
|
||||
int nb_antennas_tx,
|
||||
int num_beams,
|
||||
int flags);
|
||||
|
||||
/*! \brief Called to send samples to the RF target
|
||||
@param device pointer to the device structure specific to the RF hardware target
|
||||
@param timestamp The timestamp at whicch the first sample MUST be sent
|
||||
@param buff Buffer which holds the samples (2 dimensional)
|
||||
@param nsamps number of samples to be sent
|
||||
@param nb_antennas_tx number of antennas
|
||||
@param flags flags must be set to true if timestamp parameter needs to be applied
|
||||
*/
|
||||
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int nb_antennas_tx, int flags);
|
||||
|
||||
/*! \brief Called to send samples to the RF target
|
||||
@param device pointer to the device structure specific to the RF hardware target
|
||||
@@ -520,7 +537,27 @@ struct openair0_device_t {
|
||||
* antennas from which to receive samples \returns the number of sample read
|
||||
*/
|
||||
|
||||
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int num_antennas);
|
||||
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int num_antennas);
|
||||
|
||||
/*! \brief Receive samples from hardware.
|
||||
* Read nsamps samples from each channel to buffers. buff[0] is the array for
|
||||
* the first channel. *ptimestamp is the time at which the first sample
|
||||
* was received.
|
||||
* \param device the hardware to use
|
||||
* \param[out] ptimestamp the time at which the first sample was received.
|
||||
* \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of
|
||||
* samples nsamps.
|
||||
* \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
|
||||
* \param num_antennas number of antennas from which to receive samples
|
||||
* \param num_beams number of beams from which to receive samples
|
||||
* \returns the number of sample read
|
||||
*/
|
||||
int (*trx_read_beams_func)(openair0_device *device,
|
||||
openair0_timestamp *ptimestamp,
|
||||
void ***buff,
|
||||
int nsamps,
|
||||
int num_antennas,
|
||||
int num_beams);
|
||||
|
||||
/*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns.
|
||||
* Read nsamps samples from each channel to buffers. buff[0] is the array for
|
||||
@@ -573,6 +610,37 @@ struct openair0_device_t {
|
||||
*/
|
||||
int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg);
|
||||
|
||||
/*! \brief Set tx/rx beams
|
||||
*
|
||||
* Set the tx/rx beams. This has to be done in advance of the reception in order to
|
||||
* allow the underlying device to change receiver configuration. The exact time depends
|
||||
* on the device.
|
||||
*
|
||||
* NOTICE: the samples returned from trx_read_func may belong to more than one beam. It is up
|
||||
* to the application to determine the beam of the received samples.
|
||||
*
|
||||
* \param device the hardware to use
|
||||
* \param beam_map the beams to receive
|
||||
* \return 0 on success
|
||||
*/
|
||||
int (*trx_set_beams)(openair0_device *device, uint64_t beam_map, openair0_timestamp timestamp);
|
||||
|
||||
/*! \brief Set tx/rx beams
|
||||
*
|
||||
* Set the tx/rx beams. This has to be done in advance of the reception in order to
|
||||
* allow the underlying device to change receiver configuration. The exact time depends
|
||||
* on the device.
|
||||
*
|
||||
* NOTICE: the samples returned from trx_read_func may belong to more than one beam. It is up
|
||||
* to the application to determine the beam of the received samples.
|
||||
*
|
||||
* \param device the hardware to use
|
||||
* \param beams pointer to array of beam ids
|
||||
* \param num_beams number of beams
|
||||
* \return 0 on success
|
||||
*/
|
||||
int (*trx_set_beams2)(openair0_device *device, int* beams, int num_beams, openair0_timestamp timestamp);
|
||||
|
||||
/*! \brief RRU Configuration callback
|
||||
* \param idx RU index
|
||||
* \param arg pointer to capabilities or configuration
|
||||
@@ -631,6 +699,7 @@ typedef struct {
|
||||
uint64_t timestamp; // Timestamp value of first sample
|
||||
uint32_t option_value; // Option value
|
||||
uint32_t option_flag; // Option flag
|
||||
uint64_t beam_map;
|
||||
} samplesBlockHeader_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
add_library(rfsimulator MODULE
|
||||
simulator.c
|
||||
simulator.cpp
|
||||
apply_channelmod.c
|
||||
../../openair1/PHY/TOOLS/signal_energy.c
|
||||
)
|
||||
|
||||
@@ -209,3 +209,55 @@ to reduce the amount of transported samples:
|
||||
A possible, unimplemented optimization would be to compress samples.
|
||||
|
||||
You can further [tune your machine](../../doc/tuning_and_security.md)
|
||||
|
||||
# Beam simulation
|
||||
|
||||
RFsimulator supports beam domain simulation.
|
||||
|
||||
## Configuration
|
||||
|
||||
Several new CLI parameters were added
|
||||
|
||||
* `--rfsimulator.enable_beams` : enable beam domain simulation. Should match on server and all clients.
|
||||
* `--rfsimulator.beam_gains <comma separated list>` : define a matrix of additional pathloss values (in dB)
|
||||
to simulate the effect of different beam combinations in the RF simulator. You provide a comma-separated
|
||||
list of numbers, which forms the first row of a square matrix. The rest of the matrix is filled by projecting
|
||||
these values onto the diagonals, making it symmetric.
|
||||
|
||||
Example list: `0,-2,-3`
|
||||
Resulting matrix:
|
||||
```
|
||||
[[0,-2,-3],
|
||||
[-2,0,-2],
|
||||
[-3,-2,0]]
|
||||
```
|
||||
|
||||
The beam gain matrix will be used during beam combining. RX beam selects the row and TX beam selects column.
|
||||
Using the example above, if gNB is receiving in beam 1 and the UE is transmitting in beam 1, an additional
|
||||
2 dB pathloss will be applied on top of the pathloss from the channel model (if present).
|
||||
|
||||
* `--rfsimulator.beam_map <beam_map>` : where `<beam_map>` is a `uint64_t` value where each bit is an enabled TX/RX beam.
|
||||
For gNB: Initial beam_map, i.e. which beams gNB transmits/receives before calling beam APIs.
|
||||
For UE: Beam position in beam space in the simulation. The UE is not expected to use the beam APIs for now.
|
||||
* `--rfsimulator.beam_ids <beam_ids>` : where `<beam_ids>` is a comma separated list. Same as above but added for convenience.
|
||||
|
||||
## Runtime commands
|
||||
|
||||
### Moving the UE in beam space
|
||||
|
||||
Use telnet command `rfsimu setbeams <beam_map>` or `rfsimu setbeamids <beam_ids>`. They correspond to the CLI parameters described
|
||||
above and work the same way.
|
||||
|
||||
### Modifying the gNB beam
|
||||
|
||||
It is possible to test the beam domain simulation without implementing the beam APIs. The same telnet command can be used
|
||||
to modify the tx/rx beam of the gNB. The gNB does not need to be beam-aware and use the new APIs.
|
||||
|
||||
## Programming guide
|
||||
|
||||
RFsimulator is attempting to simulate hardware device operation, but there are differences. Like with real hardware,
|
||||
it is expected that you provide the configured beams in `set_beams` function ahead of sample reception. This is due
|
||||
to the fact that a hardware device will buffer received samples before the driver requests them.
|
||||
|
||||
For rfsimulator, as long as the call to `set_beams` with timestamp `n` is done before `trx_read` which is expected
|
||||
to return sample `n` the beam switch command will apply to the received samples.
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <complex.h>
|
||||
#include <common/utils/LOG/log.h>
|
||||
@@ -28,36 +27,17 @@
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_config.h"
|
||||
#include "rfsimulator.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(const c16_t *input_sig,
|
||||
cf_t *after_channel_sig,
|
||||
int rxAnt,
|
||||
channel_desc_t *channelDesc,
|
||||
int nbSamples,
|
||||
uint64_t TS,
|
||||
uint32_t CirSize,
|
||||
bool add_noise)
|
||||
void update_channel_model(channel_desc_t *channelDesc, uint64_t TS)
|
||||
{
|
||||
static uint64_t last_TS = 0;
|
||||
|
||||
if ((channelDesc->sat_height > 0) && (channelDesc->enable_dynamic_delay || channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit
|
||||
if ((channelDesc->sat_height > 0)
|
||||
&& (channelDesc->enable_dynamic_delay
|
||||
|| channelDesc->enable_dynamic_Doppler)) { // model for transparent satellite on circular orbit
|
||||
/* assumptions:
|
||||
- The Earth is spherical, the ground station is static, and that the Earth does not rotate.
|
||||
- An access or link is possible from the satellite to the ground station at all times.
|
||||
- The ground station is located at the North Pole (positive Zaxis), and the satellite starts from the initial elevation angle 0° in the second quadrant of the YZplane.
|
||||
- The ground station is located at the North Pole (positive Zaxis), and the satellite starts from the initial elevation angle
|
||||
0° in the second quadrant of the YZplane.
|
||||
- Satellite moves in the clockwise direction in its circular orbit.
|
||||
*/
|
||||
const double radius_earth = 6377900; // m
|
||||
@@ -78,7 +58,7 @@ void rxAddInput(const c16_t *input_sig,
|
||||
const double pos_sat_z = radius_sat * cos(w_sat * t);
|
||||
|
||||
const double vel_sat_x = 0;
|
||||
const double vel_sat_y = w_sat * radius_sat * cos(w_sat * t);
|
||||
const double vel_sat_y = w_sat * radius_sat * cos(w_sat * t);
|
||||
const double vel_sat_z = -w_sat * radius_sat * sin(w_sat * t);
|
||||
|
||||
const double pos_ue_x = 0;
|
||||
@@ -157,9 +137,17 @@ void rxAddInput(const c16_t *input_sig,
|
||||
if (channelDesc->enable_dynamic_Doppler)
|
||||
channelDesc->Doppler_phase_inc = 2 * M_PI * f_Doppler_shift_ue_sat / channelDesc->sampling_rate;
|
||||
|
||||
if(TS - last_TS >= channelDesc->sampling_rate) {
|
||||
if (TS - last_TS >= channelDesc->sampling_rate) {
|
||||
last_TS = TS;
|
||||
LOG_I(HW, "Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", t, pos_sat_x, pos_sat_y, pos_sat_z, vel_sat_x, vel_sat_y, vel_sat_z);
|
||||
LOG_I(HW,
|
||||
"Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n",
|
||||
t,
|
||||
pos_sat_x,
|
||||
pos_sat_y,
|
||||
pos_sat_z,
|
||||
vel_sat_x,
|
||||
vel_sat_y,
|
||||
vel_sat_z);
|
||||
LOG_I(HW, "Uplink delay %f ms, Doppler shift UE->SAT %f kHz\n", prop_delay * 1000, f_Doppler_shift_ue_sat / 1000);
|
||||
LOG_I(HW, "Satellite velocity towards gNB: %f m/s, acceleration towards gNB: %f m/s²\n", -vel_sat_gnb, acc_sat_gnb);
|
||||
}
|
||||
@@ -216,48 +204,70 @@ void rxAddInput(const c16_t *input_sig,
|
||||
if (channelDesc->enable_dynamic_Doppler)
|
||||
channelDesc->Doppler_phase_inc = 2 * M_PI * f_Doppler_shift_sat_ue / channelDesc->sampling_rate;
|
||||
|
||||
if(TS - last_TS >= channelDesc->sampling_rate) {
|
||||
if (TS - last_TS >= channelDesc->sampling_rate) {
|
||||
last_TS = TS;
|
||||
LOG_I(HW, "Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n", t, pos_sat_x, pos_sat_y, pos_sat_z, vel_sat_x, vel_sat_y, vel_sat_z);
|
||||
LOG_I(HW,
|
||||
"Satellite orbit: time %f s, Position = (%f, %f, %f), Velocity = (%f, %f, %f)\n",
|
||||
t,
|
||||
pos_sat_x,
|
||||
pos_sat_y,
|
||||
pos_sat_z,
|
||||
vel_sat_x,
|
||||
vel_sat_y,
|
||||
vel_sat_z);
|
||||
LOG_I(HW, "Downlink delay %f ms, Doppler shift SAT->UE %f kHz\n", prop_delay * 1000, f_Doppler_shift_sat_ue / 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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(c16_t **input_sig,
|
||||
cf_t *after_channel_sig,
|
||||
int rxAnt,
|
||||
channel_desc_t *channelDesc,
|
||||
int nbSamples,
|
||||
uint64_t TS)
|
||||
{
|
||||
// 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);
|
||||
const double pathLossLinear = pow(10, channelDesc->path_loss_dB / 20.0);
|
||||
// Energy in one sample to calibrate input noise
|
||||
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
|
||||
const double noise_per_sample = add_noise ? pow(10,channelDesc->noise_power_dB/10.0) * 256 : 0;
|
||||
const uint64_t dd = channelDesc->channel_offset;
|
||||
const int nbTx=channelDesc->nb_tx;
|
||||
const double noise_per_sample = pow(10, channelDesc->noise_power_dB / 10.0) * 256;
|
||||
const int nbTx = channelDesc->nb_tx;
|
||||
double Doppler_phase_cur = channelDesc->Doppler_phase_cur[rxAnt];
|
||||
Doppler_phase_cur -= 2 * M_PI * round(Doppler_phase_cur / (2 * M_PI));
|
||||
|
||||
for (int i=0; i<nbSamples; i++) {
|
||||
for (int i = 0; i < nbSamples; i++) {
|
||||
cf_t *out_ptr = after_channel_sig + i;
|
||||
struct complexd rx_tmp= {0};
|
||||
struct complexd rx_tmp = {0};
|
||||
|
||||
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
||||
const struct complexd *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)];
|
||||
for (int txAnt = 0; txAnt < nbTx; txAnt++) {
|
||||
const struct complexd *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
|
||||
// (X + cirSize) % cirSize to ensure that index is positive
|
||||
const int idx = ((TS + i - l - dd) * nbTx + txAnt + CirSize) % CirSize;
|
||||
const struct complex16 tx16 = input_sig[idx];
|
||||
// const struct complex *channelModelEnd=channelModel+channelDesc->channel_length;
|
||||
for (int l = 0; l < (int)channelDesc->channel_length; l++) {
|
||||
const int idx = i - l + channelDesc->channel_length - 1;
|
||||
const struct complex16 tx16 = input_sig[txAnt][idx];
|
||||
rx_tmp.r += tx16.r * channelModel[l].r - tx16.i * channelModel[l].i;
|
||||
rx_tmp.i += tx16.i * channelModel[l].r + tx16.r * channelModel[l].i;
|
||||
} //l
|
||||
} // l
|
||||
}
|
||||
|
||||
if (channelDesc->Doppler_phase_inc != 0.0) {
|
||||
@@ -279,12 +289,11 @@ void rxAddInput(const c16_t *input_sig,
|
||||
|
||||
channelDesc->Doppler_phase_cur[rxAnt] = Doppler_phase_cur;
|
||||
|
||||
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));
|
||||
// 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[0], nbSamples)),
|
||||
10 * log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)),
|
||||
channelDesc->path_loss_dB,
|
||||
10 * log10(noise_per_sample));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +1,34 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Author and copyright: Laurent Thomas, open-cells.com
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __RFSIMULATOR_H
|
||||
#define __RFSIMULATOR_H
|
||||
#define __RFSIMULATOR_H
|
||||
#include <stdbool.h>
|
||||
void rxAddInput( const c16_t *input_sig,
|
||||
cf_t *after_channel_sig,
|
||||
int rxAnt,
|
||||
channel_desc_t *channelDesc,
|
||||
int nbSamples,
|
||||
uint64_t TS,
|
||||
uint32_t CirSize,
|
||||
bool apply_noise
|
||||
);
|
||||
|
||||
void rxAddInput(c16_t **input_sig,
|
||||
cf_t *after_channel_sig,
|
||||
int rxAnt,
|
||||
channel_desc_t *channelDesc,
|
||||
int nbSamples,
|
||||
uint64_t TS);
|
||||
void update_channel_model(channel_desc_t *channelDesc, uint64_t TS);
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -548,6 +548,18 @@ static int vrtsim_write(openair0_device *device, openair0_timestamp timestamp, v
|
||||
: vrtsim_write_internal(vrtsim_state, timestamp, (c16_t *)samplesVoid[0], nsamps, 0, flags, 0);
|
||||
}
|
||||
|
||||
static int vrtsim_write_beams(openair0_device *device,
|
||||
openair0_timestamp timestamp,
|
||||
void ***buff,
|
||||
int nsamps,
|
||||
int nb_antennas_tx,
|
||||
int num_beams,
|
||||
int flags)
|
||||
{
|
||||
vrtsim_write(device, timestamp, (void **)buff[0], nsamps, nb_antennas_tx, flags);
|
||||
return nsamps;
|
||||
}
|
||||
|
||||
static int vrtsim_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt)
|
||||
{
|
||||
vrtsim_state_t *vrtsim_state = (vrtsim_state_t *)device->priv;
|
||||
@@ -657,6 +669,16 @@ static int vrtsim_set_freq(openair0_device *device, openair0_config_t *openair0_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vrtsim_set_beams(openair0_device *device, uint64_t beam_map, openair0_timestamp timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vrtsim_set_beams2(openair0_device *device, int *beam_ids, int num_beams, openair0_timestamp timestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((__visibility__("default"))) int device_init(openair0_device *device, openair0_config_t *openair0_cfg)
|
||||
{
|
||||
randominit();
|
||||
@@ -673,6 +695,9 @@ __attribute__((__visibility__("default"))) int device_init(openair0_device *devi
|
||||
device->trx_set_gains_func = vrtsim_stub2;
|
||||
device->trx_write_func = vrtsim_write;
|
||||
device->trx_read_func = vrtsim_read;
|
||||
device->trx_write_beams_func = vrtsim_write_beams;
|
||||
device->trx_set_beams = vrtsim_set_beams;
|
||||
device->trx_set_beams2 = vrtsim_set_beams2;
|
||||
|
||||
device->type = RFSIMULATOR;
|
||||
device->openair0_cfg = &openair0_cfg[0];
|
||||
|
||||
Reference in New Issue
Block a user