Commit ac711d9a authored by Raphael Defosseux's avatar Raphael Defosseux

Merge remote-tracking branch 'origin/rfsimu_config' into develop_integration_2019_w36

parents e45794ce 7a1a9f83
......@@ -57,6 +57,7 @@ pipeline {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true
echo "Platform is ${TESTPLATFORM_OWNER}"
if (params.RedHatRemoteServer == null) {
allParametersPresent = false
......
......@@ -44,7 +44,7 @@ function build_on_vm {
STATUS=1
return
fi
if [ ! -f /etc/apt/apt.conf.d/01proxy ]
if [[ ! -f /etc/apt/apt.conf.d/01proxy ]] && [[ "$OPTIONAL_APTCACHER" != "true" ]]
then
echo "Missing /etc/apt/apt.conf.d/01proxy file!"
echo "Is apt-cacher installed and configured?"
......@@ -96,12 +96,12 @@ function build_on_vm {
else
scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu
fi
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu
[ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu
echo "############################################################"
echo "Running install and build script on VM ($VM_NAME)"
echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
echo "[ -f 01proxy ] && sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS
if [[ "$VM_NAME" == *"-cppcheck"* ]]
then
......
......@@ -140,10 +140,25 @@ function command_options_usage {
echo ""
}
# function to set specific behavior depending on the TESTPLATFORM_OWNER variable
# which may be set by a jenkins server for exemple
function platform_set {
if [ "$TESTPLATFORM_OWNER" != "" ]
then
echo "Running on $TESTPLATFORM_OWNER platform"
if [ -x "/usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh" ]
then
. /usr/local/bin/oai_${TESTPLATFORM_OWNER}_setenv.sh
fi
fi
}
function setvar_usage {
declare -A HELP_VAR
HELP_VAR["VM_OSREL"]="OS release to use in virtual machines"
HELP_VAR["RUN_EXPERIMENTAL"]="Enforce execution of variants with EXPERIMENTAL variable set to \"true\""
HELP_VAR["OPTIONAL_APTCACHER"]="build and Run tests will fail if apt-cacher not installed and this variable not set to \"true\""
HELP_VAR["TESTPLATFORM_OWNER"]="Allow pipeline customization via execution of an externel scripts residing on the jenkins server"
echo "--setvar_<varname> <value> where varname is one of:"
for i in ${AUTHORIZED_VAR[@]}; do printf "%20s : %s\n" "$i" "${HELP_VAR[$i]}" ;done
}
......@@ -315,6 +330,7 @@ function check_setvar {
exit 1
}
platform_set
MY_DIR=$(dirname $(readlink -f $0))
. $MY_DIR/createVM.sh
. $MY_DIR/buildOnVM.sh
......@@ -324,6 +340,7 @@ MY_DIR=$(dirname $(readlink -f $0))
. $MY_DIR/reportBuildLocally.sh
. $MY_DIR/reportTestLocally.sh
if [ $# -lt 1 ]
then
echo "Syntax Error: too few arguments"
......@@ -440,7 +457,7 @@ RUN_OPTIONS="none"
# list of variables that can be set via the --setvar option
AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL")
AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER")
#variables to set which OS VM should use
......
......@@ -476,7 +476,7 @@ function install_epc_on_vm {
local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME`
echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR"
scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
[ -f /etc/apt/apt.conf.d/01proxy ] && scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
# ltebox specific actions (install and start)
LTE_BOX_TO_INSTALL=1
......@@ -500,7 +500,7 @@ function install_epc_on_vm {
echo "############################################################"
echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)"
echo "############################################################"
echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS
echo "sudo [ -f 01proxy ] && cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS
echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS
echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS
echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
......
......@@ -1822,7 +1822,7 @@ add_library(LFDS7
# Simulation library
##########################
add_library(SIMU
set (SIMUSRC
${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
......@@ -1833,9 +1833,13 @@ ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c
${OPENAIR1_DIR}/SIMULATION/RF/rf.c
${OPENAIR1_DIR}/SIMULATION/RF/dac.c
${OPENAIR1_DIR}/SIMULATION/RF/adc.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR_DIR}/targets/ARCH/rfsimulator/apply_channelmod.c
#${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
)
# Simulation library
##########################
add_library( SIMU SHARED ${SIMUSRC} )
add_library(SIMU_ETH
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
......@@ -2134,7 +2138,6 @@ add_executable(lte-uesoftmodem
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
${OPENAIR_TARGETS}/RT/USER/ru_control.c
${OPENAIR_TARGETS}/RT/USER/rfsim.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
......
......@@ -150,7 +150,7 @@ Options
--build-eclipse
Build eclipse project files. Paths are auto corrected by fixprj.sh
--build-lib <libraries>
Build optional shared library, <libraries> can be one or several of $OPTIONAL_LIBRARIES
Build optional shared library, <libraries> can be one or several of $OPTIONAL_LIBRARIES or \"all\"
--usrp-recplay
Build for I/Q record-playback modes
......@@ -324,16 +324,21 @@ function main() {
shift 1;;
--build-lib)
BUILD_OPTLIB=""
for alib in $2 ; do
if [ "$2" == "all" ] ; then
BUILD_OPTLIB="$OPTIONAL_LIBRARIES"
echo_info "Enabling build of all optional shared libraries ($OPTIONAL_LIBRARIES)"
else
for alib in $2 ; do
for oklib in $OPTIONAL_LIBRARIES ; do
if [ "$alib" = "$oklib" ] ; then
BUILD_OPTLIB="$BUILD_OPTLIB $alib"
echo_info "Enabling build of lib${alib}.so"
fi
if [ "$alib" = "$oklib" ] ; then
BUILD_OPTLIB="$BUILD_OPTLIB $alib"
echo_info "Enabling build of lib${alib}.so"
fi
done
done
done
if [ "${BUILD_OPTLIB## }" != "$2" ] ; then
echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES"
if [ "${BUILD_OPTLIB## }" != "$2" ] ; then
echo_fatal "Unknown optional library in $2, valid libraries are $OPTIONAL_LIBRARIES"
fi
fi
shift 2;;
--usrp-recplay)
......@@ -515,21 +520,7 @@ function main() {
$lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
fi
if [ "$UE" = 1 ] ; then
......@@ -538,21 +529,6 @@ function main() {
$lte_build_dir $lte_exec \
$lte_exec $dbin/$lte_exec.$REL
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
# ue_ip driver compilation
compilations \
$lte_build_dir ue_ip \
......@@ -665,10 +641,25 @@ function main() {
fi
# build RF device and transport protocol libraries
# build RF device, transport protocol libraries and all
# shared libraries common to UE and eNB
#####################################
if [ "$eNB" = "1" -o "$UE" = "1" ] ; then
# mandatory shared lib
compilations \
$lte_build_dir $config_libconfig_shlib \
lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so
compilations \
$lte_build_dir coding \
libcoding.so $dbin/libcoding.so
# optional libs (used when noS1 with kernel modules
compilations \
$lte_build_dir nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $dbin/nasmesh.ko
compilations \
$lte_build_dir rb_tool \
rb_tool $dbin/rb_tool
cp $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 $dbin
# build RF device libraries
if [ "$HW" != "None" ] ; then
rm -f liboai_device.so
......@@ -737,7 +728,7 @@ function main() {
echo_info "liboai_transpro.so is linked to ETHERNET transport"
fi
if [ "$RFSIMULATOR" == "true" -o "$HW" == "OAI_SIMU" ] ; then
if [ "$HW" == "OAI_SIMU" ] ; then
echo_info "Compiling rfsimulator"
compilations \
$lte_build_dir rfsimulator \
......
## config module management
```c
configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags)
```
......@@ -14,23 +16,17 @@ void End_configmodule(void)
* Free memory which has been allocated by the configuration module since its initialization.
* Possibly calls the `config_<config source>_end` function
## Retrieving parameter's values
```c
int config_get(paramdef_t *params,int numparams, char *prefix)
```
* Reads as many parameters as described in params, they must all be in the same configuration file section
* Calls the `config_<config source>_get` function
* Calls the `config_process_cmdline` function
* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function. The following bits can possibly be set in the `paramflags` mask before calling
- `PARAMFLAG_MANDATORY`: -1 is returned if the parameter is not explicitly defined in the config source.
- `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line
- `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls.
- `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called.
- `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1.
* `params` is also used as an output parameter, `< XXX >ptr >` field is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call:
- `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field
- `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value.
- `PARAMFLAG_PARAMSET`: parameter has been set to its default value
* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function.The `paramflags` bit mask can be used to modify how a specific parameter is processed and the same mask is also used by the configuration module to return information about how the parameter has been processed. Bits definitions are described in the [`paramdef_t` structure description](./struct.md)
* `numparams` is the number of entries in the params array
* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology).
* The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured
......@@ -44,6 +40,9 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int
* `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters.
* The returned value is the number of occurrences in the list or -1 in case of severe error
## utility functions and macros
The configuration module also defines APIs to access the `paramdef_t` and `configmodule_interface_t` fields. They are listed in the configuration module [include file `common/config/config_userapi.h`](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.h)
[Configuration module developer main page](../../config/devusage.md)
[Configuration module home](../../config.md)
......@@ -5,6 +5,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
|:-----------|:------------------------------------------------------------------|----:|
| `optname` | parameter name, as used when looking for it in the config source, 63 bytes max (64 with trailing \0) | I |
| `helstr` | pointer to a C string printed when using --help on the command line | I |
| `paramflags` | bit mask, used to modify how the parameter is processed, or to return to the API caller how the parameter has been set, see list in the next table | IO |
| `strptr` `strlistptr` `u8ptr` `i8ptr` `u16ptr` `i16ptr` `uptr` `iptr` `u64ptr` `i64ptr` `dblptr` `voidptr` | a pointer to a variable where the parameter value(s) will be returned. This field is an anonymous union, the supported pointer types have been built to avoid type mismatch warnings at compile time. | O |
| `defstrval` `defstrlistval` `defuintval` `defintval` `defint64val` `defintarrayval` `defdblval` | this field is an anonymous union, it can be used to define the default value for the parameter. It is ignored if `PARAMFLAG_MANDATORY` is set in the `paramflags` field.| I |
| `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I |
......@@ -12,6 +13,22 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
| `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I |
| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O |
## `paramflags` bits definition
| C macro bit definition | usage | I/O |
|:-------------------------------------|:---------------------------------------------------------------------------------------------------------------------|----:|
| `PARAMFLAG_MANDATORY` | parameter is mandatory, comfiguration module will stop the process if it is not specified. Default value is ignored | I |
| `PARAMFLAG_DISABLECMDLINE` | parameter cannot be specified on the command line | I |
| `PARAMFLAG_DONOTREAD` | ignore the parameter, usefull when a parameter group is used in different context | I |
| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I |
| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I |
| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I |
| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O |
| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O |
| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O |
# `paramlist_def_t`structure
It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160).
It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters.
......
......@@ -167,8 +167,8 @@ int config_check_unknown_cmdlineopt(char *prefix) {
char testprefix[CONFIG_MAXOPTLENGTH];
int finalcheck = 0;
memset(testprefix,0,sizeof(testprefix));
memset(testprefix,0,sizeof(testprefix));
if (prefix != NULL) {
if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0)
finalcheck = 1;
......@@ -253,7 +253,9 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
}
if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) {
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */
((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ||
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
char *valptr=NULL;
int ret;
config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED;
......
......@@ -48,7 +48,7 @@
#define PARAMFLAG_DONOTREAD (1 << 2) // parameter must be ignored in get function
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module
......
......@@ -172,7 +172,7 @@ int config_get_processedint(paramdef_t *cfgoption) {
return ret;
}
void config_printhelp(paramdef_t *params,int numparams, char *prefix) {
printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix ,numparams);
printf("\n-----Help for section %-26s: %03i entries------\n",(prefix==NULL)?"(root section)":prefix,numparams);
for (int i=0 ; i<numparams ; i++) {
printf(" %s%s: %s",
......@@ -204,6 +204,16 @@ int config_execcheck(paramdef_t *params,int numparams, char *prefix) {
return st;
}
int config_paramidx_fromname(paramdef_t *params,int numparams, char *name) {
for (int i=0; i<numparams ; i++) {
if (strcmp(name,params[i].optname) == 0)
return i;
}
fprintf(stderr,"[CONFIG]config_paramidx_fromname , %s is not a valid parameter name\n",name);
return -1;
}
int config_get(paramdef_t *params,int numparams, char *prefix) {
int ret= -1;
......@@ -438,7 +448,7 @@ int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) {
status=1;
for (int j=0; j<cfgoptions->numelt ; j++) {
printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname ,j,(int)cfgoptions->iptr[j]);
printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname,j,(int)cfgoptions->iptr[j]);
}
}
......@@ -452,7 +462,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) {
*(cfgoptions->dblptr)=cfgoptions->defdblval;
status=1;
printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr));
printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname, *(cfgoptions->dblptr));
}
return status;
......@@ -460,7 +470,7 @@ int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) {
int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) {
config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int));
int rst=inet_pton(AF_INET, ipv4addr ,cfgoptions->uptr );
int rst=inet_pton(AF_INET, ipv4addr,cfgoptions->uptr );
if (rst == 1 && *(cfgoptions->uptr) > 0) {
printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr);
......
......@@ -39,6 +39,7 @@ extern "C"
{
#endif
/* utility functions to ease usage of config module structures */
#define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode )
#define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP )
#define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] )
......@@ -46,6 +47,8 @@ extern "C"
#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))
extern int config_paramidx_fromname(paramdef_t *params,int numparams, char *name);
/* utility functions, to be used by configuration module and/or configuration libraries */
extern configmodule_interface_t *config_get_if(void);
extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
......
......@@ -123,7 +123,7 @@ void client_printf(const char *message, ...) {
if (telnetparams.new_socket > 0) {
vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args);
send(telnetparams.new_socket,telnetparams.msgbuff , strlen(telnetparams.msgbuff), MSG_NOSIGNAL);
send(telnetparams.new_socket,telnetparams.msgbuff, strlen(telnetparams.msgbuff), MSG_NOSIGNAL);
} else {
vprintf(message, va_args);
}
......@@ -475,7 +475,7 @@ int process_command(char *buf) {
memset(cmdb,0,sizeof(cmdb));
bufbck=strdup(buf);
rt=CMDSTATUS_NOTFOUND;
j = sscanf(buf,"%9s %9s %9[^\t\n]",modulename,cmd,cmdb);
j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb);
if (telnetparams.telnetdbg > 0)
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
......@@ -543,7 +543,7 @@ void run_telnetsrv(void) {
char buf[TELNET_MAX_MSGLENGTH];
struct sockaddr cli_addr;
unsigned int cli_len = sizeof(cli_addr);
int readc , filled;
int readc, filled;
int status;
int optval = 1;
pthread_setname_np(pthread_self(), "telnet");
......@@ -604,7 +604,7 @@ void run_telnetsrv(void) {
}
if (telnetparams.telnetdbg > 0)
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf);
printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf);
if (buf[0] == '!') {
if (buf[1] == '!') {
......
......@@ -54,7 +54,7 @@ cd cmake_targets/
```
- The `-I` option is to install pre-requisites, you only need it the first time you build the softmodem or when some oai dependencies have changed.
- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process.
- The `-w` option is to select the radio head support you want to include in your build. Radio head support is provided via a shared library, which is called the "oai device" The build script creates a soft link from `liboai_device.so` to the true device which will be used at run-time (here the USRP one,`liboai_usrpdevif.so` . USRP is the only hardware tested today in the Continuous Integration process. The RF simulator[RF simulator](../targets/ARCH/rfsimulator/README.md) is implemented as a specific device replacing RF hardware, it can be build using `-w SIMU` option.
- `--eNB` is to build the `lte-softmodem` executable and all required shared libraries
- `--UE` is to build the `lte-uesoftmodem` executable and all required shared libraries
......
......@@ -122,7 +122,6 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxt
phich->config[phich->num_hi].n_DMRS = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms;
phich->num_hi++;
AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n");
}
void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
......@@ -186,6 +185,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
#endif
harq_pid = dlsch0->harq_ids[proc->frame_tx%2][proc->subframe_tx];
if((harq_pid < 0) || (harq_pid >= dlsch0->Mdlharq)) {
LOG_E(PHY,"illegal harq_pid %d %s:%d\n", harq_pid, __FILE__, __LINE__);
return;
......@@ -260,9 +260,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
dlsch0->harq_mask = 1;
dlsch0_harq = dlsch0->harq_processes[0];
dlsch0_harq->pdu = sdu;
LOG_D(PHY,"NFAPI: frame %d, subframe %d (TX %d.%d): Programming SI-BR (%d) => %d\n",frame,subframe,proc->frame_tx,proc->subframe_tx,rel13->pdsch_payload_type,UE_id);
dlsch0->rnti = 0xFFFF;
dlsch0->Kmimo = 1;
dlsch0->Mdlharq = 4;
......@@ -569,8 +567,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint16_t frame,
uint8_t subframe,
uint8_t srs_active)
{
uint8_t srs_active) {
LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
if (NFAPI_MODE==NFAPI_MODE_VNF) return;
......@@ -803,13 +800,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
// clear DCI allocation maps for new subframe
if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
if (eNB->ulsch[i]) {
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
ulsch_harq->dci_alloc=0;
ulsch_harq->rar_alloc=0;
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
if (eNB->ulsch[i]) {
ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid];
ulsch_harq->dci_alloc=0;
ulsch_harq->rar_alloc=0;
}
}
}
}
for (i=0; i<number_dl_pdu; i++) {
......@@ -820,6 +817,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE:
if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_dci_dl_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(DL_req->sfn_sf)&1].num_dci++;
//LOG_E(PHY,"Incremented num_dci:%d but already set??? dl_config:num_dci:%d\n", eNB->pdcch_vars[subframe&1].num_dci, number_dci);
do_oai=1;
......@@ -832,11 +830,13 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
TX_req->tx_request_body.number_of_pdus);
eNB->pbch_configured=1;
do_oai=1;
//LOG_D(PHY,"%s() NFAPI_DL_CONFIG_BCH_PDU_TYPE TX:%d/%d RX:%d/%d TXREQ:%d/%d\n",
//__FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, NFAPI_SFNSF2SFN(TX_req->sfn_sf), NFAPI_SFNSF2SF(TX_req->sfn_sf));
if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_bch_pdu(eNB,proc,dl_config_pdu,
TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data);
TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->bch_pdu.bch_pdu_rel8.pdu_index].segments[0].segment_data);
break;
case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
......@@ -867,8 +867,8 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
dlsch_pdu_rel8->transport_blocks);
if (1) { //sdu != NULL)
if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu);
if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_dlsch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, dlsch_pdu_rel8->transport_blocks-1, sdu);
} else {
dont_send=1;
LOG_E(MAC,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index,
......@@ -911,6 +911,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE:
if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++;
break;
#endif
......@@ -918,10 +919,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
}
if ((NFAPI_MODE!=NFAPI_MONOLITHIC) && do_oai && !dont_send) {
if(Sched_INFO->TX_req->tx_request_body.number_of_pdus > 0){
if(Sched_INFO->TX_req->tx_request_body.number_of_pdus > 0) {
Sched_INFO->TX_req->sfn_sf = frame << 4 | subframe;
oai_nfapi_tx_req(Sched_INFO->TX_req);
}
Sched_INFO->DL_req->sfn_sf = frame << 4 | subframe;
oai_nfapi_dl_config_req(Sched_INFO->DL_req); // DJP - .dl_config_request_body.dl_config_pdu_list[0]); // DJP - FIXME TODO - yuk - only copes with 1 pdu
Sched_INFO->UE_release_req->sfn_sf = frame << 4 | subframe;
......@@ -935,27 +937,27 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_pdcch_symbols=0;
}
if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; i<number_hi_dci0_pdu; i++) {
hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type);
switch (hi_dci0_req_pdu->pdu_type) {
case NFAPI_HI_DCI0_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++;
break;
case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_mpdcch_dci_pdu(eNB,proc,hi_dci0_req_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++;
break;
case NFAPI_HI_DCI0_HI_PDU_TYPE:
handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
break;
if (NFAPI_MODE!=NFAPI_MODE_VNF)
for (i=0; i<number_hi_dci0_pdu; i++) {
hi_dci0_req_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
LOG_D(PHY,"NFAPI: hi_dci0_pdu %d : type %d\n",i,hi_dci0_req_pdu->pdu_type);
switch (hi_dci0_req_pdu->pdu_type) {
case NFAPI_HI_DCI0_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_dci_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
eNB->pdcch_vars[NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf)&1].num_dci++;
break;
case NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE:
handle_nfapi_hi_dci0_mpdcch_dci_pdu(eNB,proc,hi_dci0_req_pdu);
eNB->mpdcch_vars[subframe&1].num_dci++;
break;
case NFAPI_HI_DCI0_HI_PDU_TYPE:
handle_nfapi_hi_dci0_hi_pdu(eNB,NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),proc,hi_dci0_req_pdu);
break;
}
}
}
if (NFAPI_MODE!=NFAPI_MONOLITHIC) {
if (number_ul_pdu>0) {
......
This diff is collapsed.
......@@ -147,7 +147,7 @@ typedef struct {
/// Rice factor???
/// Walls (penetration loss)
/// Nodes in the scenario
node_desc_t* nodes;
node_desc_t *nodes;
} scenario_desc_t;
typedef enum {
......@@ -180,29 +180,66 @@ typedef enum {
EPA_medium,
EPA_high,
} SCM_t;
#define CHANNELMOD_MAP_INIT \
{"custom",custom},\
{"SCM_A",SCM_A},\
{"SCM_B",SCM_B},\
{"SCM_C",SCM_C},\
{"SCM_D",SCM_D},\
{"EPA",EPA},\
{"EVA",EVA},\
{"ETU",ETU},\
{"MBSFN",MBSFN},\
{"Rayleigh8",Rayleigh8},\
{"Rayleigh1",Rayleigh1},\
{"Rayleigh1_800",Rayleigh1_800},\
{"Rayleigh1_corr",Rayleigh1_corr},\
{"Rayleigh1_anticorr",Rayleigh1_anticorr},\
{"Rice8",Rice8},\
{"Rice1",Rice1},\
{"Rice1_corr",Rice1_corr},\
{"Rice1_anticorr",Rice1_anticorr},\
{"AWGN",AWGN},\
{"Rayleigh1_orthogonal",Rayleigh1_orthogonal},\
{"Rayleigh1_orth_eff_ch_TM4_prec_real",Rayleigh1_orth_eff_ch_TM4_prec_real},\
{"Rayleigh1_orth_eff_ch_TM4_prec_imag",Rayleigh1_orth_eff_ch_TM4_prec_imag},\
{"Rayleigh8_orth_eff_ch_TM4_prec_real",Rayleigh8_orth_eff_ch_TM4_prec_real},\
{"Rayleigh8_orth_eff_ch_TM4_prec_imag",Rayleigh8_orth_eff_ch_TM4_prec_imag},\
{"TS_SHIFT",TS_SHIFT},\
{"EPA_low",EPA_low},\
{"EPA_medium",EPA_medium},\
{"EPA_high",EPA_high},\
{NULL, -1}
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CHANNELMOD_SECTION "channelmod"
#define CHANNELMOD_PARAMS_DESC { \
{"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},\
}
#include "platform_constants.h"
typedef struct {
channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs];
double r_re_DL[NUMBER_OF_UE_MAX][2][30720];
double r_im_DL[NUMBER_OF_UE_MAX][2][30720];
double r_re_UL[NUMBER_OF_eNB_MAX][2][30720];
double r_im_UL[NUMBER_OF_eNB_MAX][2][30720];
int RU_output_mask[NUMBER_OF_UE_MAX];
int UE_output_mask[NUMBER_OF_RU_MAX];
pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX];
pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX];
pthread_mutex_t subframe_mutex;
int subframe_ru_mask;
int subframe_UE_mask;
openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
double ru_amp[NUMBER_OF_RU_MAX];
pthread_t rfsim_thread;
channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM_CCs];
channel_desc_t *UE2RU[NUMBER_OF_UE_MAX][NUMBER_OF_RU_MAX][MAX_NUM_CCs];
double r_re_DL[NUMBER_OF_UE_MAX][2][30720];
double r_im_DL[NUMBER_OF_UE_MAX][2][30720];
double r_re_UL[NUMBER_OF_eNB_MAX][2][30720];
double r_im_UL[NUMBER_OF_eNB_MAX][2][30720];
int RU_output_mask[NUMBER_OF_UE_MAX];
int UE_output_mask[NUMBER_OF_RU_MAX];
pthread_mutex_t RU_output_mutex[NUMBER_OF_UE_MAX];
pthread_mutex_t UE_output_mutex[NUMBER_OF_RU_MAX];
pthread_mutex_t subframe_mutex;
int subframe_ru_mask;
int subframe_UE_mask;
openair0_timestamp current_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp current_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
openair0_timestamp last_ru_rx_timestamp[NUMBER_OF_RU_MAX][MAX_NUM_CCs];
openair0_timestamp last_UE_rx_timestamp[MAX_MOBILES_PER_ENB][MAX_NUM_CCs];
double ru_amp[NUMBER_OF_RU_MAX];
pthread_t rfsim_thread;
} sim_t;
......@@ -231,7 +268,7 @@ typedef struct {
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double sampling_rate,
double sampling_rate,
double channel_bandwidth,
double forgetting_factor,
int32_t channel_offset,
......@@ -395,9 +432,23 @@ void multipath_tv_channel(channel_desc_t *desc,
/**@} */
/**@} */
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
uint64_t TS,
uint32_t CirSize
);
int modelid_fromname(char *modelname);
double channelmod_get_snr_dB(void);
double channelmod_get_sinr_dB(void);
void init_channelmod(void) ;
double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB);
#include "targets/RT/USER/rfsim.h"
void do_DL_sig(sim_t *sim,
......@@ -409,9 +460,10 @@ void do_DL_sig(sim_t *sim,
int CC_id);
void do_UL_sig(sim_t *sim,
uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
uint16_t subframe,uint8_t abstraction_flag,LTE_DL_FRAME_PARMS *frame_parms,
uint32_t frame,int ru_id,uint8_t CC_id);
#endif
......@@ -410,7 +410,6 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
#define sample_t struct complex16 // 2*16 bits complex number
typedef struct {
uint64_t magic; // Magic value (see defines above)
......
#General
# General
This is a RF simulator that allows to test OAI without a RF board.
It replaces a actual RF board driver.
As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
#build
# build
## From build_oai
You can build it the same way, and together with actual RF driver
## From [build_oai](../../../doc/BUILD.md) script
The RF simulator is implemented as an oai device and is always build when you build the oai eNB or the oai UE.
Using the `-w SIMU` option it is possible to just re-build the RF simulator device
Example:
```bash
./build_oai --ue-nas-use-tun --UE --eNB -w SIMU
./build_oai --UE --eNB
Will compile UE
Will compile eNB
CMAKE_CMD=cmake ..
No local radio head and no transport protocol selected
No radio head has been selected (HW set to None)
No transport protocol has been selected (TP set to None)
RF HW set to None
Flags for Deadline scheduler: False
..................
.................
Compiling rfsimulator
Log file for compilation has been written to: /usr/local/oai/rfsimu_config/openairinterface5g/cmake_targets/log/rfsimulator.Rel14.txt
rfsimulator compiled
......................
......................
```
It is also possible to build actual RF and use choose on each run:
```bash
./build_oai --ue-nas-use-tun --UE --eNB -w USRP --rfsimulator
```
Will build both the eNB (lte-softmodem) and the UE (lte-uesoftmodem)
We recommend to use the option --ue-nas-use-tun that is much simpler to use than the OAI kernel driver.
## Add the rfsimulator after initial build
After any regular build, you can compile the driver
After any regular build, you can compile the device, from the build directory
```bash
cd <the_compilation_dir_from_bouild_oai_script>/build
cd <path to oai sources>/openairinterface5g/cmake_targets/lte_build_oai/build
make rfsimulator
```
Then, you can use it freely
this is equivalent to using `-w SIMU` when running the `build_oai` script.
e
# Usage
Setting the env variable RFSIMULATOR enables the RF board simulator
It should the set to "server" in the eNB or gNB
To use the RF simulator you add the `--rfsim` option to the command line. By default the RF simulator device will try to connect to host 127.0.0.1, port 4043, which is usually the behavior for the UE.
The RF simulator is using the configuration module, its parameters are defined in a specific section called "rfsimulator"
| parameter | usage | default |
|:---------------------|:------------------------------------------------------------------------------------------------------------------|----:|
| serveraddr | ip address to connect to, or "enb" to behave as a tcp server | 127.0.0.1 |
| serverport | port number to connect to or to listen on (eNB, which behaved as a tcp server) | 4043 |
| options | list of comma separated run-time options, two are supported: `chanmod` to enable channel modeling and `saviq` to write transmitted iqs to a file | all options disabled |
| modelname | Name of the channel model to apply on received iqs when the `chanmod` option is enabled | AWGN |
| IQfile | Path to the file to be used to store iqs, when the `saviq`option is enabled | /tmp/rfsimulator.iqs |
Setting the env variable RFSIMULATOR can be used instead of using the serveraddr parameter, it is to preserve compatibility with previous version.
## 4G case
For the UE, it should be set to the IP address of the eNB
......@@ -38,13 +59,14 @@ example:
```bash
sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50
```
Except this, the UE and the eNB can be used as it the RF is real
Except this, the UE and the eNB can be used as it the RF is real. noS1 mode can also be used with the RF simulator.
If you reach 'RA not active' on UE, be careful to generate a valid SIM
If you reach 'RA not active' on UE, be careful to generate a valid SIM.
```bash
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
```
## 5G case
5G RF simulator will be aligned with 4G as the effort to merge 5G specifuc branches into develop is making progress.
After regular build, add the simulation driver
(don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
```bash
......@@ -66,7 +88,7 @@ In UE, you can add "-d" to get the softscope
You can store emitted I/Q samples:
If you set the environment variable: saveIQfile to a file name
If you set the option `saviq`
The simulator will write all IQ samples into this file
Then, you can replay with the executable "replay_node"
......@@ -83,11 +105,11 @@ If you have existing stored I/Q, you can adpat the tool "replay_node" to convert
The format intend to be compatible with the OAI store/replay feature on USRP
### Channel simulation
The RF channel simulator is called.
In current version all channel paramters are hard coded in the call to:
When the `chanmod` option is enabled, The RF channel simulator is called.
In current version all channel paramters are set depending on the model name via a call to:
```
new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
AWGN,
<model name>,
bridge->sample_rate,
bridge->tx_bw,
0.0, // forgetting_factor
......@@ -95,7 +117,7 @@ new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
0); // path_loss in dB
```
Only the input noise can be changed on command line with -s parameter.
With path loss = 0 set "-s 5" to see a little noise
With path loss = 0 set "-s 5" to see a little noise. -s is a shortcut to `channelmod.s`. It is expected to enhance the channel modedelization flexibility via the addition of more parameters in the channelmod section.
#Caveacts
# Caveacts
Still issues in power control: txgain, rxgain are not used
/*
Author: Laurent THOMAS, Open Cells for Nokia
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <common/utils/assertions.h>
#include <common/utils/LOG/log.h>
#include <common/config/config_userapi.h>
#include <openair1/SIMULATION/TOOLS/sim.h>
/*
Legacy study:
The parameters are:
gain&loss (decay, signal power, ...)
either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average
=> don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE
will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop)
lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas);
a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain
multi_path (auto convolution, ISI, ...)
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
legacy: we regenerate each sub frame in UL, and each frame only in DL
*/
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
int rxAnt,
channel_desc_t *channelDesc,
int nbSamples,
uint64_t TS,
uint32_t CirSize
) {
// channelDesc->path_loss_dB should contain the total path gain
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
// UE and NB gain control to be added
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
// Energy in one sample to calibrate input noise
//Fixme: modified the N0W computation, not understand the origin value
const double KT=1.38e-23*290; //Boltzman*temperature
// sampling rate is linked to acquisition band (the input pass band filter)
const double noise_figure_watt = KT*channelDesc->sampling_rate;
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
// the parameter "-s" is declared as SNR, but the input power is not well defined
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
const double rxGain= 132.24 - channelmod_get_snr_dB();
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
// fixme: the last constant is pure trial results to make decent noise
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
// Fixme: we don't fill the offset length samples at begining ?
// anyway, in today code, channel_offset=0
const int dd = abs(channelDesc->channel_offset);
const int nbTx=channelDesc->nb_tx;
for (int i=0; i<((int)nbSamples-dd); i++) {
struct complex16 *out_ptr=after_channel_sig+dd+i;
struct complex rx_tmp= {0};
for (int txAnt=0; txAnt < nbTx; txAnt++) {
const struct complex *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)];
//const struct complex *channelModelEnd=channelModel+channelDesc->channel_length;
for (int l = 0; l<(int)channelDesc->channel_length; l++) {
// let's assume TS+i >= l
// fixme: the rfsimulator current structure is interleaved antennas
// this has been designed to not have to wait a full block transmission
// but it is not very usefull
// it would be better to split out each antenna in a separate flow
// that will allow to mix ru antennas freely
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
rx_tmp.x += tx16.r * channelModel[l].x - tx16.i * channelModel[l].y;
rx_tmp.y += tx16.i * channelModel[l].x + tx16.r * channelModel[l].y;
} //l
}
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
out_ptr++;
}
if ( (TS*nbTx)%CirSize+nbSamples <= CirSize )
// Cast to a wrong type for compatibility !
LOG_D(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n",
10*log10((double)signal_energy((int32_t *)&input_sig[(TS*nbTx)%CirSize], nbSamples)),
10*log10((double)signal_energy((int32_t *)after_channel_sig, nbSamples)),
channelDesc->path_loss_dB,
10*log10(noise_per_sample));
}
This diff is collapsed.
......@@ -5,6 +5,7 @@
#include <common/utils/simple_executable.h>
volatile int oai_exit = 0;
void fullwrite(int fd, void *_buf, int count) {
char *buf = _buf;
......@@ -123,7 +124,7 @@ int main(int argc, char *argv[]) {
setblocking(serviceSock, blocking);
AssertFatal(read(fd,&header,sizeof(header)), "");
fullwrite(serviceSock, &header, sizeof(header));
int dataSize=sizeof(sample_t)*header.size*header.nbAnt;
int dataSize=sizeof(int32_t)*header.size*header.nbAnt;
if (dataSize>bufSize) {
void * new_buff = realloc(buff, dataSize);
......
......@@ -275,12 +275,24 @@ NETWORK_CONTROLLER :
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
/*
#example config for rfsimulator
rfsimulator :
{
serveraddr = "enb";
serverport = "4043";
options = ("saviq");
modelname = "AWGN";
IQfile = "/tmp/rfsimulator.iqs";
};
*/
log_config :
{
global_log_level ="info";
......
......@@ -38,7 +38,7 @@
static softmodem_params_t softmodem_params;
char *parallel_config=NULL;
char *worker_config=NULL;
double snr_dB=25;
uint64_t get_softmodem_optmask(void) {
return softmodem_params.optmask;
......
......@@ -78,7 +78,6 @@
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
#define CONFIG_HLP_TPORT "tracer port\n"
......@@ -200,7 +199,6 @@
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
{"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, 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}, \
......@@ -264,9 +262,9 @@ typedef struct {
int numerology;
unsigned int start_msc;
uint32_t clock_source;
uint32_t timing_source;
uint32_t timing_source;
int hw_timing_advance;
uint32_t send_dmrs_sync;
uint32_t send_dmrs_sync;
} softmodem_params_t;
#define IS_SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT)
......@@ -285,8 +283,6 @@ uint64_t get_pdcp_optmask(void);
extern pthread_cond_t sync_cond;
extern pthread_mutex_t sync_mutex;
extern int sync_var;
extern double snr_dB;
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
......@@ -311,7 +307,7 @@ extern void stop_eNB(int);
extern void kill_eNB_proc(int inst);
// In lte-ru.c
extern void init_RU(char*,clock_source_t clock_source,clock_source_t time_source,int send_dmrssync);
extern void init_RU(char *,clock_source_t clock_source,clock_source_t time_source,int send_dmrssync);
extern void stop_ru(RU_t *ru);
extern void init_ru_vnf(void);
extern void init_RU_proc(RU_t *ru);
......@@ -337,7 +333,7 @@ extern void kill_td_thread(PHY_VARS_eNB *);
extern void kill_te_thread(PHY_VARS_eNB *);
extern void RCConfig_sim(void);
extern void init_ocm(double,double);
extern void init_ocm(void);
extern void init_ue_devices(PHY_VARS_UE *);
PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
......
......@@ -323,12 +323,10 @@ static void get_options(void) {
int CC_id;
int tddflag;
char *loopfile=NULL;
int dumpframe=0;
int timingadv;
uint8_t nfapi_mode;
int simL1flag ;
set_default_frame_parms(frame_parms);
CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
/* unknown parameters on command line will be checked in main
......@@ -616,7 +614,7 @@ int main( int argc, char **argv ) {
if (config_mod == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
mode = normal_txrx;
memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS);
set_latency_target();
......@@ -811,7 +809,7 @@ int main( int argc, char **argv ) {
//p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
if (IS_SOFTMODEM_SIML1 ) {
init_ocm(snr_dB,0);
init_ocm();
PHY_vars_UE_g[0][0]->no_timing_correction = 1;
}
......
This diff is collapsed.
......@@ -27,7 +27,7 @@
#include "PHY/defs_UE.h"
#include "PHY/defs_eNB.h"
void init_ocm(double snr_dB,double sinr_dB);
void init_ocm(void);
void update_ocm(double snr_dB,double sinr_dB);
......@@ -37,4 +37,4 @@ void update_ocm(double snr_dB,double sinr_dB);
void init_channel_vars(void);
#endif
#endif
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