Commit 470ecad2 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge remote-tracking branch 'origin/add_chansimuparams' into develop_integration_2020_w31

parents e83acab6 d4bd2cdc
...@@ -2478,8 +2478,8 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_ ...@@ -2478,8 +2478,8 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_
target_link_libraries(enbscope ${XFORMS_LIBRARIES}) target_link_libraries(enbscope ${XFORMS_LIBRARIES})
target_link_libraries(uescope ${XFORMS_LIBRARIES}) target_link_libraries(uescope ${XFORMS_LIBRARIES})
add_library(gnbscope MODULE ${XFORMS_SOURCE_NR}) add_library(nrscope MODULE ${XFORMS_SOURCE_NR})
target_link_libraries(gnbscope ${XFORMS_LIBRARIES}) target_link_libraries(nrscope ${XFORMS_LIBRARIES})
add_library(rfsimulator MODULE add_library(rfsimulator MODULE
...@@ -2735,7 +2735,7 @@ add_executable(nr-softmodem ...@@ -2735,7 +2735,7 @@ add_executable(nr-softmodem
${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${GTPU_need_ITTI} ${GTPU_need_ITTI}
${XFORMS_SOURCE_NR} ${XFORMSINTERFACE_SOURCE}
${T_SOURCE} ${T_SOURCE}
${CONFIG_SOURCES} ${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES} ${SHLIB_LOADER_SOURCES}
...@@ -2777,7 +2777,7 @@ add_executable(nr-uesoftmodem ...@@ -2777,7 +2777,7 @@ add_executable(nr-uesoftmodem
${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c
${XFORMS_SOURCE_NR} ${XFORMSINTERFACE_SOURCE}
${T_SOURCE} ${T_SOURCE}
${UTIL_SRC} ${UTIL_SRC}
${CONFIG_SOURCES} ${CONFIG_SOURCES}
......
...@@ -67,7 +67,7 @@ UE_TIMING_TRACE="False" ...@@ -67,7 +67,7 @@ UE_TIMING_TRACE="False"
USRP_REC_PLAY="False" USRP_REC_PLAY="False"
BUILD_ECLIPSE=0 BUILD_ECLIPSE=0
NR="False" NR="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope msc" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc"
trap handle_ctrl_c INT trap handle_ctrl_c INT
function print_help() { function print_help() {
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#include "common/utils/load_module_shlib.h" #include "common/utils/load_module_shlib.h"
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
#include "common/utils/threadPool/thread-pool.h"
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include <readline/history.h> #include <readline/history.h>
...@@ -507,12 +508,22 @@ int process_command(char *buf) { ...@@ -507,12 +508,22 @@ int process_command(char *buf) {
} }
rt= CMDSTATUS_FOUND; rt= CMDSTATUS_FOUND;
} else if (strncasecmp(cmd,"get",3) == 0 || strncasecmp(cmd,"set",3) == 0) { } else if (strcasecmp(cmd,"get") == 0 || strcasecmp(cmd,"set") == 0) {
rt= setgetvar(i,cmd[0],cmdb); rt= setgetvar(i,cmd[0],cmdb);
} else { } else {
for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) { for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) {
if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) { if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) {
if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) {
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
cmddata->prnt=client_printf;
cmddata->debug=telnetparams.telnetdbg;
cmddata->cmdbuff=strdup(cmdb);
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
} else {
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf); telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
}
rt= CMDSTATUS_FOUND; rt= CMDSTATUS_FOUND;
} }
} /* for k */ } /* for k */
...@@ -673,6 +684,16 @@ void run_telnetsrv(void) { ...@@ -673,6 +684,16 @@ void run_telnetsrv(void) {
return; return;
} }
void poll_telnetcmdq(void *qid, void *arg) {
notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid);
if (msg != NULL) {
telnetsrv_qmsg_t *msgdata=NotifiedFifoData(msg);
msgdata->cmdfunc(msgdata->cmdbuff,msgdata->debug,msgdata->prnt,arg);
free(msgdata->cmdbuff);
delNotifiedFIFO_elt(msg);
}
}
/*------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------*/
/* load the commands delivered with the telnet server /* load the commands delivered with the telnet server
* *
...@@ -758,6 +779,7 @@ int telnetsrv_autoinit(void) { ...@@ -758,6 +779,7 @@ int telnetsrv_autoinit(void) {
*/ */
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) { int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) {
int i; int i;
notifiedFIFO_t *afifo=NULL;
if( modulename == NULL || var == NULL || cmd == NULL) { if( modulename == NULL || var == NULL || cmd == NULL) {
fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n"); fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
...@@ -769,6 +791,13 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde ...@@ -769,6 +791,13 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1); strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
telnetparams.CmdParsers[i].cmd = cmd; telnetparams.CmdParsers[i].cmd = cmd;
telnetparams.CmdParsers[i].var = var; telnetparams.CmdParsers[i].var = var;
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
if (afifo == NULL) {
afifo = malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(afifo);
}
cmd->qptr = afifo;
}
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
i,telnetparams.CmdParsers[i].module); i,telnetparams.CmdParsers[i].module);
break; break;
...@@ -797,8 +826,10 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers ...@@ -797,8 +826,10 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers
} }
int telnetsrv_getfarray(loader_shlibfunc_t **farray) { int telnetsrv_getfarray(loader_shlibfunc_t **farray) {
*farray=malloc(sizeof(loader_shlibfunc_t)); *farray=malloc(sizeof(loader_shlibfunc_t)*2);
(*farray)[0].fname=TELNET_ADDCMD_FNAME; (*farray)[0].fname=TELNET_ADDCMD_FNAME;
(*farray)[0].fptr=(int (*)(void) )add_telnetcmd; (*farray)[0].fptr=(int (*)(void) )add_telnetcmd;
return 1; (*farray)[1].fname=TELNET_POLLCMDQ_FNAME;
(*farray)[1].fptr=(int (*)(void) )poll_telnetcmdq;
return ( 2);
} }
...@@ -53,13 +53,26 @@ ...@@ -53,13 +53,26 @@
/* to add a set of new command to the telnet server shell */ /* to add a set of new command to the telnet server shell */
typedef void(*telnet_printfunc_t)(const char* format, ...); typedef void(*telnet_printfunc_t)(const char* format, ...);
typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt); typedef int(*cmdfunc_t)(char*, int, 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
typedef struct cmddef { typedef struct cmddef {
char cmdname[TELNET_CMD_MAXSIZE]; char cmdname[TELNET_CMD_MAXSIZE];
char helpstr[TELNET_HELPSTR_SIZE]; char helpstr[TELNET_HELPSTR_SIZE];
cmdfunc_t cmdfunc; cmdfunc_t cmdfunc;
unsigned int cmdflags;
void *qptr;
} telnetshell_cmddef_t; } telnetshell_cmddef_t;
/*----------------------------------------------------------------------------*/
/* structure used to send a command via a message queue to enable */
/* executing a command in a thread different from the telnet server thread */
typedef struct telnetsrv_qmsg {
qcmdfunc_t cmdfunc;
telnet_printfunc_t prnt;
int debug;
char *cmdbuff;
} telnetsrv_qmsg_t;
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/*structure to be used when adding a module to the telnet server */ /*structure to be used when adding a module to the telnet server */
/* This is the first parameter of the add_telnetcmd function, which can be used */ /* This is the first parameter of the add_telnetcmd function, which can be used */
...@@ -111,9 +124,6 @@ typedef struct { ...@@ -111,9 +124,6 @@ typedef struct {
} telnetsrv_params_t; } telnetsrv_params_t;
typedef int(*addcmdfunc_t)(char*, telnetshell_vardef_t*, telnetshell_cmddef_t*);
typedef void(*settelnetmodule_t)(char *name, void *ptr); typedef void(*settelnetmodule_t)(char *name, void *ptr);
/*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/
...@@ -133,7 +143,9 @@ VT escape sequence definition, for smarter display.... ...@@ -133,7 +143,9 @@ VT escape sequence definition, for smarter display....
/*---------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------*/
#define TELNET_ADDCMD_FNAME "add_telnetcmd" #define TELNET_ADDCMD_FNAME "add_telnetcmd"
#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq"
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg);
#ifdef TELNETSERVERCODE #ifdef TELNETSERVERCODE
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
void set_sched(pthread_t tid, int pid,int priority); void set_sched(pthread_t tid, int pid,int priority);
......
...@@ -75,7 +75,7 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -75,7 +75,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "system.h" #include "system.h"
#include <openair2/GNB_APP/gnb_app.h> #include <openair2/GNB_APP/gnb_app.h>
#include "PHY/TOOLS/phy_scope_interface.h"
#include "PHY/TOOLS/nr_phy_scope.h" #include "PHY/TOOLS/nr_phy_scope.h"
#include "stats.h" #include "stats.h"
#include "nr-softmodem.h" #include "nr-softmodem.h"
...@@ -156,7 +156,6 @@ char channels[128] = "0"; ...@@ -156,7 +156,6 @@ char channels[128] = "0";
int rx_input_level_dBm; int rx_input_level_dBm;
uint32_t do_forms=0;
int otg_enabled; int otg_enabled;
//int number_of_cards = 1; //int number_of_cards = 1;
...@@ -454,7 +453,11 @@ static void get_options(void) { ...@@ -454,7 +453,11 @@ static void get_options(void) {
paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
get_common_options(SOFTMODEM_GNB_BIT );
config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
...@@ -817,7 +820,6 @@ int main( int argc, char **argv ) ...@@ -817,7 +820,6 @@ int main( int argc, char **argv )
configure_linux(); configure_linux();
printf("Reading in command-line options\n"); printf("Reading in command-line options\n");
get_options (); get_options ();
get_common_options(SOFTMODEM_GNB_BIT );
if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) {
fprintf(stderr,"Getting configuration failed\n"); fprintf(stderr,"Getting configuration failed\n");
...@@ -959,14 +961,14 @@ if(!IS_SOFTMODEM_NOS1) ...@@ -959,14 +961,14 @@ if(!IS_SOFTMODEM_NOS1)
printf("RC.nb_RU:%d\n", RC.nb_RU); printf("RC.nb_RU:%d\n", RC.nb_RU);
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
printf("ALL RUs ready - init gNBs\n"); printf("ALL RUs ready - init gNBs\n");
if(IS_SOFTMODEM_DOFORMS) {
if (do_forms==1) {
scopeParms_t p; scopeParms_t p;
p.argc=&argc; p.argc=&argc;
p.argv=argv; p.argv=argv;
p.gNB=RC.gNB[0]; p.gNB=RC.gNB[0];
p.ru=RC.ru[0]; p.ru=RC.ru[0];
gNBinitScope(&p); load_softscope("nr",&p);
} }
if (nfapi_mode != 1 && nfapi_mode != 2) { if (nfapi_mode != 1 && nfapi_mode != 2) {
......
...@@ -19,21 +19,12 @@ ...@@ -19,21 +19,12 @@
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC_GNB { \ #define CMDLINE_PARAMS_DESC_GNB { \
{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
{"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
} }
......
...@@ -78,6 +78,9 @@ unsigned short config_frames[4] = {2,9,11,13}; ...@@ -78,6 +78,9 @@ unsigned short config_frames[4] = {2,9,11,13};
/* Callbacks, globals and object handlers */ /* Callbacks, globals and object handlers */
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
#include "PHY/TOOLS/phy_scope_interface.h"
#include "PHY/TOOLS/nr_phy_scope.h" #include "PHY/TOOLS/nr_phy_scope.h"
#include <executables/nr-uesoftmodem.h> #include <executables/nr-uesoftmodem.h>
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
...@@ -148,14 +151,11 @@ char ref[128] = "internal"; ...@@ -148,14 +151,11 @@ char ref[128] = "internal";
char channels[128] = "0"; char channels[128] = "0";
static char *parallel_config = NULL;
static char *worker_config = NULL;
int rx_input_level_dBm; int rx_input_level_dBm;
//static int online_log_messages=0; //static int online_log_messages=0;
uint32_t do_forms=0;
int otg_enabled; int otg_enabled;
//int number_of_cards = 1; //int number_of_cards = 1;
...@@ -758,8 +758,10 @@ int main( int argc, char **argv ) { ...@@ -758,8 +758,10 @@ int main( int argc, char **argv ) {
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
configure_linux(); configure_linux();
mlockall(MCL_CURRENT | MCL_FUTURE); mlockall(MCL_CURRENT | MCL_FUTURE);
if (do_forms)
nrUEinitScope(PHY_vars_UE_g[0][0]); if(IS_SOFTMODEM_DOFORMS) {
load_softscope("nr",PHY_vars_UE_g[0][0]);
}
number_of_cards = 1; number_of_cards = 1;
for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
......
...@@ -61,19 +61,11 @@ ...@@ -61,19 +61,11 @@
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0,TYPE_UINT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_INT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0}, \
{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \
{"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, 0, iptr:&numerology, defintval:0, TYPE_INT, 0}, \
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)&parallel_config, defstrval:NULL, TYPE_STRING, 0}, \
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0}, \
{"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \ {"ue-timing-correction-disable", CONFIG_HLP_DISABLETIMECORR, PARAMFLAG_BOOL, iptr:&UE_no_timing_correction, defintval:0, TYPE_INT, 0}, \
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "nr_phy_scope.h" #include "nr_phy_scope.h"
#include "executables/nr-softmodem-common.h" #include "executables/nr-softmodem-common.h"
#include "executables/softmodem-common.h"
#include <forms.h> #include <forms.h>
#define TPUT_WINDOW_LENGTH 100 #define TPUT_WINDOW_LENGTH 100
...@@ -768,6 +769,15 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) { ...@@ -768,6 +769,15 @@ void nrUEinitScope(PHY_VARS_NR_UE *ue) {
threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW); threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
} }
void nrscope_autoinit(void *dataptr) {
AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context");
if (IS_SOFTMODEM_GNB_BIT)
gNBinitScope(dataptr);
else
nrUEinitScope(dataptr);
}
// Kept to put back the functionality soon // Kept to put back the functionality soon
#if 0 #if 0
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
...@@ -795,6 +805,8 @@ static void reset_stats_gNB(FL_OBJECT *button, ...@@ -795,6 +805,8 @@ static void reset_stats_gNB(FL_OBJECT *button,
} }
} }
static FD_stats_form *create_form_stats_form(int ID) { static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj; FL_OBJECT *obj;
FD_stats_form *fdui = calloc(( sizeof *fdui ),1); FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
......
...@@ -40,8 +40,6 @@ typedef struct { ...@@ -40,8 +40,6 @@ typedef struct {
PHY_VARS_gNB *gNB; PHY_VARS_gNB *gNB;
} scopeParms_t; } scopeParms_t;
void gNBinitScope(scopeParms_t *p);
void nrUEinitScope(PHY_VARS_NR_UE *ue);
extern RAN_CONTEXT_t RC; extern RAN_CONTEXT_t RC;
#endif #endif
...@@ -37,10 +37,10 @@ ...@@ -37,10 +37,10 @@
#define SOFTSCOPE_ENDFUNC_IDX 0 #define SOFTSCOPE_ENDFUNC_IDX 0
static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}}; static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}};
int load_softscope(char *exectype) { int load_softscope(char *exectype, void *initarg) {
char libname[64]; char libname[64];
sprintf(libname,"%.10sscope",exectype); sprintf(libname,"%.10sscope",exectype);
return load_module_shlib(libname,scope_fdesc,1,NULL); return load_module_shlib(libname,scope_fdesc,1,initarg);
} }
int end_forms(void) { int end_forms(void) {
......
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
*/ */
int load_softscope(char *exectype); int load_softscope(char *exectype, void *initarg);
int end_forms(void) ; int end_forms(void) ;
...@@ -45,8 +45,12 @@ static mapping channelmod_names[] = { ...@@ -45,8 +45,12 @@ static mapping channelmod_names[] = {
}; };
static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); 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);
static telnetshell_cmddef_t channelmod_cmdarray[] = { static telnetshell_cmddef_t channelmod_cmdarray[] = {
{"show","",channelmod_show_cmd}, {"help","",channelmod_print_help},
{"show","<predef,current>",channelmod_show_cmd},
{"modify","<channelid> <param> <value>",channelmod_modify_cmd},
{"","",NULL}, {"","",NULL},
}; };
...@@ -56,7 +60,8 @@ static telnetshell_vardef_t channelmod_vardef[] = { ...@@ -56,7 +60,8 @@ 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 channel_desc_t** defined_channels;
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,
...@@ -88,6 +93,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, ...@@ -88,6 +93,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
if (delays==NULL) { if (delays==NULL) {
chan_desc->delays = (double *) malloc(nb_taps*sizeof(double)); chan_desc->delays = (double *) malloc(nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_DELAY ;
delta_tau = Td/nb_taps; delta_tau = Td/nb_taps;
for (i=0; i<nb_taps; i++) for (i=0; i<nb_taps; i++)
...@@ -129,10 +135,9 @@ void fill_channel_desc(channel_desc_t *chan_desc, ...@@ -129,10 +135,9 @@ void fill_channel_desc(channel_desc_t *chan_desc,
if (R_sqrt == NULL) { if (R_sqrt == NULL) {
chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_NTAPS ;
for (i = 0; i<nb_taps; i++) { for (i = 0; i<nb_taps; i++) {
chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) { for (j = 0; j<nb_tx*nb_rx*nb_tx*nb_rx; j+=(nb_tx*nb_rx+1)) {
chan_desc->R_sqrt[i][j].x = 1.0; chan_desc->R_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0; chan_desc->R_sqrt[i][j].y = 0.0;
...@@ -280,11 +285,23 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -280,11 +285,23 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
double path_loss_dB) { double path_loss_dB) {
channel_desc_t *chan_desc = (channel_desc_t *)malloc(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++) {
if (defined_channels[i] == NULL) {
defined_channels[i]=chan_desc;
chan_desc->chan_idx=i;
break;
}
else {
AssertFatal(i<(max_chan-1),
"No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan);
}
}
uint16_t i,j; uint16_t i,j;
double sum_amps; double sum_amps;
double aoa,ricean_factor,Td,maxDoppler; double aoa,ricean_factor,Td,maxDoppler;
int channel_length,nb_taps; int channel_length,nb_taps;
chan_desc->modelid = channel_model;
chan_desc->nb_tx = nb_tx; chan_desc->nb_tx = nb_tx;
chan_desc->nb_rx = nb_rx; chan_desc->nb_rx = nb_rx;
chan_desc->sampling_rate = sampling_rate; chan_desc->sampling_rate = sampling_rate;
...@@ -313,7 +330,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -313,7 +330,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -351,6 +368,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -351,6 +368,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<6; i++) for (i = 0; i<6; i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else { } else {
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) { for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
...@@ -372,7 +390,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -372,7 +390,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -410,6 +428,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -410,6 +428,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<6; i++) for (i = 0; i<6; i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else { } else {
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) { for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
...@@ -430,7 +449,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -430,7 +449,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -463,7 +482,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -463,7 +482,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else { } else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) { for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
...@@ -484,7 +503,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -484,7 +503,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -538,7 +557,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -538,7 +557,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -592,7 +611,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -592,7 +611,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -646,7 +665,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -646,7 +665,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -679,7 +698,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -679,7 +698,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else { } else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) { for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
...@@ -700,7 +719,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -700,7 +719,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -733,7 +752,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -733,7 +752,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
} else { } else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
for (i = 0; i<6; i++) { for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
...@@ -754,7 +773,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -754,7 +773,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0; sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
for (i = 0; i<chan_desc->nb_taps; i++) { for (i = 0; i<chan_desc->nb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]);
sum_amps += chan_desc->amps[i]; sum_amps += chan_desc->amps[i];
...@@ -781,7 +800,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -781,7 +800,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *)); chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6;
for (i = 0; i<6; i++) { for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
...@@ -1295,9 +1314,36 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -1295,9 +1314,36 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
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;
if(ch->free_flags&CHANMODEL_FREE_AMPS)
free(ch->amps);
for (int i = 0; i<ch->nb_tx*ch->nb_rx; i++) {
free(ch->ch[i]);
free(ch->chF[i]);
}
for (int i = 0; i<ch->nb_taps; i++) {
free(ch->a[i]);
}
if(ch->free_flags&CHANMODEL_FREE_DELAY)
free(ch->delays);
if(ch->free_flags&CHANMODEL_FREE_RSQRT_6)
for (int i = 0; i<6; i++)
free(ch->R_sqrt[i]);
if(ch->free_flags&CHANMODEL_FREE_RSQRT_NTAPS)
for (int i = 0; i<ch->nb_taps;i++)
free(ch->R_sqrt[i]);
free(ch->R_sqrt);
free(ch->ch);
free(ch->chF);
free(ch->a);
free(ch); free(ch);
} }
void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) {
cdesc->module_id=module_id;
}
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;
...@@ -1408,11 +1454,11 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { ...@@ -1408,11 +1454,11 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
desc->ch[aarx+(aatx*desc->nb_rx)][k].y = 0.0; desc->ch[aarx+(aatx*desc->nb_rx)][k].y = 0.0;
for (l=0; l<desc->nb_taps; l++) { for (l=0; l<desc->nb_taps; l++) {
if ((k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET) == 0) if ((k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset) == 0)
s = 1.0; s = 1.0;
else else
s = sin(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET))/ s = sin(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset))/
(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET)); (M_PI*(k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset));
desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x; desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x;
desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y; desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y;
...@@ -1488,22 +1534,125 @@ double N_RB2channel_bandwidth(uint16_t N_RB) { ...@@ -1488,22 +1534,125 @@ double N_RB2channel_bandwidth(uint16_t N_RB) {
LOG_E(PHY,"Unknown N_PRB\n"); LOG_E(PHY,"Unknown N_PRB\n");
return(-1); return(-1);
} }
return(channel_bandwidth); return(channel_bandwidth);
} }
static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ) {
prnt("channelmod commands can be used to display or modify channel models parameters\n");
prnt("channelmod show predef: display predefined model algorithms available in oai\n");
prnt("channelmod show current: display the currently used models in the running executable\n");
prnt("channelmod modify <model index> <param name> <param value>: set the specified parameters in a current model to the given value\n");
prnt(" <model index> specifies the model, the show current model command can be used to list the current models indexes\n");
prnt(" <param name> can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"offset\", \"forgetf\"\n");
return CMDSTATUS_FOUND;
}
static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) {
char *module_id_str[]=MODULEID_STR_INIT;
if (cd->module_id != 0) {
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("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"));
prnt("max Doppler: %lf path loss: %lf rchannel offset: %i forget factor; %lf\n",
cd->max_Doppler, cd->path_loss_dB, cd->channel_offset, cd->forgetting_factor);
prnt("Initial phase: %lf nb_path: %i \n",
cd->ip, cd->nb_paths);
for (int i=0; i<cd->nb_taps ; i++) {
prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]);
}
}
static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
for(int i=0; channelmod_names[i].name != NULL ; i++) { char *subcmd=NULL;
int s = sscanf(buff,"%ms\n",&subcmd);
if (s>0) {
if ( strcmp(subcmd,"predef") == 0) {
for (int i=0; channelmod_names[i].name != NULL ; i++) {
prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i )); prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i ));
} }
} else if ( strcmp(subcmd,"current") == 0) {
for (int i=0; i < max_chan ; i++) {
if (defined_channels[i] != NULL) {
prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid));
display_channelmodel(defined_channels[i],debug,prnt);
}
}
} else {
channelmod_print_help(buff, debug, prnt);
}
free(subcmd);
}
return CMDSTATUS_FOUND;
}
return 0;
static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
char *param=NULL, *value=NULL;
int cd_id= -1;
int s = sscanf(buff,"%i %ms %ms \n",&cd_id,&param, &value);
if (cd_id<0 || cd_id >= max_chan) {
prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1);
return CMDSTATUS_FOUND;
}
if (defined_channels[cd_id]==NULL) {
prnt("ERROR, %i: Channel model has not been set\n",cd_id);
return CMDSTATUS_FOUND;
}
if (s==3) {
if ( strcmp(param,"riceanf") == 0) {
double dbl = atof(value);
if (dbl <0 || dbl > 1)
prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl);
else
defined_channels[cd_id]->ricean_factor=dbl;
} else if ( strcmp(param,"aoa") == 0) {
double dbl = atof(value);
if (dbl <0 || dbl >6.28)
prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl);
else
defined_channels[cd_id]->aoa=dbl;
} else if ( strcmp(param,"randaoa") == 0) {
int i = atoi(value);
if (i!=0 && i!=1)
prnt("ERROR: randaoa is a boolean, must be 0 or 1\n");
else
defined_channels[cd_id]->random_aoa=i;
} else if ( strcmp(param,"ploss") == 0) {
double dbl = atof(value);
defined_channels[cd_id]->path_loss_dB=dbl;
} else if ( strcmp(param,"offset") == 0) {
int i = atoi(value);
defined_channels[cd_id]->channel_offset=i;
} else if ( strcmp(param,"forgetf") == 0) {
double dbl = atof(value);
if (dbl <0 || dbl > 1)
prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl);
else
defined_channels[cd_id]->forgetting_factor=dbl;
} else {
prnt("ERROR: %s, unknown channel parameter\n",param);
return CMDSTATUS_FOUND;
}
display_channelmodel(defined_channels[cd_id],debug,prnt);
free(param);
free(value);
random_channel(defined_channels[cd_id],false);
}
return CMDSTATUS_FOUND;
} }
int modelid_fromname(char *modelname) { int modelid_fromname(char *modelname) {
int modelid=map_str_to_int(channelmod_names,modelname); int modelid=map_str_to_int(channelmod_names,modelname);
AssertFatal(modelid>0, if (modelid < 0)
"random_channel.c: Error channel model %s unknown\n",modelname); LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname);
return modelid; return modelid;
} }
...@@ -1519,6 +1668,9 @@ void init_channelmod(void) { ...@@ -1519,6 +1668,9 @@ 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 ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),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*));
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);
......
...@@ -40,6 +40,16 @@ The present clause specifies several numerical functions for testing of digital ...@@ -40,6 +40,16 @@ The present clause specifies several numerical functions for testing of digital
#define NB_SAMPLES_CHANNEL_OFFSET 4 #define NB_SAMPLES_CHANNEL_OFFSET 4
typedef enum {
UNSPECIFIED_MODID=0,
RFSIMU_MODULEID=1
} channelmod_moduleid_t;
#define MODULEID_STR_INIT {"","rfsimulator"}
#define CHANMODEL_FREE_DELAY 1<<0
#define CHANMODEL_FREE_RSQRT_6 1<<1
#define CHANMODEL_FREE_RSQRT_NTAPS 1<<2
#define CHANMODEL_FREE_AMPS 1<<3
typedef struct { typedef struct {
///Number of tx antennas ///Number of tx antennas
uint8_t nb_tx; uint8_t nb_tx;
...@@ -92,6 +102,14 @@ typedef struct { ...@@ -92,6 +102,14 @@ typedef struct {
time_stats_t interp_time; time_stats_t interp_time;
time_stats_t interp_freq; time_stats_t interp_freq;
time_stats_t convolution; time_stats_t convolution;
/// index in the channel descriptors array
unsigned int chan_idx;
/// id of the channel modeling algorithm
int modelid;
/// identifies channel descriptor owner (the module which created this descriptor)
channelmod_moduleid_t module_id;
/// flags to properly trigger memory free
unsigned int free_flags;
} channel_desc_t; } channel_desc_t;
typedef struct { typedef struct {
...@@ -214,8 +232,9 @@ typedef enum { ...@@ -214,8 +232,9 @@ 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"
#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},\
} }
#include "platform_constants.h" #include "platform_constants.h"
...@@ -273,9 +292,18 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, ...@@ -273,9 +292,18 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
double forgetting_factor, double forgetting_factor,
int32_t channel_offset, int32_t channel_offset,
double path_loss_dB); double path_loss_dB);
/**
\brief free memory allocated for a model descriptor
\param ch points to the model, which cannot be used after calling this fuction
*/
void free_channel_desc_scm(channel_desc_t *ch);
/**
\brief This set the ownerid of a model descriptor, can be later used to check what module created a channel model
\param cdesc points to the model descriptor
\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);
/** \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
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <common/utils/assertions.h> #include <common/utils/assertions.h>
#include <common/utils/LOG/log.h> #include <common/utils/LOG/log.h>
#include <common/utils/load_module_shlib.h> #include <common/utils/load_module_shlib.h>
#include <common/utils/telnetsrv/telnetsrv.h>
#include <common/config/config_userapi.h> #include <common/config/config_userapi.h>
#include "common_lib.h" #include "common_lib.h"
#include <openair1/PHY/defs_eNB.h> #include <openair1/PHY/defs_eNB.h>
...@@ -78,11 +79,25 @@ extern RAN_CONTEXT_t RC; ...@@ -78,11 +79,25 @@ extern RAN_CONTEXT_t RC;
#define RFSIMULATOR_PARAMS_DESC {\ #define RFSIMULATOR_PARAMS_DESC {\
{"serveraddr", "<ip address to connect to>\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ {"serveraddr", "<ip address to connect to>\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
{"serverport", "<port to connect to>\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ {"serverport", "<port to connect to>\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
{RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0},\ {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
{"IQfile", "<file path to use when saving IQs>\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ {"IQfile", "<file path to use when saving IQs>\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
{"modelname", "<channel model name>\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 }\ {"modelname", "<channel model name>\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
{"ploss", "<channel path loss in dB>\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
{"forgetfact", "<channel forget factor ((0 to 1)>\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
{"offset", "<channel offset in samps>\n", 0, 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},
{"","",NULL},
};
static telnetshell_vardef_t rfsimu_vardef[] = {
{"",0,NULL}
};
pthread_mutex_t Sockmutex; pthread_mutex_t Sockmutex;
typedef struct complex16 sample_t; // 2*16 bits complex number typedef struct complex16 sample_t; // 2*16 bits complex number
...@@ -114,6 +129,11 @@ typedef struct { ...@@ -114,6 +129,11 @@ typedef struct {
double sample_rate; double sample_rate;
double tx_bw; double tx_bw;
int channelmod; int channelmod;
double chan_pathloss;
double chan_forgetfact;
int chan_offset;
void *telnetcmd_qid;
poll_telnetcmdq_func_t poll_telnetcmdq;
} rfsimulator_state_t; } rfsimulator_state_t;
...@@ -164,9 +184,10 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { ...@@ -164,9 +184,10 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
bridge->channelmod, bridge->channelmod,
bridge->sample_rate, bridge->sample_rate,
bridge->tx_bw, bridge->tx_bw,
0.0, // forgetting_factor bridge->chan_forgetfact, // forgetting_factor
0, // maybe used for TA bridge->chan_offset, // maybe used for TA
0); // path_loss in dB bridge->chan_pathloss); // path_loss in dB
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
random_channel(ptr->channel_model,false); random_channel(ptr->channel_model,false);
} }
} }
...@@ -293,6 +314,41 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { ...@@ -293,6 +314,41 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
rfsimulator->typeStamp = UE_MAGICDL_FDD; rfsimulator->typeStamp = UE_MAGICDL_FDD;
} }
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);
if (s == 1) {
int channelmod=modelid_fromname(modelname);
if (channelmod<0)
prnt("ERROR: model %s unknown\n",modelname);
else {
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
for (int i=0; i<FD_SETSIZE; i++) {
buffer_t *b=&t->buf[i];
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,
t->tx_bw,
t->chan_forgetfact, // forgetting_factor
t->chan_offset, // maybe used for TA
t->chan_pathloss); // path_loss in dB
set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
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);
}
}
}
} else {
prnt("ERROR: no model specified\n");
}
free(modelname);
return CMDSTATUS_FOUND;
}
int server_start(openair0_device *device) { int server_start(openair0_device *device) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
t->typeStamp=ENB_MAGICDL_FDD; t->typeStamp=ENB_MAGICDL_FDD;
...@@ -647,7 +703,8 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ...@@ -647,7 +703,8 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
// it seems legacy behavior is: never in UL, each frame in DL // it seems legacy behavior is: never in UL, each frame in DL
if (reGenerateChannel) if (reGenerateChannel)
random_channel(ptr->channel_model,0); random_channel(ptr->channel_model,0);
if (t->poll_telnetcmdq)
t->poll_telnetcmdq(t->telnetcmd_qid,t);
for (int a=0; a<nbAnt; a++) { for (int a=0; a<nbAnt; a++) {
if ( ptr->channel_model != NULL ) // apply a channel model if ( ptr->channel_model != NULL ) // apply a channel model
rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
...@@ -742,5 +799,18 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -742,5 +799,18 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator->tx_bw=openair0_cfg->tx_bw; 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 */
add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
if (addcmd != NULL) {
rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME);
addcmd("rfsimu",rfsimu_vardef,rfsimu_cmdarray);
for(int i=0; rfsimu_cmdarray[i].cmdfunc != NULL; i++) {
if ( rfsimu_cmdarray[i].qptr != NULL) {
rfsimulator->telnetcmd_qid = rfsimu_cmdarray[i].qptr;
break;
}
}
}
return 0; return 0;
} }
...@@ -727,7 +727,7 @@ int main ( int argc, char **argv ) ...@@ -727,7 +727,7 @@ int main ( int argc, char **argv )
// end of CI modifications // end of CI modifications
//getchar(); //getchar();
if(IS_SOFTMODEM_DOFORMS) if(IS_SOFTMODEM_DOFORMS)
load_softscope("enb"); load_softscope("enb",NULL);
itti_wait_tasks_end(); itti_wait_tasks_end();
oai_exit=1; oai_exit=1;
LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit); LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit);
......
...@@ -759,7 +759,7 @@ int main( int argc, char **argv ) { ...@@ -759,7 +759,7 @@ int main( int argc, char **argv ) {
} }
if(IS_SOFTMODEM_DOFORMS) if(IS_SOFTMODEM_DOFORMS)
load_softscope("ue"); load_softscope("ue",NULL);
config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
printf("Sending sync to all threads (%p,%p,%p)\n",&sync_var,&sync_cond,&sync_mutex); printf("Sending sync to all threads (%p,%p,%p)\n",&sync_var,&sync_cond,&sync_mutex);
......
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