Merge branch 'develop' into feature-59-tm4
This commit is contained in:
@@ -1759,6 +1759,7 @@ add_executable(lte-softmodem
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${GTPU_need_ITTI}
|
||||
${HW_SOURCE}
|
||||
${TRANSPORT_SOURCE}
|
||||
@@ -1885,9 +1886,11 @@ add_executable(oaisim
|
||||
${OPENAIR_TARGETS}/SIMU/USER/oaisim_functions.c
|
||||
${OPENAIR_TARGETS}/SIMU/USER/event_handler.c
|
||||
${OPENAIR_TARGETS}/SIMU/USER/oaisim.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${GTPU_need_ITTI}
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
||||
${HW_SOURCE}
|
||||
@@ -1899,7 +1902,7 @@ add_executable(oaisim
|
||||
|
||||
target_include_directories(oaisim PUBLIC ${OPENAIR_TARGETS}/SIMU/USER)
|
||||
target_link_libraries (oaisim
|
||||
-Wl,--start-group
|
||||
-Wl,-ldl,--start-group
|
||||
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB GTPV1U SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${MSC_LIB} L2 ${RAL_LIB} LIB_NAS_UE SIMU SIMU_ETH SECU_OSA ${ITTI_LIB} ${MIH_LIB}
|
||||
-Wl,--end-group )
|
||||
|
||||
@@ -1930,6 +1933,7 @@ add_executable(oaisim_nos1
|
||||
${OPENAIR_TARGETS}/SIMU/USER/oaisim_functions.c
|
||||
${OPENAIR_TARGETS}/SIMU/USER/event_handler.c
|
||||
${OPENAIR_TARGETS}/SIMU/USER/oaisim.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR_TARGETS}/COMMON/create_tasks.c
|
||||
|
||||
@@ -88,31 +88,47 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototype
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2")
|
||||
|
||||
#This is to detect nettle version changes between Ubuntu 14.04/16.04
|
||||
set ( nettle_cmd "nettle-hash" )
|
||||
set ( nettle_arg "-V" )
|
||||
execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev)
|
||||
|
||||
string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov})
|
||||
|
||||
message("NETTLE_VERSION = ${nv}")
|
||||
|
||||
# we need to remove decimal as floating point arithematic does not work properly with C preprocessor
|
||||
STRING(REGEX REPLACE "[.]" "" nv ${nv})
|
||||
|
||||
if ("${nv}" STREQUAL "")
|
||||
message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" )
|
||||
endif()
|
||||
|
||||
set (NETTLE_VERSION "${nv}")
|
||||
add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}")
|
||||
##This is to detect nettle version changes between Ubuntu 14.04/16.04
|
||||
#set ( nettle_cmd "nettle-hash" )
|
||||
#set ( nettle_arg "-V" )
|
||||
#execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev)
|
||||
#
|
||||
#string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov})
|
||||
#
|
||||
#message("NETTLE_VERSION = ${nv}")
|
||||
#
|
||||
## we need to remove decimal as floating point arithematic does not work properly with C preprocessor
|
||||
#STRING(REGEX REPLACE "[.]" "" nv ${nv})
|
||||
#
|
||||
#if ("${nv}" STREQUAL "")
|
||||
# message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" )
|
||||
#endif()
|
||||
#
|
||||
#set (NETTLE_VERSION "${nv}")
|
||||
#add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}")
|
||||
|
||||
include(FindPkgConfig)
|
||||
|
||||
INCLUDE(FindNettle)
|
||||
IF( NOT NETTLE_FOUND )
|
||||
MESSAGE( SEND_ERROR "Nettle is required" )
|
||||
ENDIF( NOT NETTLE_FOUND )
|
||||
pkg_search_module(NETTLE nettle)
|
||||
if(NOT ${NETTLE_FOUND})
|
||||
message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!")
|
||||
else()
|
||||
include_directories(${NETTLE_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}")
|
||||
|
||||
string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION})
|
||||
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION})
|
||||
message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}")
|
||||
message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}")
|
||||
|
||||
if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "")
|
||||
message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" )
|
||||
endif()
|
||||
|
||||
add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}")
|
||||
add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}")
|
||||
|
||||
|
||||
pkg_search_module(OPENSSL openssl REQUIRED)
|
||||
@@ -215,8 +231,8 @@ set(api_user_HDR
|
||||
|
||||
add_library(api_user ${api_user_SRC} ${api_user_HDR})
|
||||
target_include_directories(api_user PRIVATE ${OPENAIR_NAS_DIR}/UE/API/USER
|
||||
${OPENAIR_NAS_DIR}/UE
|
||||
${OPENAIR_NAS_DIR}/COMMON
|
||||
${OPENAIR_NAS_DIR}/UE
|
||||
)
|
||||
|
||||
################################################################################
|
||||
@@ -397,6 +413,7 @@ target_include_directories(emm PRIVATE
|
||||
${OPENAIR_DIR}/common/utils/msc
|
||||
${OPENAIR_DIR}/common/utils
|
||||
${OPENAIR_DIR}/openair2/COMMON
|
||||
${OPENAIR_NAS_DIR}/UE
|
||||
${OPENAIR_NAS_DIR}/UE/API/USIM
|
||||
${OPENAIR_NAS_DIR}/UE/EMM
|
||||
${OPENAIR_NAS_DIR}/COMMON/EMM/MSG
|
||||
@@ -409,7 +426,6 @@ target_include_directories(emm PRIVATE
|
||||
# esm LIB
|
||||
################################################################################
|
||||
set(esm_SRC
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/esm_main.c
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/DedicatedEpsBearerContextActivation.c
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/DefaultEpsBearerContextActivation.c
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/EpsBearerContextDeactivation.c
|
||||
@@ -452,6 +468,7 @@ set(esm_SRC
|
||||
)
|
||||
|
||||
set(esm_HDR
|
||||
${OPENAIR_TARGETS}/COMMON/openairinterface5g_limits.h
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/esm_main.h
|
||||
${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextAccept.h
|
||||
${OPENAIR_NAS_DIR}/COMMON/ESM/MSG/ActivateDedicatedEpsBearerContextReject.h
|
||||
@@ -481,13 +498,17 @@ set(esm_HDR
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_recv.h
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_sap.h
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/SAP/esm_send.h
|
||||
${OPENAIR_DIR}/common/utils/utils.h
|
||||
)
|
||||
|
||||
add_library(esm ${esm_SRC} ${esm_HDR})
|
||||
|
||||
target_include_directories(esm PRIVATE
|
||||
${OPENAIR_DIR}/common/utils
|
||||
${OPENAIR_NAS_DIR}/UE
|
||||
${OPENAIR_NAS_DIR}/UE/API/USER
|
||||
${OPENAIR_NAS_DIR}/UE/ESM
|
||||
${OPENAIR_TARGETS}/COMMON
|
||||
${OPENAIR_NAS_DIR}/COMMON/ESM/MSG
|
||||
${OPENAIR_NAS_DIR}/UE/ESM/SAP
|
||||
${OPENAIR_NAS_DIR}/COMMON/IES
|
||||
@@ -670,6 +691,9 @@ target_include_directories(ies PRIVATE
|
||||
# EXECUTABLE at_nas_ue
|
||||
################################################################################
|
||||
include_directories(
|
||||
${OPENAIR_TARGETS}/COMMON
|
||||
${OPENAIR_NAS_DIR}/UE
|
||||
${OPENAIR_DIR}/common/utils
|
||||
${OPENAIR_DIR}/common/utils/msc
|
||||
${OPENAIR3_DIR}/COMMON
|
||||
${OPENAIR3_DIR}/SECU
|
||||
@@ -691,6 +715,7 @@ ADD_EXECUTABLE(at_nas_ue ${OPENAIR_NAS_DIR}/UE/UEprocess.c
|
||||
${OPENAIR_NAS_DIR}/UE/nas_parser.c
|
||||
${OPENAIR_NAS_DIR}/UE/nas_proc.c
|
||||
${OPENAIR_NAS_DIR}/UE/nas_user.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
)
|
||||
|
||||
target_link_libraries (at_nas_ue
|
||||
|
||||
@@ -3,6 +3,9 @@ source oaienv
|
||||
cd cmake_targets
|
||||
rm -rf log
|
||||
mkdir -p log
|
||||
echo $PRE_BUILD
|
||||
bash -c "$PRE_BUILD"
|
||||
echo $BUILD_PROG $BUILD_ARGUMENTS
|
||||
$BUILD_PROG $BUILD_ARGUMENTS
|
||||
echo $PRE_EXEC
|
||||
bash -c "$PRE_EXEC"
|
||||
|
||||
+61
-25
@@ -57,17 +57,20 @@ CMAKE_BUILD_TYPE=""
|
||||
UE_AUTOTEST_TRACE="False"
|
||||
trap handle_ctrl_c INT
|
||||
|
||||
gen_nvram_path=$OPENAIR_DIR/targets/bin
|
||||
conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
|
||||
|
||||
function print_help() {
|
||||
echo_info '
|
||||
echo_info "
|
||||
This program installs OpenAirInterface Software
|
||||
You should have ubuntu 14.xx, updated, and the Linux kernel >= 3.14
|
||||
Options
|
||||
-h
|
||||
This help
|
||||
-c | --clean
|
||||
Erase all files to make a rebuild from start"
|
||||
Erase all files to make a rebuild from start
|
||||
-C | --clean-all
|
||||
Erase all files made by previous compilations, installations"
|
||||
Erase all files made by previous compilations, installations
|
||||
--clean-kernel
|
||||
Erase previously installed features in kernel: iptables, drivers, ...
|
||||
-I | --install-external-packages
|
||||
@@ -82,7 +85,11 @@ Options
|
||||
--eNB
|
||||
Makes the LTE softmodem
|
||||
--UE
|
||||
Makes the UE specific parts (ue_ip, usim, nvram)
|
||||
Makes the UE specific parts (ue_ip, usim, nvram) from the given configuration file
|
||||
--UE-conf-nvram [configuration file]
|
||||
Specify conf_nvram_path (default \"$conf_nvram_path\")
|
||||
--UE-gen-nvram [output path]
|
||||
Specify gen_nvram_path (default \"$gen_nvram_path\")
|
||||
--RRH
|
||||
Makes the RRH
|
||||
-a | --agent
|
||||
@@ -97,7 +104,7 @@ Options
|
||||
ETHERNET , None
|
||||
Adds this trasport protocol support in compilation
|
||||
--oaisim
|
||||
Makes the oaisim simulator. Hardware will be defaulted to "None".
|
||||
Makes the oaisim simulator. Hardware will be defaulted to \"None\".
|
||||
--phy_simulators
|
||||
Makes the unitary tests Layer 1 simulators
|
||||
--core_simulators
|
||||
@@ -140,11 +147,12 @@ Usage (first build):
|
||||
Usage (Regular):
|
||||
oaisim : ./build_oai --oaisim -x
|
||||
Eurecom EXMIMO + OAI ENB : ./build_oai --eNB -x
|
||||
NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP'
|
||||
NI/ETTUS B201 + OAI ENB : ./build_oai --eNB -x -w USRP"
|
||||
}
|
||||
|
||||
|
||||
function main() {
|
||||
|
||||
until [ -z "$1" ]
|
||||
do
|
||||
case "$1" in
|
||||
@@ -183,6 +191,12 @@ function main() {
|
||||
UE=1
|
||||
echo_info "Will compile UE"
|
||||
shift;;
|
||||
--UE-conf-nvram)
|
||||
conf_nvram_path=$(readlink -f "$1")
|
||||
shift 2;;
|
||||
--UE-gen-nvram)
|
||||
gen_nvram_path=$(readlink -f $2)
|
||||
shift 2;;
|
||||
--RRH)
|
||||
RRH=1
|
||||
echo_info "Will compile RRH"
|
||||
@@ -292,6 +306,10 @@ function main() {
|
||||
UE_AUTOTEST_TRACE="True"
|
||||
echo_info "Enabling autotest specific trace for UE"
|
||||
shift 1;;
|
||||
--uhd-images-dir)
|
||||
UHD_IMAGES_DIR=$2
|
||||
echo_info "Downloading UHD images in the indicated location"
|
||||
shift 2;;
|
||||
-h | --help)
|
||||
print_help
|
||||
exit 1;;
|
||||
@@ -362,6 +380,10 @@ function main() {
|
||||
echo_info "Flags for Deadline scheduler: $DEADLINE_SCHEDULER_FLAG_USER"
|
||||
echo_info "Flags for CPU Affinity: $CPU_AFFINITY_FLAG_USER"
|
||||
|
||||
if [ -n "$UHD_IMAGES_DIR" ] && [ -z "$INSTALL_EXTERNAL" ]; then
|
||||
echo_error "UHD images download settings will not be applied without -I present"
|
||||
exit
|
||||
fi
|
||||
############################################
|
||||
# setting and printing OAI envs, we should check here
|
||||
############################################
|
||||
@@ -399,7 +421,7 @@ function main() {
|
||||
echo_info "installing packages for USRP support"
|
||||
check_install_usrp_uhd_driver
|
||||
if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then
|
||||
install_usrp_uhd_driver
|
||||
install_usrp_uhd_driver $UHD_IMAGES_DIR
|
||||
fi
|
||||
fi
|
||||
if [ "$HW" == "OAI_BLADERF" ] ; then
|
||||
@@ -418,9 +440,9 @@ function main() {
|
||||
|
||||
if [ "$oaisim" = "1" ] ; then
|
||||
#to be discussed
|
||||
# there is no RF device and no transport protocol
|
||||
# there is no RF device transport protocol
|
||||
HW="None"
|
||||
TP="None"
|
||||
TP="ETHERNET"
|
||||
|
||||
if [ "$XFORMS" == "True" ] ; then
|
||||
PRINT_STATS="True"
|
||||
@@ -517,15 +539,17 @@ function main() {
|
||||
compilations \
|
||||
nas_sim_tools nvram \
|
||||
nvram $dbin/nvram
|
||||
compilations \
|
||||
nas_sim_tools conf2uedata \
|
||||
conf2uedata $dbin/conf2uedata
|
||||
|
||||
# generate USIM data
|
||||
if [ -f $dbin/nvram ]; then
|
||||
install_nas_tools $dbin $dconf
|
||||
if [ -f $dbin/conf2uedata ]; then
|
||||
install_nas_tools $conf_nvram_path $gen_nvram_path
|
||||
echo_info "Copying UE specific part to $DIR/$lte_build_dir/build"
|
||||
cp -Rvf $dbin/.ue_emm.nvram $DIR/$lte_build_dir/build
|
||||
cp -Rvf $dbin/.ue.nvram $DIR/$lte_build_dir/build
|
||||
cp -Rvf $dbin/.usim.nvram $DIR/$lte_build_dir/build
|
||||
|
||||
cp -Rvf $dbin/.ue_emm.nvram0 $DIR/$lte_build_dir/build
|
||||
cp -Rvf $dbin/.ue.nvram0 $DIR/$lte_build_dir/build
|
||||
cp -Rvf $dbin/.usim.nvram0 $DIR/$lte_build_dir/build
|
||||
else
|
||||
echo_warning "not generated UE NAS files: binaries not found"
|
||||
fi
|
||||
@@ -647,10 +671,13 @@ function main() {
|
||||
compilations \
|
||||
nas_sim_tools nvram \
|
||||
nvram $dbin/nvram
|
||||
compilations \
|
||||
nas_sim_tools conf2uedata \
|
||||
conf2uedata $dbin/conf2uedata
|
||||
|
||||
# generate USIM data
|
||||
if [ -f $dbin/nvram ]; then
|
||||
install_nas_tools $dbin $dconf
|
||||
if [ -f $dbin/conf2uedata ]; then
|
||||
install_nas_tools $conf_nvram_path $gen_nvram_path
|
||||
else
|
||||
echo_warning "not generated UE NAS files: binaries not found"
|
||||
fi
|
||||
@@ -671,6 +698,15 @@ function main() {
|
||||
# CMakeFiles/oai_nw_drv/oai_nw_drv.ko $dbin/oai_nw_drv.ko
|
||||
fi
|
||||
|
||||
if [ "$TP" == "ETHERNET" ] ; then
|
||||
compilations \
|
||||
$oaisim_build_dir oai_eth_transpro \
|
||||
liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
|
||||
ln -sf liboai_eth_transpro.so liboai_transpro.so
|
||||
ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
|
||||
echo_info "liboai_transpro.so is linked with ETHERNET library"
|
||||
fi
|
||||
|
||||
cmake_file=$DIR/oaisim_mme_build_oai/CMakeLists.txt
|
||||
cp $DIR/oaisim_mme_build_oai/CMakeLists.template $cmake_file
|
||||
echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
|
||||
@@ -754,8 +790,8 @@ function main() {
|
||||
liboai_usrpdevif.so $dbin/liboai_usrpdevif.so.$REL
|
||||
fi
|
||||
|
||||
ln -s liboai_usrpdevif.so liboai_device.so
|
||||
ln -s $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
|
||||
ln -sf liboai_usrpdevif.so liboai_device.so
|
||||
ln -sf $dbin/liboai_usrpdevif.so.$REL $dbin/liboai_device.so
|
||||
echo_info "liboai_device.so is linked to USRP device library"
|
||||
elif [ "$HW" == "OAI_BLADERF" ] ; then
|
||||
if [ -f "/usr/include/libbladeRF.h" ] ; then
|
||||
@@ -764,8 +800,8 @@ function main() {
|
||||
liboai_bladerfdevif.so $dbin/liboai_bladerfdevif.so.$REL
|
||||
fi
|
||||
|
||||
ln -s liboai_bladerfdevif.so liboai_device.so
|
||||
ln -s $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
|
||||
ln -sf liboai_bladerfdevif.so liboai_device.so
|
||||
ln -sf $dbin/liboai_bladerfdevif.so.$REL $dbin/liboai_device.so
|
||||
echo_info "liboai_device.so is linked to BLADERF device library"
|
||||
elif [ "$HW" == "OAI_LMSSDR" ] ; then
|
||||
# if [ -f "/usr/include/libbladeRF.h" ] ; then
|
||||
@@ -774,8 +810,8 @@ function main() {
|
||||
liboai_lmssdrdevif.so $dbin/liboai_lmssdrdevif.so.$REL
|
||||
# fi
|
||||
|
||||
ln -s liboai_lmssdrdevif.so liboai_device.so
|
||||
ln -s $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
|
||||
ln -sf liboai_lmssdrdevif.so liboai_device.so
|
||||
ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so
|
||||
echo_info "liboai_device.so is linked to LMSSDR device library"
|
||||
else
|
||||
echo_info "liboai_device.so is not linked to any device library"
|
||||
@@ -791,8 +827,8 @@ function main() {
|
||||
compilations \
|
||||
$build_dir oai_eth_transpro \
|
||||
liboai_eth_transpro.so $dbin/liboai_eth_transpro.so.$REL
|
||||
ln -s liboai_eth_transpro.so liboai_transpro.so
|
||||
ln -s $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
|
||||
ln -sf liboai_eth_transpro.so liboai_transpro.so
|
||||
ln -sf $dbin/liboai_eth_transpro.so.$REL $dbin/liboai_transpro.so
|
||||
echo_info "liboai_transpro.so is linked with ETHERNET library"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -2,70 +2,89 @@ cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(NAS_SIM_TOOLS)
|
||||
|
||||
include(FindPkgConfig)
|
||||
pkg_search_module(CONFIG libconfig REQUIRED)
|
||||
include_directories(${CONFIG_INCLUDE_DIRS})
|
||||
add_definitions(-std=gnu99)
|
||||
|
||||
ENABLE_LANGUAGE(C)
|
||||
#Sends the -std=c99 flag to the gcc compiler
|
||||
add_definitions(-std=c99)
|
||||
add_definitions(-DNAS_UE)
|
||||
|
||||
set(CMAKE_C_FLAGS
|
||||
"${CMAKE_C_FLAGS} ${C_FLAGS_PROCESSOR} -Werror -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -g")
|
||||
|
||||
set(OPENAIR_DIR $ENV{OPENAIR_DIR})
|
||||
set(OPENAIR1_DIR $ENV{OPENAIR_DIR}/openair1)
|
||||
set(OPENAIR2_DIR $ENV{OPENAIR_DIR}/openair2)
|
||||
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
|
||||
set(OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3)
|
||||
set(OPENAIR_TARGETS $ENV{OPENAIR_DIR}/targets)
|
||||
|
||||
#set(EXECUTABLE_OUTPUT_PATH ${OPENAIR_DIR}/targets/bin)
|
||||
|
||||
|
||||
# Add .h files for dependancies
|
||||
set(usim_SRC
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/usim_data.c
|
||||
set(CONF2UEDATA_LIB_SRC
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_data.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_usim.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_network.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_user_plmn.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_parser.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/fs.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/display.c
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.c
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.c
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.c
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
)
|
||||
set(usim_HDR
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/network.h
|
||||
|
||||
set(conf2uedata_HDR
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.h
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf_emm.h
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/usim_api.h
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM/aka_functions.h
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.h
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/OctetString.h
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/TLVEncoder.h
|
||||
${OPENAIR_DIR}/common/utils/utils.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${OPENAIR_DIR}/common/utils
|
||||
${OPENAIR_DIR}/openair3/NAS/UE
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USER
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/API/USIM
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/EMM/
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/ESM/
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/IES/
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL
|
||||
)
|
||||
ADD_EXECUTABLE(usim ${usim_SRC} ${usim_HDR})
|
||||
|
||||
# conf2uedata binary
|
||||
|
||||
set(conf2uedata_SRC
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/conf2uedata.c
|
||||
${CONF2UEDATA_LIB_SRC}
|
||||
)
|
||||
|
||||
add_executable(conf2uedata ${conf2uedata_SRC} ${conf2uedata_HDR} )
|
||||
target_link_libraries(conf2uedata ${CONFIG_LIBRARIES})
|
||||
|
||||
# usim binary
|
||||
|
||||
set(usim_SRC
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/usim.c
|
||||
${CONF2UEDATA_LIB_SRC}
|
||||
)
|
||||
|
||||
|
||||
add_executable(usim ${usim_SRC} ${conf2uedata_HDR} )
|
||||
target_link_libraries(usim ${CONFIG_LIBRARIES})
|
||||
|
||||
# nvram binary
|
||||
|
||||
set(nvram_SRC
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/ue_data.c
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.c
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/nas_log.c
|
||||
${OPENAIR_DIR}/openair3/NAS/TOOLS/nvram.c
|
||||
${CONF2UEDATA_LIB_SRC}
|
||||
)
|
||||
|
||||
set(nvram_HDR
|
||||
${OPENAIR_DIR}/openair3/NAS/UE/EMM/emmData.h
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/UTIL/memory.h
|
||||
${OPENAIR_DIR}/openair3/NAS/COMMON/userDef.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(nvram ${nvram_SRC} ${nvram_HDR})
|
||||
|
||||
#install (TARGETS usim DESTINATION ${EXECUTABLE_OUTPUT_PATH})
|
||||
#install (TARGETS nvram DESTINATION ${EXECUTABLE_OUTPUT_PATH})
|
||||
|
||||
#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/nvram --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)")
|
||||
#install(CODE "EXECUTE_PROCESS (COMMAND ${OPENAIR_TARGETS}/bin/usim --gen WORKING_DIRECTORY ${OPENAIR_TARGETS}/bin)")
|
||||
add_executable(nvram ${nvram_SRC} ${conf2uedata_HDR} )
|
||||
target_link_libraries(nvram ${CONFIG_LIBRARIES})
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
export UHD_IMAGES_DIR=$SNAP/uhd_images
|
||||
exec $@
|
||||
@@ -171,7 +171,7 @@ install_protobuf_from_source(){
|
||||
echo "Downloading protobuf"
|
||||
rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
|
||||
wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
|
||||
tar -xzvf protobuf-2.6.1.tar.gz
|
||||
tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
|
||||
cd protobuf-2.6.1/
|
||||
./configure
|
||||
echo "Compiling protobuf"
|
||||
@@ -208,15 +208,19 @@ check_install_usrp_uhd_driver(){
|
||||
#The new USRP repository
|
||||
$SUDO add-apt-repository ppa:ettusresearch/uhd -y
|
||||
$SUDO apt-get update
|
||||
$SUDO apt-get -y install python python-tk libboost-all-dev libusb-1.0-0-dev
|
||||
$SUDO apt-get -y install libuhd-dev libuhd003 uhd-host
|
||||
$SUDO apt-get -y --allow-unauthenticated install python python-tk libboost-all-dev libusb-1.0-0-dev
|
||||
$SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host
|
||||
}
|
||||
|
||||
install_usrp_uhd_driver() {
|
||||
# We move uhd-host apart because it depends on linux kernel version
|
||||
# On newer kernels, it fails to install
|
||||
$SUDO apt-get -y install uhd-host
|
||||
$SUDO uhd_images_downloader
|
||||
if [ -z $1 ]; then
|
||||
$SUDO uhd_images_downloader
|
||||
else
|
||||
$SUDO uhd_images_downloader -i $1
|
||||
fi
|
||||
}
|
||||
|
||||
check_install_bladerf_driver(){
|
||||
@@ -224,9 +228,9 @@ check_install_bladerf_driver(){
|
||||
$SUDO add-apt-repository -y ppa:bladerf/bladerf
|
||||
$SUDO apt-get update
|
||||
fi
|
||||
$SUDO apt-get install -y bladerf libbladerf-dev
|
||||
$SUDO apt-get install -y bladerf-firmware-fx3
|
||||
$SUDO apt-get install -y bladerf-fpga-hostedx40
|
||||
$SUDO apt-get install -y--allow-unauthenticated bladerf libbladerf-dev
|
||||
$SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3
|
||||
$SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40
|
||||
}
|
||||
|
||||
flash_firmware_bladerf() {
|
||||
@@ -450,19 +454,18 @@ install_asn1c_from_source(){
|
||||
################################################
|
||||
|
||||
install_nas_tools() {
|
||||
cd $1
|
||||
if [ ! -f .ue.nvram ]; then
|
||||
if [ ! -f .ue.nvram0 ]; then
|
||||
echo_success "generate .ue_emm.nvram .ue.nvram"
|
||||
./nvram --gen
|
||||
./nvram --gen -c $1 -o $2
|
||||
else
|
||||
[ ./nvram -nt .ue.nvram -o ./nvram -nt .ue_emm.nvram ] && ./nvram --gen
|
||||
[ ./nvram -nt .ue.nvram0 -o ./nvram -nt .ue_emm.nvram0 ] && ./nvram --gen -c $1 -o $2
|
||||
fi
|
||||
|
||||
if [ ! -f .usim.nvram ]; then
|
||||
if [ ! -f .usim.nvram0 ]; then
|
||||
echo_success "generate .usim.nvram"
|
||||
./usim --gen
|
||||
./usim --gen -c $1 -o $2
|
||||
else
|
||||
[ ./usim -nt .usim.nvram ] && ./usim --gen
|
||||
[ ./usim -nt .usim.nvram0 ] && ./usim --gen -c $1 -o $2
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
@@ -247,12 +247,6 @@ function main()
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "200 lte " >> /etc/iproute2/rt_tables
|
||||
fi
|
||||
ip rule add fwmark 1 table lte
|
||||
ifconfig oip1 up
|
||||
ip route add default dev oip1 table lte
|
||||
# the actual IP address depends on the EPC/MME config file for address pool
|
||||
ip route add from 192.188.0.0/24 table lte
|
||||
ip route add to 192.188.0.0/24 table lte
|
||||
|
||||
exe_arguments="$exe_arguments -s15 -AAWGN -y1 -b1 -u1 -Q0"
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
export KERNEL_DIR=/lib/modules/$(shell uname -r)/
|
||||
CC=gcc
|
||||
CCC=gcc
|
||||
linux := $(shell if [ `uname` = "Linux" ] ; then echo "1" ; else echo "0" ; fi)
|
||||
|
||||
|
||||
CFLAGS += -std=gnu99
|
||||
CFLAGS += -Wall -g -ggdb -Wstrict-prototypes -fno-strict-aliasing
|
||||
|
||||
# Need to force this option because default kernel module builder is wrong
|
||||
CFLAGS += $(call cc-option,-mpreferred-stack-boundary=4)
|
||||
|
||||
#For performance, if some option doesn't exist in all gcc versions, use $(call cc-option,MY_OPTION)
|
||||
#CFLAGS += -O2
|
||||
#CFLAGS += -funroll-loops
|
||||
CFLAGS += -Wno-packed-bitfield-compat
|
||||
|
||||
# This is the minimum CPU faetures for OAI
|
||||
CFLAGS += -mmmx -msse -msse2 -mssse3 -msse4.1
|
||||
# Add CPU features from local CPU
|
||||
#CFLAGS += -march=native
|
||||
|
||||
ifeq ($(OSTYPE),Cygwin)
|
||||
cygwin=1
|
||||
CFLAGS += -DCYGWIN
|
||||
else
|
||||
cygwin=0
|
||||
endif
|
||||
|
||||
ifeq ($(linux),1)
|
||||
CFLAGS +=
|
||||
LDFLAGS +=
|
||||
endif
|
||||
|
||||
ITTI_DIR = $(COMMON_UTILS_DIR)/itti
|
||||
|
||||
ITTI_OBJS = $(ITTI_DIR)/intertask_interface.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/intertask_interface_dump.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/backtrace.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/memory_pools.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/signals.o
|
||||
ITTI_OBJS += $(ITTI_DIR)/timer.o
|
||||
|
||||
|
||||
HASHTABLE_DIR = $(COMMON_UTILS_DIR)/collection/hashtable
|
||||
MSC_DIR = $(COMMON_UTILS_DIR)/msc
|
||||
|
||||
HASHTABLE_OBJS = $(HASHTABLE_DIR)/hashtable.o
|
||||
HASHTABLE_OBJS += $(HASHTABLE_DIR)/obj_hashtable.o
|
||||
|
||||
UTILS_OBJS = $(ITTI_OBJS) $(HASHTABLE_OBJS)
|
||||
|
||||
UTILS_incl = \
|
||||
-I$(COMMON_UTILS_DIR) \
|
||||
-I$(HASHTABLE_DIR) \
|
||||
-I$(ITTI_DIR) \
|
||||
-I$(MSC_DIR)
|
||||
|
||||
print-% : ; @echo $* = $($*)
|
||||
@@ -184,8 +184,30 @@ extern T_cache_t *T_cache;
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* we have 4 versions of T_HEADER:
|
||||
* - bad quality C++ version with time
|
||||
* - good quality C version with time
|
||||
* - bad quality C++ version without time
|
||||
* - good quality C version without time
|
||||
*/
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* C++ version of T_HEADER with time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
struct timespec T_HEADER_time; \
|
||||
if (clock_gettime(CLOCK_REALTIME, &T_HEADER_time)) abort(); \
|
||||
memcpy(T_LOCAL_buf, &T_HEADER_time, sizeof(struct timespec)); \
|
||||
T_LOCAL_size += sizeof(struct timespec); \
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#else /* #ifdef __cplusplus */
|
||||
|
||||
/* C version of T_HEADER with time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
|
||||
@@ -201,8 +223,21 @@ extern T_cache_t *T_cache;
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#else /* #ifdef T_SEND_TIME */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* C++ version of T_HEADER without time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#else /* #ifdef __cplusplus */
|
||||
|
||||
/* C version of T_HEADER without time */
|
||||
#define T_HEADER(x) \
|
||||
do { \
|
||||
if (!__builtin_types_compatible_p(typeof(x), struct T_header *)) { \
|
||||
@@ -214,6 +249,8 @@ extern T_cache_t *T_cache;
|
||||
T_PUT_int(1, (int)(uintptr_t)(x)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif /* #ifdef T_SEND_TIME */
|
||||
|
||||
#define T1(t) \
|
||||
|
||||
@@ -65,7 +65,7 @@ _Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
|
||||
|
||||
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %"PRIdMAX"\n"#vALUE2": %"PRIdMAX"\n"#vALUE3": %"PRIdMAX"\n"#vALUE4": %"PRIdMAX"\n\n", \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
|
||||
|
||||
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _TIME_UTILS_H_
|
||||
#define _TIME_UTILS_H_
|
||||
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end)
|
||||
{
|
||||
struct timespec temp;
|
||||
int64_t temp_ns;
|
||||
|
||||
if ((end.tv_nsec-start.tv_nsec)<0) {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec-1;
|
||||
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
|
||||
} else {
|
||||
temp.tv_sec = end.tv_sec-start.tv_sec;
|
||||
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
|
||||
}
|
||||
temp_ns = (int64_t)(temp.tv_sec) * (int64_t)1000000000 + (temp.tv_nsec);
|
||||
return temp_ns;
|
||||
}
|
||||
|
||||
#endif /* _TIME_UTILS_H_ */
|
||||
@@ -0,0 +1,107 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include "utils.h"
|
||||
|
||||
void *calloc_or_fail(size_t size) {
|
||||
void *ptr = calloc(1, size);
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "[UE] Failed to calloc %zu bytes", size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *malloc_or_fail(size_t size) {
|
||||
void *ptr = malloc(size);
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "[UE] Failed to malloc %zu bytes", size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: hex_char_to_hex_value() **
|
||||
** **
|
||||
** Description: Converts an hexadecimal ASCII coded digit into its value. **
|
||||
** **
|
||||
** Inputs: c: A char holding the ASCII coded value **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: None **
|
||||
** Return: Converted value (-1 on error) **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int hex_char_to_hex_value (char c)
|
||||
{
|
||||
if (!((c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F') ||
|
||||
(c >= '0' && c <= '9')))
|
||||
return -1;
|
||||
|
||||
if (c >= 'A') {
|
||||
/* Remove case bit */
|
||||
c &= ~('a' ^ 'A');
|
||||
|
||||
return (c - 'A' + 10);
|
||||
} else {
|
||||
return (c - '0');
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: hex_string_to_hex_value() **
|
||||
** **
|
||||
** Description: Converts an hexadecimal ASCII coded string into its value.**
|
||||
** **
|
||||
** Inputs: hex_value: A pointer to the location to store the **
|
||||
** conversion result **
|
||||
** size: The size of hex_value in bytes **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: hex_value: Converted value **
|
||||
** Return: 0 on success, -1 on error **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strlen(hex_string) != size*2) {
|
||||
fprintf(stderr, "the string '%s' should be of length %d\n", hex_string, size*2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i < size; i++) {
|
||||
int a = hex_char_to_hex_value(hex_string[2 * i]);
|
||||
int b = hex_char_to_hex_value(hex_string[2 * i + 1]);
|
||||
if (a == -1 || b == -1) goto error;
|
||||
hex_value[i] = (a << 4) | b;
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fprintf(stderr, "the string '%s' is not a valid hexadecimal string\n", hex_string);
|
||||
for (i=0; i < size; i++)
|
||||
hex_value[i] = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *itoa(int i) {
|
||||
char buffer[64];
|
||||
int ret;
|
||||
|
||||
ret = snprintf(buffer, sizeof(buffer), "%d",i);
|
||||
if ( ret <= 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(buffer);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
void *calloc_or_fail(size_t size);
|
||||
void *malloc_or_fail(size_t size);
|
||||
|
||||
// Converts an hexadecimal ASCII coded digit into its value. **
|
||||
int hex_char_to_hex_value (char c);
|
||||
// Converts an hexadecimal ASCII coded string into its value.**
|
||||
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
|
||||
|
||||
char *itoa(int i);
|
||||
|
||||
#endif
|
||||
@@ -1411,7 +1411,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
|
||||
common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff/fp->nb_antennas_tx;
|
||||
}
|
||||
#ifdef DEBUG_PHY
|
||||
msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%d bytes)\n",
|
||||
msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%zu bytes)\n",
|
||||
eNB_id,i,j,common_vars->beam_weights[eNB_id][i][j],
|
||||
fp->ofdm_symbol_size*sizeof(int32_t));
|
||||
#endif
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
#ifdef USER_MODE
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
@@ -581,10 +581,10 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
|
||||
*peak_val_out = peak_val;
|
||||
|
||||
if (peak_val <= (40*(uint32_t)mean_val)) {
|
||||
LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%u,%u)\n",peak_pos,peak_val,mean_val,40*mean_val);
|
||||
LOG_D(PHY,"[SYNC TIME] No peak found (%u,%u,%"PRIu64",%"PRIu64")\n",peak_pos,peak_val,mean_val,40*mean_val);
|
||||
return(-1);
|
||||
} else {
|
||||
LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %u\n",peak_pos,peak_val,mean_val);
|
||||
LOG_D(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val);
|
||||
return(peak_pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -3972,6 +3972,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
|
||||
LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
|
||||
|
||||
if (!dlsch[0]) return -1;
|
||||
|
||||
#ifdef DEBUG_DCI
|
||||
LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n",
|
||||
rnti,
|
||||
@@ -4001,6 +4003,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
break;
|
||||
|
||||
case format1A:
|
||||
if (!dlsch[0]) return -1;
|
||||
|
||||
switch (frame_parms->N_RB_DL) {
|
||||
case 6:
|
||||
@@ -4042,7 +4045,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
|
||||
NPRB = RIV2nb_rb_LUT6[rballoc];
|
||||
dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3];
|
||||
|
||||
}
|
||||
|
||||
@@ -4100,9 +4102,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
|
||||
NPRB = RIV2nb_rb_LUT25[rballoc];
|
||||
dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
|
||||
dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3];
|
||||
|
||||
}
|
||||
|
||||
if (vrb_type == LOCALIZED) {
|
||||
@@ -4156,9 +4155,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
|
||||
NPRB = RIV2nb_rb_LUT50[rballoc];
|
||||
dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
|
||||
dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3];
|
||||
|
||||
}
|
||||
|
||||
if (vrb_type == LOCALIZED) {
|
||||
@@ -4226,9 +4222,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
|
||||
NPRB = RIV2nb_rb_LUT100[rballoc];
|
||||
dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
|
||||
dlsch[0]->g_pucch += delta_PUCCH_lut[TPC&3];
|
||||
|
||||
}
|
||||
|
||||
if (vrb_type == LOCALIZED) {
|
||||
@@ -4329,6 +4322,9 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
dlsch0_harq->first_tx,
|
||||
dlsch0_harq->status,
|
||||
dlsch0_harq->round);
|
||||
|
||||
dlsch[0]->active = 1;
|
||||
|
||||
if ((ndi!=dlsch0_harq->DCINdi)|| // DCI has been toggled or this is the first transmission
|
||||
|
||||
(dlsch0_harq->first_tx==1)) {
|
||||
@@ -4403,10 +4399,15 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
}
|
||||
dlsch[0]->rnti = rnti;
|
||||
dlsch0 = dlsch[0];
|
||||
|
||||
if (dlsch0_harq->round == 0)
|
||||
dlsch0_harq->status = ACTIVE;
|
||||
|
||||
//printf("Format 1A: harq_pid %d, nb_rb %d, round %d\n",harq_pid,dlsch0_harq->nb_rb,dlsch0_harq->round);
|
||||
break;
|
||||
|
||||
case format1C:
|
||||
if (!dlsch[0]) return -1;
|
||||
|
||||
harq_pid = 0;
|
||||
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
|
||||
@@ -4523,7 +4524,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
|
||||
dlsch0_harq->dl_power_off = 1; //no power offset
|
||||
|
||||
// Needs to be checked
|
||||
dlsch0_harq->codeword=0;
|
||||
|
||||
LOG_D(PHY,"UE (%x/%d): Subframe %d Format1C DCI: harq_status %d, round %d\n",
|
||||
@@ -4543,6 +4543,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
break;
|
||||
|
||||
case format1:
|
||||
if (!dlsch[0]) return -1;
|
||||
|
||||
switch (frame_parms->N_RB_DL) {
|
||||
case 6:
|
||||
@@ -4630,13 +4631,13 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
break;
|
||||
}
|
||||
|
||||
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
|
||||
|
||||
if (harq_pid>=8) {
|
||||
LOG_E(PHY,"Format 1: harq_pid=%d >= 8\n", harq_pid);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
|
||||
|
||||
if((mcs>28) && (dlsch0_harq->round == 0) )
|
||||
{
|
||||
// DCI false detection
|
||||
@@ -4649,7 +4650,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
|
||||
dlsch[0]->current_harq_pid = harq_pid;
|
||||
@@ -4685,7 +4685,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
|
||||
dlsch0_harq->dl_power_off = 1; //no power offset
|
||||
|
||||
// Needs to be checked
|
||||
dlsch0_harq->codeword=0;
|
||||
|
||||
LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi,
|
||||
@@ -4696,7 +4695,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
(dlsch0_harq->first_tx==1)) {
|
||||
// printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx);
|
||||
dlsch0_harq->round=0;
|
||||
dlsch0_harq->status = ACTIVE;
|
||||
dlsch0_harq->DCINdi = ndi;
|
||||
|
||||
dlsch[0]->harq_ack[subframe].send_harq_status = 1;
|
||||
@@ -4706,8 +4704,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
}
|
||||
}
|
||||
|
||||
dlsch0_harq->mcs = mcs;
|
||||
|
||||
// this a retransmission
|
||||
if(dlsch0_harq->round)
|
||||
{
|
||||
@@ -4722,18 +4718,25 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
}
|
||||
}
|
||||
|
||||
dlsch0_harq->TBS = TBStable[get_I_TBS(mcs)][NPRB-1];
|
||||
if (mcs <= 28)
|
||||
dlsch0_harq->Qm = get_Qm(mcs);
|
||||
else if (mcs<=31)
|
||||
dlsch0_harq->Qm = (mcs-28)<<1;
|
||||
else
|
||||
LOG_E(PHY,"invalid mcs %d\n",mcs);
|
||||
// printf("test: MCS %d, NPRB %d, TBS %d\n",mcs,NPRB,dlsch0_harq->TBS);
|
||||
dlsch[0]->current_harq_pid = harq_pid;
|
||||
|
||||
dlsch[0]->active = 1;
|
||||
|
||||
if (dlsch0_harq->round == 0) {
|
||||
dlsch0_harq->status = ACTIVE;
|
||||
// printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
|
||||
// MCS and TBS don't change across HARQ rounds
|
||||
dlsch0_harq->mcs = mcs;
|
||||
dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];
|
||||
|
||||
if (mcs <= 28)
|
||||
dlsch0_harq->Qm = get_Qm(mcs);
|
||||
else if (mcs<=31)
|
||||
dlsch0_harq->Qm = (mcs-28)<<1;
|
||||
else
|
||||
LOG_E(PHY,"invalid mcs %d\n",mcs);
|
||||
}
|
||||
|
||||
dlsch[0]->rnti = rnti;
|
||||
|
||||
if (beamforming_mode == 0)
|
||||
@@ -5142,12 +5145,10 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
|
||||
if (dlsch0_harq != NULL) {
|
||||
dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
dlsch0->g_pucch += delta_PUCCH_lut[TPC&3];
|
||||
}
|
||||
|
||||
if (dlsch1_harq != NULL) {
|
||||
dlsch1_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];
|
||||
dlsch1->g_pucch += delta_PUCCH_lut[TPC&3];
|
||||
}
|
||||
|
||||
// assume one layer per codeword (2 antenna port case)
|
||||
@@ -5859,6 +5860,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
|
||||
break;
|
||||
|
||||
case format1E_2A_M10PRB:
|
||||
if (!dlsch[0]) return -1;
|
||||
|
||||
harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid;
|
||||
|
||||
@@ -7920,8 +7922,8 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
|
||||
rb_alloc = rballoc;
|
||||
|
||||
if (rb_alloc>RIV_max) {
|
||||
LOG_E(PHY,"Format 0: rb_alloc > RIV_max\n");
|
||||
mac_xface->macphy_exit("Format 0: rb_alloc > RIV_max\n");
|
||||
LOG_E(PHY,"Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max);
|
||||
mac_xface->macphy_exit("Format 0: error");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "SCHED/defs.h"
|
||||
#include "defs.h"
|
||||
#include "UTIL/LOG/vcd_signal_dumper.h"
|
||||
#include "UTIL/LOG/log.h"
|
||||
#include <syscall.h>
|
||||
|
||||
//#define DEBUG_DLSCH_CODING
|
||||
//#define DEBUG_DLSCH_FREE 1
|
||||
@@ -347,6 +349,8 @@ int dlsch_encoding_2threads0(te_params *tep) {
|
||||
|
||||
extern int oai_exit;
|
||||
void *te_thread(void *param) {
|
||||
pthread_setname_np( pthread_self(),"te processing");
|
||||
LOG_I(PHY,"thread te created id=%ld", syscall(__NR_gettid));
|
||||
|
||||
eNB_proc_t *proc = &((te_params *)param)->eNB->proc;
|
||||
while (!oai_exit) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -59,3 +59,5 @@ typedef struct IF5_mobipass_header IF5_mobipass_header_t;
|
||||
void send_IF5(PHY_VARS_eNB*, openair0_timestamp, int, uint8_t*, uint16_t);
|
||||
|
||||
void recv_IF5(PHY_VARS_eNB*, openair0_timestamp*, int, uint16_t);
|
||||
|
||||
void malloc_IF5_buffer(PHY_VARS_eNB*);
|
||||
|
||||
@@ -1375,11 +1375,7 @@ void rx_phich(PHY_VARS_UE *ue,
|
||||
HI16,
|
||||
nseq_PHICH,
|
||||
ngroup_PHICH);
|
||||
get_Msg3_alloc_ret(&ue->frame_parms,
|
||||
subframe,
|
||||
proc->frame_rx,
|
||||
&ue->ulsch_Msg3_frame[eNB_id],
|
||||
&ue->ulsch_Msg3_subframe[eNB_id]);
|
||||
|
||||
ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
|
||||
// ulsch->harq_processes[harq_pid]->Ndi = 0;
|
||||
ulsch->harq_processes[harq_pid]->round++;
|
||||
@@ -1393,7 +1389,7 @@ void rx_phich(PHY_VARS_UE *ue,
|
||||
}
|
||||
} else {
|
||||
//#ifdef DEBUG_PHICH
|
||||
LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d (Mlimit %d)\n",
|
||||
LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n",
|
||||
ue->Mod_id,harq_pid,
|
||||
proc->frame_rx%1024,
|
||||
subframe,
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/LTE_TRANSPORT/uespec_pilots.c
|
||||
* \brief Top-level routines for generating DL ue-specific reference signals V12.5 2015-03
|
||||
|
||||
@@ -19,134 +19,132 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "PHY/defs.h"
|
||||
#include "PHY/impl_defs_lte.h"
|
||||
|
||||
//#define DEBUG_PC 0
|
||||
/*
|
||||
double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0},
|
||||
{ 5.0/4.0,1.0,3.0/4.0,1.0/2.0}};
|
||||
*/
|
||||
|
||||
double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db
|
||||
{ 0.96910, 0.00000, -1.24939, -3.01030}};
|
||||
|
||||
double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers
|
||||
|
||||
double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated)
|
||||
{
|
||||
#include "PHY/defs.h"
|
||||
#include "PHY/impl_defs_lte.h"
|
||||
|
||||
//#define DEBUG_PC 0
|
||||
/*
|
||||
double ratioPB[2][4]={{ 1.0,4.0/5.0,3.0/5.0,2.0/5.0},
|
||||
{ 5.0/4.0,1.0,3.0/4.0,1.0/2.0}};
|
||||
*/
|
||||
|
||||
double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db
|
||||
{ 0.96910, 0.00000, -1.24939, -3.01030}};
|
||||
|
||||
double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers
|
||||
|
||||
double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated)
|
||||
{
|
||||
if (pdsch_config_dedicated)
|
||||
return(pa_values[ pdsch_config_dedicated->p_a]);
|
||||
return(pa_values[ pdsch_config_dedicated->p_a]);
|
||||
else
|
||||
return(0.0);
|
||||
}
|
||||
|
||||
double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port){
|
||||
double rho_a_dB;
|
||||
double sqrt_rho_a_lin;
|
||||
|
||||
}
|
||||
|
||||
double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port){
|
||||
double rho_a_dB;
|
||||
double sqrt_rho_a_lin;
|
||||
|
||||
rho_a_dB = get_pa_dB(pdsch_config_dedicated);
|
||||
|
||||
if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5
|
||||
rho_a_dB-=10*log10(2);
|
||||
|
||||
if(n_antenna_port==4) // see TS 36.213 Section 5.2
|
||||
rho_a_dB=+10*log10(2);
|
||||
|
||||
sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
|
||||
|
||||
dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
|
||||
|
||||
#if DEBUG_PC
|
||||
printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a);
|
||||
#endif
|
||||
|
||||
return(rho_a_dB);
|
||||
}
|
||||
|
||||
double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
PDSCH_CONFIG_COMMON *pdsch_config_common,
|
||||
uint8_t n_antenna_port,
|
||||
LTE_eNB_DLSCH_t *dlsch_eNB,
|
||||
int dl_power_off)
|
||||
{
|
||||
|
||||
double rho_a_dB, rho_b_dB;
|
||||
double sqrt_rho_b_lin;
|
||||
|
||||
rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port);
|
||||
|
||||
if(n_antenna_port>1)
|
||||
rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
|
||||
else
|
||||
rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
|
||||
|
||||
sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
|
||||
|
||||
dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
|
||||
|
||||
#ifdef DEBUG_PC
|
||||
printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pdsch_config_common->p_b,ratioPB[1][pdsch_config_common->p_b],dlsch_eNB->sqrt_rho_b);
|
||||
#endif
|
||||
return(rho_b_dB);
|
||||
}
|
||||
|
||||
|
||||
double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
LTE_UE_DLSCH_t *dlsch_ue,
|
||||
unsigned char dl_power_off,
|
||||
uint8_t n_antenna_port
|
||||
){
|
||||
|
||||
double rho_a_dB;
|
||||
double sqrt_rho_a_lin;
|
||||
|
||||
|
||||
if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5
|
||||
rho_a_dB-=10*log10(2);
|
||||
|
||||
if(n_antenna_port==4) // see TS 36.213 Section 5.2
|
||||
rho_a_dB=+10*log10(2);
|
||||
|
||||
sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
|
||||
|
||||
dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
|
||||
|
||||
#if DEBUG_PC
|
||||
printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a);
|
||||
#endif
|
||||
|
||||
return(rho_a_dB);
|
||||
}
|
||||
|
||||
double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
PDSCH_CONFIG_COMMON *pdsch_config_common,
|
||||
uint8_t n_antenna_port,
|
||||
LTE_eNB_DLSCH_t *dlsch_eNB,
|
||||
int dl_power_off)
|
||||
{
|
||||
|
||||
double rho_a_dB, rho_b_dB;
|
||||
double sqrt_rho_b_lin;
|
||||
|
||||
rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port);
|
||||
|
||||
if(n_antenna_port>1)
|
||||
rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
|
||||
else
|
||||
rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
|
||||
|
||||
sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
|
||||
|
||||
dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
|
||||
|
||||
#ifdef DEBUG_PC
|
||||
printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pdsch_config_common->p_b,ratioPB[1][pdsch_config_common->p_b],dlsch_eNB->sqrt_rho_b);
|
||||
#endif
|
||||
return(rho_b_dB);
|
||||
}
|
||||
|
||||
|
||||
double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
LTE_UE_DLSCH_t *dlsch_ue,
|
||||
unsigned char dl_power_off,
|
||||
uint8_t n_antenna_port
|
||||
){
|
||||
|
||||
double rho_a_dB;
|
||||
double sqrt_rho_a_lin;
|
||||
|
||||
rho_a_dB = get_pa_dB(pdsch_config_dedicated);
|
||||
|
||||
if(!dl_power_off)
|
||||
rho_a_dB-=10*log10(2);
|
||||
//if dl_power_offset is 0, this is for MU-interference, TM5. But in practice UE may assume 16 or 64QAM TM4 as multiuser
|
||||
|
||||
if(n_antenna_port==4) // see TS 36.213 Section 5.2
|
||||
rho_a_dB=+10*log10(2);
|
||||
|
||||
sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
|
||||
|
||||
dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
|
||||
|
||||
#ifdef DEBUG_PC
|
||||
printf("UE: p_a=%d, value=%f, dl_power_off=%d, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dl_power_off,dlsch_ue->sqrt_rho_a);
|
||||
#endif
|
||||
|
||||
return(rho_a_dB);
|
||||
}
|
||||
|
||||
double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
PDSCH_CONFIG_COMMON *pdsch_config_common,
|
||||
uint8_t n_antenna_port,
|
||||
LTE_UE_DLSCH_t *dlsch_ue,
|
||||
unsigned char dl_power_off)
|
||||
{
|
||||
|
||||
double rho_a_dB, rho_b_dB;
|
||||
double sqrt_rho_b_lin;
|
||||
|
||||
rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off, n_antenna_port);
|
||||
|
||||
if(n_antenna_port>1)
|
||||
rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
|
||||
else
|
||||
rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
|
||||
|
||||
sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
|
||||
|
||||
dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
|
||||
|
||||
#ifdef DEBUG_PC
|
||||
printf("UE: p_b=%d, n_ant=%d -> ratio=%f -> sqrt_rho_b=%d\n",pdsch_config_common->p_b, n_antenna_port,ratioPB[1][pdsch_config_common->p_b],dlsch_ue->sqrt_rho_b);
|
||||
#endif
|
||||
return(rho_b_dB);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!dl_power_off)
|
||||
rho_a_dB-=10*log10(2);
|
||||
//if dl_power_offset is 0, this is for MU-interference, TM5. But in practice UE may assume 16 or 64QAM TM4 as multiuser
|
||||
|
||||
if(n_antenna_port==4) // see TS 36.213 Section 5.2
|
||||
rho_a_dB=+10*log10(2);
|
||||
|
||||
sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
|
||||
|
||||
dlsch_ue->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13));
|
||||
|
||||
#ifdef DEBUG_PC
|
||||
printf("UE: p_a=%d, value=%f, dl_power_off=%d, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dl_power_off,dlsch_ue->sqrt_rho_a);
|
||||
#endif
|
||||
|
||||
return(rho_a_dB);
|
||||
}
|
||||
|
||||
double computeRhoB_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
|
||||
PDSCH_CONFIG_COMMON *pdsch_config_common,
|
||||
uint8_t n_antenna_port,
|
||||
LTE_UE_DLSCH_t *dlsch_ue,
|
||||
unsigned char dl_power_off)
|
||||
{
|
||||
|
||||
double rho_a_dB, rho_b_dB;
|
||||
double sqrt_rho_b_lin;
|
||||
|
||||
rho_a_dB= computeRhoA_UE(pdsch_config_dedicated,dlsch_ue,dl_power_off, n_antenna_port);
|
||||
|
||||
if(n_antenna_port>1)
|
||||
rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB;
|
||||
else
|
||||
rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB;
|
||||
|
||||
sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB));
|
||||
|
||||
dlsch_ue->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13));
|
||||
|
||||
#ifdef DEBUG_PC
|
||||
printf("UE: p_b=%d, n_ant=%d -> ratio=%f -> sqrt_rho_b=%d\n",pdsch_config_common->p_b, n_antenna_port,ratioPB[1][pdsch_config_common->p_b],dlsch_ue->sqrt_rho_b);
|
||||
#endif
|
||||
return(rho_b_dB);
|
||||
}
|
||||
|
||||
@@ -645,6 +645,12 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
|
||||
|
||||
#else //normal case (simulation)
|
||||
prach_start = subframe*ue->frame_parms.samples_per_tti-ue->N_TA_offset;
|
||||
LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id,
|
||||
prach_start,
|
||||
ue->rx_offset,
|
||||
ue->hw_timing_advance,
|
||||
ue->N_TA_offset);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1074,6 +1080,8 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
|
||||
#ifdef PRACH_DEBUG
|
||||
write_output("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1);
|
||||
write_output("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1);
|
||||
write_output("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][0]),2*ue->frame_parms.samples_per_tti,1,1);
|
||||
exit(-1);
|
||||
#endif
|
||||
|
||||
return signal_energy( (int*)prach, 256 );
|
||||
@@ -1125,7 +1133,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
int fft_size,log2_ifft_size;
|
||||
uint8_t nb_ant_rx = 1; //eNB->frame_parms.nb_antennas_rx;
|
||||
|
||||
// int en;
|
||||
int en;
|
||||
|
||||
for (aa=0; aa<nb_ant_rx; aa++) {
|
||||
prach[aa] = (int16_t*)&eNB->common_vars.rxdata[0][aa][subframe*eNB->frame_parms.samples_per_tti-eNB->N_TA_offset];
|
||||
@@ -1327,9 +1335,26 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
/// **** send_IF4 of rxsigF to RCC **** ///
|
||||
send_IF4p5(eNB, eNB->proc.frame_prach, eNB->proc.subframe_prach, IF4p5_PRACH, k);
|
||||
|
||||
// en = dB_fixed(signal_energy(&rxsigF[0][k],840));
|
||||
// if (en>60)
|
||||
// printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
|
||||
#if 0
|
||||
/* TODO: resolv this conflict (there should be no printf anyway, so no big deal) */
|
||||
<<<<<<< HEAD
|
||||
/*
|
||||
en = dB_fixed(signal_energy(&rxsigF[0][k],840));
|
||||
printf("Sending PRACH, k %d,n_ra_prb %d, N_RB_UL %d, en %d\n",k,n_ra_prb,eNB->frame_parms.N_RB_UL,en);
|
||||
if (en>60) {
|
||||
printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
|
||||
write_output("prach_rx0.m","prach_rx0",(int16_t*)&rxsigF[0][k],839,1,1);
|
||||
exit(-1);
|
||||
}
|
||||
*/
|
||||
|
||||
=======
|
||||
en = dB_fixed(signal_energy(&rxsigF[0][k],840));
|
||||
if (en>60)
|
||||
printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
|
||||
>>>>>>> origin/fix-if4p5
|
||||
#endif
|
||||
|
||||
return;
|
||||
} else if (eNB->node_function == NGFI_RCC_IF4p5) {
|
||||
k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
|
||||
@@ -1347,9 +1372,25 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
(&rxsigF[0][0]),
|
||||
839*2*sizeof(int16_t));
|
||||
|
||||
//en = dB_fixed(signal_energy(&rxsigF[0][k],840));
|
||||
// if (en>60)
|
||||
//printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
|
||||
#if 0
|
||||
/* TODO: resolv this conflict (there should be no printf anyway, so no big deal) */
|
||||
<<<<<<< HEAD
|
||||
/*
|
||||
en = dB_fixed(signal_energy(&rxsigF[0][k],840));
|
||||
printf("Receiving PRACH, k %d,n_ra_prb %d, N_RB_UL %d, en %d\n",k,n_ra_prb,eNB->frame_parms.N_RB_UL,en);
|
||||
if (en>60) {
|
||||
printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
|
||||
write_output("prach_rx0.m","prach_rx0",(int16_t*)&rxsigF[0][k],839,1,1);
|
||||
exit(-1);
|
||||
}
|
||||
*/
|
||||
=======
|
||||
en = dB_fixed(signal_energy(&rxsigF[0][k],840));
|
||||
/*if (en>60)
|
||||
printf("PRACH: Frame %d, Subframe %d => %d dB\n",eNB->proc.frame_rx,eNB->proc.subframe_rx,en);*/
|
||||
|
||||
>>>>>>> origin/fix-if4p5
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -1523,7 +1564,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
|
||||
#ifdef PRACH_DEBUG
|
||||
|
||||
// if (en>40) {
|
||||
if (en>40) {
|
||||
k = (12*n_ra_prb) - 6*eNB->frame_parms.N_RB_UL;
|
||||
|
||||
if (k<0)
|
||||
@@ -1537,7 +1578,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
write_output("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1);
|
||||
write_output("prach_ifft0.m","prach_t0",prach_ifft[0],1024,1,1);
|
||||
exit(-1);
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
} // new dft
|
||||
|
||||
@@ -1551,7 +1592,7 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
for (aa=0; aa<nb_ant_rx; aa++) {
|
||||
lev += (int32_t)prach_ifft[aa][(preamble_shift2+i)<<1]*prach_ifft[aa][(preamble_shift2+i)<<1] + (int32_t)prach_ifft[aa][1+((preamble_shift2+i)<<1)]*prach_ifft[aa][1+((preamble_shift2+i)<<1)];
|
||||
}
|
||||
|
||||
|
||||
levdB = dB_fixed_times10(lev);
|
||||
|
||||
if (levdB>preamble_energy_list[preamble_index] ) {
|
||||
@@ -1559,12 +1600,12 @@ void rx_prach(PHY_VARS_eNB *eNB,
|
||||
preamble_delay_list[preamble_index] = (i*fft_size)>>log2_ifft_size;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PRACH_DEBUG
|
||||
LOG_D(PHY,"[RAPROC] Preamble %d => %d dB, %d (shift %d (%d), NCS2 %d(%d), Ncp %d)\n",preamble_index,preamble_energy_list[preamble_index],preamble_delay_list[preamble_index],preamble_shift2,
|
||||
preamble_shift, NCS2,NCS,Ncp);
|
||||
#endif
|
||||
// exit(-1);
|
||||
#endif
|
||||
|
||||
}// preamble_index
|
||||
|
||||
stop_meas(&eNB->rx_prach);
|
||||
|
||||
@@ -1957,7 +1957,7 @@ void generate_pucch2x(int32_t **txdataF,
|
||||
PUCCH_FMT_t fmt,
|
||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
||||
uint16_t n2_pucch,
|
||||
uint16_t *payload,
|
||||
uint8_t *payload,
|
||||
int A,
|
||||
int B2,
|
||||
int16_t amp,
|
||||
|
||||
@@ -473,7 +473,7 @@ void generate_pucch2x(int32_t **txdataF,
|
||||
PUCCH_FMT_t fmt,
|
||||
PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
|
||||
uint16_t n2_pucch,
|
||||
uint16_t *payload,
|
||||
uint8_t *payload,
|
||||
int A,
|
||||
int B2,
|
||||
int16_t amp,
|
||||
@@ -573,7 +573,8 @@ void generate_pucch2x(int32_t **txdataF,
|
||||
n_cs = (ncs_cell[ns][l]+nprime)%12;
|
||||
|
||||
alpha_ind = 0;
|
||||
for (n=0; n<12; n++) {
|
||||
for (n=0; n<12; n++)
|
||||
{
|
||||
// this is r_uv^alpha(n)
|
||||
ref_re = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][n<<1] - (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)])>>15);
|
||||
ref_im = (int16_t)(((int32_t)alpha_re[alpha_ind] * ul_ref_sigs[u][v][0][1+(n<<1)] + (int32_t)alpha_im[alpha_ind] * ul_ref_sigs[u][v][0][n<<1])>>15);
|
||||
@@ -584,11 +585,25 @@ void generate_pucch2x(int32_t **txdataF,
|
||||
//LOG_I(PHY,"slot %d ofdm# %d ==> d[%d,%d] \n",ns,l,data_ind,n);
|
||||
}
|
||||
else {
|
||||
((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15);
|
||||
((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15);
|
||||
//LOG_I(PHY,"slot %d ofdm# %d ==> dmrs[%d] \n",ns,l,n);
|
||||
}
|
||||
alpha_ind = (alpha_ind + n_cs)%12;
|
||||
if ((l==1) || ( (l==5) && (fmt==pucch_format2) ))
|
||||
{
|
||||
((int16_t *)&zptr[n])[0] = ((int32_t)amp*ref_re>>15);
|
||||
((int16_t *)&zptr[n])[1] = ((int32_t)amp*ref_im>>15);
|
||||
}
|
||||
// l == 5 && pucch format 2a
|
||||
else if (fmt==pucch_format2a)
|
||||
{
|
||||
((int16_t *)&zptr[n])[0] = ((int32_t)d[20]*ref_re>>15);
|
||||
((int16_t *)&zptr[n])[1] = ((int32_t)d[21]*ref_im>>15);
|
||||
}
|
||||
// l == 5 && pucch format 2b
|
||||
else if (fmt==pucch_format2b)
|
||||
{
|
||||
((int16_t *)&zptr[n])[0] = ((int32_t)d[20]*ref_re>>15);
|
||||
((int16_t *)&zptr[n])[1] = ((int32_t)d[21]*ref_im>>15);
|
||||
}
|
||||
} // l==1 || l==5
|
||||
alpha_ind = (alpha_ind + n_cs)%12;
|
||||
} // n
|
||||
zptr+=12;
|
||||
|
||||
|
||||
@@ -418,6 +418,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
|
||||
|
||||
extern int oai_exit;
|
||||
void *td_thread(void *param) {
|
||||
pthread_setname_np( pthread_self(), "td processing");
|
||||
PHY_VARS_eNB *eNB = ((td_params*)param)->eNB;
|
||||
eNB_proc_t *proc = &eNB->proc;
|
||||
|
||||
@@ -2067,7 +2068,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
|
||||
get_ack(&eNB->frame_parms,
|
||||
PHY_vars_UE_g[UE_id][CC_id]->dlsch[0][0]->harq_ack,
|
||||
subframe,
|
||||
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK);
|
||||
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK,0);
|
||||
} else { // get remote UEs' ack
|
||||
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[0] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[0];
|
||||
eNB->ulsch[UE_index]->harq_processes[harq_pid]->o_ACK[1] = PHY_vars_UE_g[UE_id][CC_id]->ulsch[0]->o_ACK[1];
|
||||
|
||||
@@ -415,7 +415,7 @@ void ulsch_modulation(int32_t **txdataF,
|
||||
return;
|
||||
}
|
||||
|
||||
if (first_rb >25 ) {
|
||||
if (first_rb > frame_parms->N_RB_UL) {
|
||||
printf("ulsch_modulation.c: Frame %d, Subframe %d Illegal first_rb %d\n",frame,subframe,first_rb);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file PHY/MODULATION/beamforming.c
|
||||
* \brief
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,29 +1,3 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITTOOLHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/* Form definition file generated by fdesign */
|
||||
#include <stdlib.h>
|
||||
#include "lte_phy_scope.h"
|
||||
@@ -797,4 +797,4 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
|
||||
for (arx=0;arx<nb_antennas_rx;arx++) {
|
||||
free(chest_t_abs[arx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/* Twiddles generated with
|
||||
twa = floor(32767*exp(-sqrt(-1)*2*pi*(0:6143)/18432));
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#ifndef __PHY_DEFS__H__
|
||||
#define __PHY_DEFS__H__
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
@@ -391,6 +392,9 @@ typedef struct {
|
||||
pthread_mutex_t mutex_rxtx;
|
||||
/// scheduling parameters for RXn-TXnp4 thread
|
||||
struct sched_param sched_param_rxtx;
|
||||
int sub_frame_start;
|
||||
int sub_frame_step;
|
||||
unsigned long long gotIQs;
|
||||
} UE_rxtx_proc_t;
|
||||
|
||||
/// Context data structure for eNB subframe processing
|
||||
@@ -430,6 +434,7 @@ typedef struct PHY_VARS_eNB_s {
|
||||
eNB_proc_t proc;
|
||||
eNB_func_t node_function;
|
||||
eNB_timing_t node_timing;
|
||||
eth_params_t *eth_params;
|
||||
int single_thread_flag;
|
||||
openair0_rf_map rf_map;
|
||||
int abstraction_flag;
|
||||
|
||||
@@ -284,21 +284,7 @@ typedef enum {
|
||||
#define NUMBER_OF_HARQ_PID_MAX 8
|
||||
|
||||
#define MAX_FRAME_NUMBER 0x400
|
||||
#if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP)
|
||||
#define NUMBER_OF_eNB_MAX 1
|
||||
#define NUMBER_OF_UE_MAX 16
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 3
|
||||
#else
|
||||
#ifdef LARGE_SCALE
|
||||
#define NUMBER_OF_eNB_MAX 2
|
||||
#define NUMBER_OF_UE_MAX 120
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 1 // to save some memory
|
||||
#else
|
||||
#define NUMBER_OF_eNB_MAX 7
|
||||
#define NUMBER_OF_UE_MAX 16
|
||||
#define NUMBER_OF_CONNECTED_eNB_MAX 3
|
||||
#endif
|
||||
#endif
|
||||
#include "openairinterface5g_limits.h"
|
||||
|
||||
#define NUMBER_OF_RN_MAX 3
|
||||
typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t;
|
||||
|
||||
@@ -305,7 +305,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n);
|
||||
@param o_ACK Pointer to ACK/NAK payload for PUCCH/PUSCH
|
||||
@returns status indicator for PUCCH/PUSCH transmission
|
||||
*/
|
||||
uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK);
|
||||
uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t subframe,uint8_t *o_ACK, uint8_t cw_idx);
|
||||
|
||||
/*! \brief Reset ACK/NACK information
|
||||
@param frame_parms Pointer to DL frame parameter descriptor
|
||||
@@ -317,7 +317,8 @@ uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,harq_status_t *harq_ack,uint8_t
|
||||
uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
harq_status_t *harq_ack,
|
||||
unsigned char subframe,
|
||||
unsigned char *o_ACK);
|
||||
unsigned char *o_ACK,
|
||||
uint8_t cw_idx);
|
||||
|
||||
/*! \brief Compute UL ACK subframe from DL subframe. This is used to retrieve corresponding DLSCH HARQ pid at eNB upon reception of ACK/NAK information on PUCCH/PUSCH. Derived from Table 10.1-1 in 36.213 (p. 69 in version 8.6)
|
||||
@param frame_parms Pointer to DL frame parameter descriptor
|
||||
|
||||
+147
-29
@@ -455,6 +455,151 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DCI_pdu->dci_alloc[1].L = 2;
|
||||
DCI_pdu->dci_alloc[1].rnti = 0x1235;
|
||||
DCI_pdu->dci_alloc[1].format = format0;
|
||||
DCI_pdu->dci_alloc[1].ra_flag = 0;
|
||||
|
||||
if (eNB->frame_parms.frame_type == FDD) {
|
||||
switch (eNB->frame_parms.N_RB_DL) {
|
||||
case 6:
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(6,1,4);
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_1_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
/* case 15:
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_3MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;*/
|
||||
case 25:
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,1,20);
|
||||
printf("rballoc %d\n",((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc);
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_5MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
case 50:
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(50,1,48);
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_10MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
/* case 75:
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_15MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;*/
|
||||
case 100:
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(100,1,96);
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_20MHz_FDD_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (eNB->frame_parms.N_RB_DL==6) {
|
||||
case 6:
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(6,1,5);
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_1_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
/* case 15:
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_3MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;*/
|
||||
case 25:
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,20);
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_5MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
case 50:
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(50,1,48);
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_10MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
/* case 75:
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_15MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;*/
|
||||
case 100:
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->type = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->hopping = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->rballoc = computeRIV(100,1,96);
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->mcs = eNB->target_ue_ul_mcs;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->ndi = proc->frame_tx&1;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->TPC = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cshift = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->dai = 0;
|
||||
((DCI0_20MHz_TDD_1_6_t*)&DCI_pdu->dci_alloc[1].dci_pdu[0])->cqi_req = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (transmission_mode==4) {
|
||||
DCI_pdu->Num_ue_spec_dci = 1;
|
||||
// user 1
|
||||
@@ -543,32 +688,8 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
|
||||
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
|
||||
break;
|
||||
*/
|
||||
/*
|
||||
case 9:
|
||||
DCI_pdu->Num_ue_spec_dci = 1;
|
||||
|
||||
|
||||
//user 1
|
||||
if (eNB->frame_parms.frame_type == FDD)
|
||||
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_FDD_t ;
|
||||
else
|
||||
DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
|
||||
|
||||
DCI_pdu->dci_alloc[0].L = 2;
|
||||
DCI_pdu->dci_alloc[0].rnti = 0x1235;
|
||||
DCI_pdu->dci_alloc[0].format = format0;
|
||||
DCI_pdu->dci_alloc[0].ra_flag = 0;
|
||||
|
||||
UL_alloc_pdu.type = 0;
|
||||
UL_alloc_pdu.hopping = 0;
|
||||
UL_alloc_pdu.rballoc = computeRIV(25,2,eNB->ue_ul_nb_rb);
|
||||
UL_alloc_pdu.mcs = eNB->target_ue_ul_mcs;
|
||||
UL_alloc_pdu.ndi = proc->frame_tx&1;
|
||||
UL_alloc_pdu.TPC = 0;
|
||||
UL_alloc_pdu.cshift = 0;
|
||||
UL_alloc_pdu.dai = 0;
|
||||
UL_alloc_pdu.cqi_req = 1;
|
||||
memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
|
||||
*/
|
||||
// user 2
|
||||
/*
|
||||
DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
|
||||
@@ -593,11 +714,8 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
|
||||
UL_alloc_pdu.dai = 0;
|
||||
UL_alloc_pdu.cqi_req = 1;
|
||||
memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t));
|
||||
break;
|
||||
|
||||
*/
|
||||
|
||||
/*default:
|
||||
break;*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -325,6 +325,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
harq_status_t *harq_ack,
|
||||
unsigned char subframe,
|
||||
unsigned char *o_ACK,
|
||||
uint8_t cw_idx,
|
||||
uint8_t do_reset) // 1 to reset ACK/NACK status : 0 otherwise
|
||||
{
|
||||
uint8_t status=0;
|
||||
@@ -337,7 +338,7 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
else
|
||||
subframe_dl0 = subframe - 4;
|
||||
|
||||
o_ACK[0] = harq_ack[subframe_dl0].ack;
|
||||
o_ACK[cw_idx] = harq_ack[subframe_dl0].ack;
|
||||
status = harq_ack[subframe_dl0].send_harq_status;
|
||||
|
||||
if(do_reset)
|
||||
@@ -484,17 +485,19 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t get_ack(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
harq_status_t *harq_ack,
|
||||
unsigned char subframe,
|
||||
unsigned char *o_ACK)
|
||||
unsigned char *o_ACK,
|
||||
uint8_t cw_idx)
|
||||
{
|
||||
return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 0);
|
||||
return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 0);
|
||||
}
|
||||
|
||||
uint8_t reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
harq_status_t *harq_ack,
|
||||
unsigned char subframe,
|
||||
unsigned char *o_ACK)
|
||||
unsigned char *o_ACK,
|
||||
uint8_t cw_idx)
|
||||
{
|
||||
return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, 1);
|
||||
return get_reset_ack(frame_parms, harq_ack, subframe, o_ACK, cw_idx, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -78,7 +78,8 @@
|
||||
void exit_fun(const char* s);
|
||||
|
||||
extern int exit_openair;
|
||||
|
||||
struct timespec start_fh, start_fh_prev;
|
||||
int start_fh_sf, start_fh_prev_sf;
|
||||
// Fix per CC openair rf/if device update
|
||||
// extern openair0_device openair0;
|
||||
|
||||
@@ -92,6 +93,9 @@ extern uint16_t hundred_times_log10_NPRB[100];
|
||||
unsigned int max_peak_val;
|
||||
int max_sync_pos;
|
||||
|
||||
int harq_pid_updated[NUMBER_OF_UE_MAX][8] = {{0}};
|
||||
int harq_pid_round[NUMBER_OF_UE_MAX][8] = {{0}};
|
||||
|
||||
//DCI_ALLOC_t dci_alloc[8];
|
||||
|
||||
#ifdef EMOS
|
||||
@@ -1444,15 +1448,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
|
||||
eNB->dlsch_ra->active = 0;
|
||||
}
|
||||
|
||||
#if defined(FLEXRAN_AGENT_SB_IF)
|
||||
#ifndef DISABLE_SF_TRIGGER
|
||||
//Send subframe trigger to the controller
|
||||
if (mac_agent_registered[eNB->Mod_id]) {
|
||||
agent_mac_xface[eNB->Mod_id]->flexran_agent_send_sf_trigger(eNB->Mod_id);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Now scan UE specific DLSCH
|
||||
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
|
||||
{
|
||||
@@ -1559,7 +1554,6 @@ void process_HARQ_feedback(uint8_t UE_id,
|
||||
int subframe = proc->subframe_rx;
|
||||
int harq_pid = subframe2harq_pid( fp,frame,subframe);
|
||||
|
||||
|
||||
if (fp->frame_type == FDD) { //FDD
|
||||
subframe_m4 = (subframe<4) ? subframe+6 : subframe-4;
|
||||
|
||||
@@ -1687,6 +1681,7 @@ void process_HARQ_feedback(uint8_t UE_id,
|
||||
mp = m;
|
||||
|
||||
dl_harq_pid[m] = dlsch->harq_ids[dl_subframe];
|
||||
harq_pid_updated[UE_id][dl_harq_pid[m]] = 1;
|
||||
|
||||
if ((pucch_sel != 2)&&(pusch_flag == 0)) { // multiplexing
|
||||
if ((SR_payload == 1)&&(all_ACKed == 1))
|
||||
@@ -1774,7 +1769,7 @@ void process_HARQ_feedback(uint8_t UE_id,
|
||||
eNB->dlsch[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// Do fine-grain rate-adaptation for DLSCH
|
||||
if (ue_stats->dlsch_NAK_round0 > dlsch->error_threshold) {
|
||||
if (ue_stats->dlsch_mcs_offset == 1)
|
||||
@@ -1787,7 +1782,7 @@ void process_HARQ_feedback(uint8_t UE_id,
|
||||
LOG_D(PHY,"[process_HARQ_feedback] Frame %d Setting round to %d for pid %d (subframe %d)\n",frame,
|
||||
dlsch_harq_proc->round,dl_harq_pid[m],subframe);
|
||||
#endif
|
||||
|
||||
harq_pid_round[UE_id][dl_harq_pid[m]] = dlsch_harq_proc->round;
|
||||
// Clear NAK stats and adjust mcs offset
|
||||
// after measurement window timer expires
|
||||
if (ue_stats->dlsch_sliding_cnt == dlsch->ra_window_size) {
|
||||
@@ -1806,8 +1801,6 @@ void process_HARQ_feedback(uint8_t UE_id,
|
||||
ue_stats->dlsch_NAK_round0 = 0;
|
||||
ue_stats->dlsch_sliding_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2611,6 +2604,7 @@ extern int oai_exit;
|
||||
|
||||
static void *fep_thread(void *param) {
|
||||
|
||||
pthread_setname_np( pthread_self(), "UEfep");
|
||||
PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param;
|
||||
eNB_proc_t *proc = &eNB->proc;
|
||||
while (!oai_exit) {
|
||||
@@ -2756,7 +2750,12 @@ void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) {
|
||||
|
||||
if (eNB->node_function == NGFI_RRU_IF4p5) {
|
||||
/// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
|
||||
LOG_D(PHY,"send_IF4p5 (PULFFT): frame %d, subframe %d\n",proc_rxtx->frame_rx,proc_rxtx->subframe_rx);
|
||||
send_IF4p5(eNB, proc_rxtx->frame_rx, proc_rxtx->subframe_rx, IF4p5_PULFFT, 0);
|
||||
start_fh_prev = start_fh;
|
||||
start_fh_prev_sf = start_fh_sf;
|
||||
clock_gettime( CLOCK_MONOTONIC, &start_fh);
|
||||
start_fh_sf = proc_rxtx->subframe_rx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2768,6 +2767,10 @@ void eNB_fep_rru_if5(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc_rxtx) {
|
||||
/// **** send_IF5 of rxdata to BBU **** ///
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 1 );
|
||||
send_IF5(eNB, proc->timestamp_rx, proc->subframe_rx, &seqno, IF5_RRH_GW_UL);
|
||||
start_fh_prev = start_fh;
|
||||
start_fh_prev_sf = start_fh_sf;
|
||||
clock_gettime( CLOCK_MONOTONIC, &start_fh);
|
||||
start_fh_sf = proc->subframe_rx;
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5, 0 );
|
||||
|
||||
}
|
||||
@@ -3076,12 +3079,15 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
|
||||
LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,eNB->ulsch[i]->harq_processes[harq_pid]->round);
|
||||
|
||||
if (eNB->ulsch[i]->Msg3_flag == 1) {
|
||||
|
||||
LOG_D(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d/%d\n",
|
||||
eNB->Mod_id,
|
||||
eNB->CC_id,
|
||||
frame,subframe, i,
|
||||
eNB->ulsch[i]->harq_processes[harq_pid]->round-1,
|
||||
fp->maxHARQ_Msg3Tx-1);
|
||||
/*dump_ulsch(eNB,proc,i);
|
||||
exit(-1);*/
|
||||
|
||||
LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n",
|
||||
eNB->Mod_id,harq_pid,
|
||||
@@ -3164,6 +3170,10 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
|
||||
eNB->UE_stats[i].ulsch_errors[harq_pid]++;
|
||||
eNB->UE_stats[i].ulsch_consecutive_errors++;
|
||||
|
||||
/*if (eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb > 20) {
|
||||
dump_ulsch(eNB,proc,i);
|
||||
exit(-1);
|
||||
}*/
|
||||
// indicate error to MAC
|
||||
if (eNB->mac_enabled == 1)
|
||||
mac_xface->rx_sdu(eNB->Mod_id,
|
||||
@@ -3428,14 +3438,21 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//}
|
||||
|
||||
#ifdef EMOS
|
||||
phy_procedures_emos_eNB_RX(subframe,eNB);
|
||||
#endif
|
||||
|
||||
#if defined(FLEXRAN_AGENT_SB_IF)
|
||||
#ifndef DISABLE_SF_TRIGGER
|
||||
//Send subframe trigger to the controller
|
||||
if (mac_agent_registered[eNB->Mod_id]) {
|
||||
agent_mac_xface[eNB->Mod_id]->flexran_agent_send_sf_trigger(eNB->Mod_id);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC+offset, 0 );
|
||||
|
||||
stop_meas(&eNB->phy_proc_rx);
|
||||
|
||||
@@ -639,7 +639,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
|
||||
uint8_t pucch_ack_payload[2];
|
||||
if (get_ack(&ue->frame_parms,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
subframe_tx,pucch_ack_payload) > 0)
|
||||
subframe_tx,pucch_ack_payload,0) > 0)
|
||||
{
|
||||
is_sr_an_subframe = 1;
|
||||
}
|
||||
@@ -737,6 +737,60 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
|
||||
}
|
||||
}
|
||||
|
||||
PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
|
||||
lte_prefix_type_t cyclic_prefix_type,
|
||||
uint8_t SR_payload,
|
||||
uint8_t nb_cw,
|
||||
uint8_t cqi_status,
|
||||
uint8_t ri_status)
|
||||
{
|
||||
if((cqi_status == 0) && (ri_status==0))
|
||||
{
|
||||
// PUCCH Format 1 1a 1b
|
||||
// 1- SR only ==> PUCCH format 1
|
||||
// 2- 1bit Ack/Nack with/without SR ==> PUCCH format 1a
|
||||
// 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
|
||||
if(nb_cw == 1)
|
||||
{
|
||||
return pucch_format1a;
|
||||
}
|
||||
if(nb_cw == 2)
|
||||
{
|
||||
return pucch_format1b;
|
||||
}
|
||||
if(SR_payload == 1)
|
||||
{
|
||||
return pucch_format1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// PUCCH Format 2 2a 2b
|
||||
// 1- CQI only or RI only ==> PUCCH format 2
|
||||
// 2- CQI or RI + 1bit Ack/Nack for normal CP ==> PUCCH format 2a
|
||||
// 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b
|
||||
// 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2
|
||||
if(nb_cw == 0)
|
||||
{
|
||||
return pucch_format2;
|
||||
}
|
||||
if(cyclic_prefix_type == NORMAL)
|
||||
{
|
||||
if(nb_cw == 1)
|
||||
{
|
||||
return pucch_format2a;
|
||||
}
|
||||
if(nb_cw == 2)
|
||||
{
|
||||
return pucch_format2b;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return pucch_format2;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint16_t get_n1_pucch(PHY_VARS_UE *ue,
|
||||
UE_rxtx_proc_t *proc,
|
||||
harq_status_t *harq_ack,
|
||||
@@ -986,8 +1040,8 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
|
||||
int subframe_tx = proc->subframe_tx;
|
||||
int frame_tx = proc->frame_tx;
|
||||
int ulsch_start;
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
int overflow=0;
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
int k,l;
|
||||
int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
|
||||
#endif
|
||||
@@ -1015,14 +1069,15 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
|
||||
ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
|
||||
#endif //else EXMIMO
|
||||
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
if (empty_subframe)
|
||||
{
|
||||
//#if 1
|
||||
overflow = ulsch_start - 9*frame_parms->samples_per_tti;
|
||||
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
|
||||
memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti));
|
||||
memset(&ue->common_vars.txdata[aa][ulsch_start],0,
|
||||
4*cmin(frame_parms->samples_per_tti-overflow,frame_parms->samples_per_tti));
|
||||
|
||||
if (overflow> 0)
|
||||
memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
|
||||
@@ -1043,7 +1098,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
|
||||
#endif*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
if ((frame_tx%100) == 0)
|
||||
LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
|
||||
@@ -1381,7 +1436,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
|
||||
ack_status = reset_ack(&ue->frame_parms,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
subframe_tx,
|
||||
ue->ulsch[eNB_id]->o_ACK);
|
||||
ue->ulsch[eNB_id]->o_ACK,0);
|
||||
Nbundled = ack_status;
|
||||
first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
|
||||
nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
|
||||
@@ -1394,7 +1449,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
|
||||
|
||||
// check if we received a PDSCH at subframe_tx - 4
|
||||
// ==> send ACK/NACK on PUSCH
|
||||
ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status;
|
||||
ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = 1;
|
||||
|
||||
#if T_TRACER
|
||||
if(ue->ulsch[eNB_id]->o_ACK[0])
|
||||
@@ -1411,7 +1466,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
|
||||
Mod_id,
|
||||
ue->ulsch[eNB_id]->rnti,
|
||||
frame_tx,subframe_tx,
|
||||
@@ -1421,7 +1476,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
|
||||
|
||||
#ifdef DEBUG_PHY_PROC
|
||||
LOG_D(PHY,
|
||||
"[UE %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n",
|
||||
"[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, bundling %d\n",
|
||||
Mod_id,harq_pid,frame_tx,subframe_tx,
|
||||
first_rb,nb_rb,
|
||||
ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
|
||||
@@ -1684,17 +1739,79 @@ int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
void get_pucch_param(PHY_VARS_UE *ue,
|
||||
UE_rxtx_proc_t *proc,
|
||||
uint8_t *ack_payload,
|
||||
PUCCH_FMT_t format,
|
||||
uint8_t eNB_id,
|
||||
uint8_t SR,
|
||||
uint8_t cqi_report,
|
||||
uint16_t *pucch_resource,
|
||||
uint8_t *pucch_payload,
|
||||
uint16_t *plength)
|
||||
{
|
||||
|
||||
switch (format) {
|
||||
case pucch_format1:
|
||||
{
|
||||
pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex;
|
||||
pucch_payload[0] = 0; // payload is ignored in case of format1
|
||||
pucch_payload[1] = 0; // payload is ignored in case of format1
|
||||
}
|
||||
break;
|
||||
|
||||
case pucch_format1a:
|
||||
case pucch_format1b:
|
||||
{
|
||||
pucch_resource[0] = get_n1_pucch(ue,
|
||||
proc,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
eNB_id,
|
||||
ack_payload,
|
||||
SR);
|
||||
pucch_payload[0] = ack_payload[0];
|
||||
//pucch_payload[1] = ack_payload[1];
|
||||
pucch_payload[1] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case pucch_format2:
|
||||
{
|
||||
pucch_resource[0] = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
|
||||
if(cqi_report)
|
||||
{
|
||||
pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,plength);
|
||||
}
|
||||
else
|
||||
{
|
||||
*plength = 1;
|
||||
pucch_payload[0] = get_pucch2_ri(ue,eNB_id);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case pucch_format2a:
|
||||
case pucch_format2b:
|
||||
LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
|
||||
|
||||
|
||||
uint8_t pucch_ack_payload[2];
|
||||
uint8_t n1_pucch,n2_pucch;
|
||||
uint8_t pucch_ack_payload[2];
|
||||
uint8_t n1_pucch,n2_pucch;
|
||||
uint16_t pucch_resource;
|
||||
ANFBmode_t bundling_flag;
|
||||
PUCCH_FMT_t format;
|
||||
|
||||
uint8_t SR_payload;
|
||||
uint8_t SR_payload;
|
||||
uint16_t CQI_payload;
|
||||
uint16_t RI_payload;
|
||||
uint8_t pucch_payload[2];
|
||||
uint16_t len;
|
||||
|
||||
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
|
||||
int frame_tx=proc->frame_tx;
|
||||
@@ -1704,6 +1821,11 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
|
||||
int tx_amp;
|
||||
int16_t Po_PUCCH;
|
||||
uint8_t ack_status=0;
|
||||
uint8_t ack_status_cw0=0;
|
||||
uint8_t ack_status_cw1=0;
|
||||
uint8_t nb_cw=0;
|
||||
uint8_t cqi_status=0;
|
||||
uint8_t ri_status=0;
|
||||
uint8_t ack_sr_generated = 0;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
|
||||
@@ -1741,312 +1863,255 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
|
||||
LOG_D(PHY,"[UE] PUCCH 1b\n");
|
||||
}
|
||||
|
||||
// Check for SR and do ACK/NACK accordingly
|
||||
if (is_SR_TXOp(ue,proc,eNB_id)==1) {
|
||||
LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d: got SR_TXOp, Checking for SR for PUSCH from MAC\n",
|
||||
Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx);
|
||||
|
||||
if (ue->mac_enabled==1) {
|
||||
SR_payload = mac_xface->ue_get_SR(Mod_id,
|
||||
CC_id,
|
||||
frame_tx,
|
||||
eNB_id,
|
||||
ue->pdcch_vars[eNB_id]->crnti,
|
||||
subframe_tx); // subframe used for meas gap
|
||||
}
|
||||
else {
|
||||
SR_payload = 1;
|
||||
}
|
||||
|
||||
if (SR_payload>0) {
|
||||
ue->generate_ul_signal[eNB_id] = 1;
|
||||
LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d got the SR for PUSCH is %d\n",
|
||||
Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx,SR_payload);
|
||||
} else {
|
||||
ue->sr[subframe_tx]=0;
|
||||
}
|
||||
} else {
|
||||
SR_payload=0;
|
||||
// Part - I
|
||||
// Collect feedback that should be transmitted at this subframe
|
||||
// - SR
|
||||
// - ACK/NACK
|
||||
// - CQI
|
||||
// - RI
|
||||
|
||||
SR_payload = 0;
|
||||
if (is_SR_TXOp(ue,proc,eNB_id)==1)
|
||||
{
|
||||
if (ue->mac_enabled==1) {
|
||||
SR_payload = mac_xface->ue_get_SR(Mod_id,
|
||||
CC_id,
|
||||
frame_tx,
|
||||
eNB_id,
|
||||
ue->pdcch_vars[eNB_id]->crnti,
|
||||
subframe_tx); // subframe used for meas gap
|
||||
}
|
||||
else {
|
||||
SR_payload = 1;
|
||||
}
|
||||
}
|
||||
|
||||
ack_status = get_ack(&ue->frame_parms,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
subframe_tx,pucch_ack_payload);
|
||||
if (ack_status > 0) {
|
||||
// we need to transmit ACK/NAK in this subframe
|
||||
|
||||
ue->generate_ul_signal[eNB_id] = 1;
|
||||
ack_sr_generated = 1;
|
||||
|
||||
if ((frame_parms->frame_type == TDD) && (SR_payload>0)) {
|
||||
format = pucch_format1b;
|
||||
}
|
||||
ack_status_cw0 = reset_ack(&ue->frame_parms,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
subframe_tx,
|
||||
pucch_ack_payload,
|
||||
0);
|
||||
|
||||
ack_status_cw1 = reset_ack(&ue->frame_parms,
|
||||
ue->dlsch[eNB_id][1]->harq_ack,
|
||||
subframe_tx,
|
||||
pucch_ack_payload,
|
||||
1);
|
||||
|
||||
nb_cw = ack_status_cw0 + ack_status_cw1;
|
||||
|
||||
cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
|
||||
(is_cqi_TXOp(ue,proc,eNB_id)==1));
|
||||
|
||||
ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
|
||||
(is_ri_TXOp(ue,proc,eNB_id)==1));
|
||||
|
||||
// Part - II
|
||||
// if nothing to report ==> exit function
|
||||
if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0))
|
||||
{
|
||||
LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n",
|
||||
frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Part - III
|
||||
// Decide which PUCCH format should be used if needed
|
||||
format = get_pucch_format(frame_parms->frame_type,
|
||||
frame_parms->Ncp,
|
||||
SR_payload,
|
||||
nb_cw,
|
||||
cqi_status,
|
||||
ri_status);
|
||||
// Determine PUCCH resources and payload: mandatory for pucch encoding
|
||||
get_pucch_param(ue,
|
||||
proc,
|
||||
pucch_ack_payload,
|
||||
format,
|
||||
eNB_id,
|
||||
SR_payload,
|
||||
cqi_status,
|
||||
&pucch_resource,
|
||||
&pucch_payload,
|
||||
&len);
|
||||
|
||||
LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", frame_tx, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
|
||||
|
||||
|
||||
// Part - IV
|
||||
// Generate PUCCH signal
|
||||
ue->generate_ul_signal[eNB_id] = 1;
|
||||
|
||||
switch (format) {
|
||||
case pucch_format1:
|
||||
case pucch_format1a:
|
||||
case pucch_format1b:
|
||||
{
|
||||
if (ue->mac_enabled == 1) {
|
||||
Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
|
||||
}
|
||||
else {
|
||||
Po_PUCCH = ue->tx_power_max_dBm;
|
||||
}
|
||||
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
|
||||
ue->tx_total_RE[subframe_tx] = 12;
|
||||
|
||||
n1_pucch = get_n1_pucch(ue,
|
||||
proc,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
eNB_id,
|
||||
pucch_ack_payload,
|
||||
SR_payload);
|
||||
|
||||
if (ue->mac_enabled == 1) {
|
||||
Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
|
||||
}
|
||||
else {
|
||||
Po_PUCCH = ue->tx_power_max_dBm;
|
||||
}
|
||||
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
|
||||
ue->tx_total_RE[subframe_tx] = 12;
|
||||
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
tx_amp = get_tx_amp(Po_PUCCH,
|
||||
ue->tx_power_max_dBm,
|
||||
ue->frame_parms.N_RB_UL,
|
||||
1);
|
||||
tx_amp = get_tx_amp(Po_PUCCH,
|
||||
ue->tx_power_max_dBm,
|
||||
ue->frame_parms.N_RB_UL,
|
||||
1);
|
||||
#else
|
||||
tx_amp = AMP;
|
||||
tx_amp = AMP;
|
||||
#endif
|
||||
#if T_TRACER
|
||||
T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
|
||||
T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
|
||||
T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
|
||||
#endif
|
||||
if (SR_payload>0) {
|
||||
LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx % 1024, subframe_tx,
|
||||
(format == pucch_format1a? "1a": (
|
||||
format == pucch_format1b? "1b" : "??")),
|
||||
pucch_ack_payload[0],pucch_ack_payload[1],
|
||||
frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
|
||||
isShortenPucch,
|
||||
ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
|
||||
Po_PUCCH,
|
||||
tx_amp);
|
||||
} else {
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx, subframe_tx,ue->rx_offset_diff,
|
||||
(format == pucch_format1a? "1a": (
|
||||
format == pucch_format1b? "1b" : "??")),
|
||||
frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
|
||||
isShortenPucch,
|
||||
n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
|
||||
Po_PUCCH,
|
||||
tx_amp);
|
||||
}
|
||||
if(format == pucch_format1)
|
||||
{
|
||||
LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx, subframe_tx,
|
||||
frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
|
||||
isShortenPucch,
|
||||
ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
|
||||
Po_PUCCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SR_payload>0) {
|
||||
LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx % 1024, subframe_tx,
|
||||
(format == pucch_format1a? "1a": (
|
||||
format == pucch_format1b? "1b" : "??")),
|
||||
pucch_ack_payload[0],pucch_ack_payload[1],
|
||||
frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
|
||||
isShortenPucch,
|
||||
pucch_resource,
|
||||
Po_PUCCH,
|
||||
tx_amp);
|
||||
} else {
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx%1024, subframe_tx,ue->rx_offset_diff,
|
||||
(format == pucch_format1a? "1a": (
|
||||
format == pucch_format1b? "1b" : "??")),
|
||||
frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
|
||||
isShortenPucch,
|
||||
pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload,
|
||||
Po_PUCCH,
|
||||
tx_amp);
|
||||
}
|
||||
}
|
||||
|
||||
#if T_TRACER
|
||||
if(pucch_ack_payload[0])
|
||||
{
|
||||
LOG_I(PHY,"PUCCH ACK\n");
|
||||
T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
|
||||
T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_I(PHY,"PUCCH NACK\n");
|
||||
T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
|
||||
T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
|
||||
}
|
||||
if(pucch_payload[0])
|
||||
{
|
||||
T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
|
||||
T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
|
||||
}
|
||||
else
|
||||
{
|
||||
T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[eNB_id][0]->rnti),
|
||||
T_INT(ue->dlsch[eNB_id][0]->current_harq_pid));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (abstraction_flag == 0) {
|
||||
|
||||
generate_pucch1x(ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
ue->ncs_cell,
|
||||
format,
|
||||
&ue->pucch_config_dedicated[eNB_id],
|
||||
n1_pucch,
|
||||
isShortenPucch, // shortened format
|
||||
pucch_ack_payload,
|
||||
tx_amp,
|
||||
subframe_tx);
|
||||
|
||||
} else {
|
||||
|
||||
if (abstraction_flag == 0) {
|
||||
|
||||
generate_pucch1x(ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
ue->ncs_cell,
|
||||
format,
|
||||
&ue->pucch_config_dedicated[eNB_id],
|
||||
pucch_resource,
|
||||
isShortenPucch, // shortened format
|
||||
pucch_payload,
|
||||
tx_amp,
|
||||
subframe_tx);
|
||||
|
||||
} else {
|
||||
#ifdef PHY_ABSTRACTION
|
||||
LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
|
||||
generate_pucch_emul(ue,
|
||||
proc,
|
||||
format,
|
||||
ue->frame_parms.pucch_config_common.nCS_AN,
|
||||
pucch_ack_payload,
|
||||
SR_payload);
|
||||
LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
|
||||
generate_pucch_emul(ue,
|
||||
proc,
|
||||
format,
|
||||
ue->frame_parms.pucch_config_common.nCS_AN,
|
||||
pucch_payload,
|
||||
SR_payload);
|
||||
#endif
|
||||
}
|
||||
} else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
ack_sr_generated = 1;
|
||||
if (ue->mac_enabled == 1) {
|
||||
Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,pucch_format1);
|
||||
}
|
||||
else {
|
||||
Po_PUCCH = ue->tx_power_max_dBm;
|
||||
}
|
||||
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
|
||||
ue->tx_total_RE[subframe_tx] = 12;
|
||||
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
tx_amp = get_tx_amp(Po_PUCCH,
|
||||
ue->tx_power_max_dBm,
|
||||
ue->frame_parms.N_RB_UL,
|
||||
1);
|
||||
#else
|
||||
tx_amp = AMP;
|
||||
#endif
|
||||
#if T_TRACER
|
||||
T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
|
||||
T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
|
||||
#endif
|
||||
LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx, subframe_tx,
|
||||
frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
|
||||
isShortenPucch,
|
||||
ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
|
||||
Po_PUCCH);
|
||||
|
||||
if (abstraction_flag == 0) {
|
||||
|
||||
generate_pucch1x(ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
ue->ncs_cell,
|
||||
pucch_format1,
|
||||
&ue->pucch_config_dedicated[eNB_id],
|
||||
ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
|
||||
isShortenPucch, // shortened format
|
||||
pucch_ack_payload, // this is ignored anyway, we just need a pointer
|
||||
tx_amp,
|
||||
subframe_tx);
|
||||
} else {
|
||||
LOG_D(PHY,"Calling generate_pucch_emul ...\n");
|
||||
generate_pucch_emul(ue,
|
||||
proc,
|
||||
pucch_format1,
|
||||
ue->frame_parms.pucch_config_common.nCS_AN,
|
||||
pucch_ack_payload,
|
||||
SR_payload);
|
||||
|
||||
}
|
||||
} // SR_Payload==1
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
|
||||
|
||||
// PUCCH 2x
|
||||
|
||||
if (ack_sr_generated == 0) { // we have not generated ACK/NAK/SR in this subframe
|
||||
|
||||
n2_pucch = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex;
|
||||
// only use format2 for now, i.e. now ACK/NAK - CQI multiplexing
|
||||
format = pucch_format2;
|
||||
|
||||
// Periodic CQI report
|
||||
if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
|
||||
(is_cqi_TXOp(ue,proc,eNB_id)==1)){
|
||||
|
||||
case pucch_format2:
|
||||
{
|
||||
if (ue->mac_enabled == 1) {
|
||||
Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
|
||||
Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
|
||||
}
|
||||
else {
|
||||
Po_PUCCH = ue->tx_power_max_dBm;
|
||||
Po_PUCCH = ue->tx_power_max_dBm;
|
||||
}
|
||||
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
|
||||
ue->tx_total_RE[subframe_tx] = 12;
|
||||
|
||||
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
tx_amp = get_tx_amp(Po_PUCCH,
|
||||
ue->tx_power_max_dBm,
|
||||
ue->frame_parms.N_RB_UL,
|
||||
1);
|
||||
ue->tx_power_max_dBm,
|
||||
ue->frame_parms.N_RB_UL,
|
||||
1);
|
||||
#else
|
||||
tx_amp = AMP;
|
||||
#endif
|
||||
#if T_TRACER
|
||||
T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
|
||||
T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
|
||||
T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
|
||||
#endif
|
||||
|
||||
int len;
|
||||
// get the payload : < 12 bits, returned in len
|
||||
CQI_payload = get_pucch2_cqi(ue,eNB_id,&len);
|
||||
generate_pucch2x(ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
ue->ncs_cell,
|
||||
format,
|
||||
&ue->pucch_config_dedicated[eNB_id],
|
||||
n2_pucch,
|
||||
&CQI_payload,
|
||||
len, // A
|
||||
0, // B2 not needed
|
||||
tx_amp,
|
||||
subframe_tx,
|
||||
ue->pdcch_vars[eNB_id]->crnti);
|
||||
|
||||
ue->generate_ul_signal[eNB_id] = 1;
|
||||
|
||||
LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (CQI %d), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx, subframe_tx,CQI_payload,
|
||||
n2_pucch,
|
||||
Po_PUCCH,
|
||||
isShortenPucch,
|
||||
tx_amp);
|
||||
|
||||
}
|
||||
// Periodic RI report
|
||||
else if ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
|
||||
(is_ri_TXOp(ue,proc,eNB_id)==1)){
|
||||
|
||||
if (ue->mac_enabled == 1) {
|
||||
Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format);
|
||||
}
|
||||
else {
|
||||
Po_PUCCH = ue->tx_power_max_dBm;
|
||||
}
|
||||
ue->tx_power_dBm[subframe_tx] = Po_PUCCH;
|
||||
ue->tx_total_RE[subframe_tx] = 12;
|
||||
#if T_TRACER
|
||||
T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
|
||||
T_INT(tx_amp),T_INT(ue->dlsch[eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
|
||||
#endif
|
||||
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
|
||||
tx_amp = get_tx_amp(Po_PUCCH,
|
||||
ue->tx_power_max_dBm,
|
||||
ue->frame_parms.N_RB_UL,
|
||||
1);
|
||||
#else
|
||||
tx_amp = AMP;
|
||||
#endif
|
||||
LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx, subframe_tx,
|
||||
n2_pucch,
|
||||
Po_PUCCH,
|
||||
isShortenPucch,
|
||||
tx_amp);
|
||||
|
||||
RI_payload = get_pucch2_ri(ue,eNB_id);
|
||||
LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx%1024, subframe_tx,
|
||||
n2_pucch,
|
||||
Po_PUCCH,
|
||||
isShortenPucch,
|
||||
tx_amp);
|
||||
|
||||
generate_pucch2x(ue->common_vars.txdataF,
|
||||
&ue->frame_parms,
|
||||
ue->ncs_cell,
|
||||
format,
|
||||
&ue->pucch_config_dedicated[eNB_id],
|
||||
n2_pucch,
|
||||
&RI_payload,
|
||||
1, // A
|
||||
0, // B2 not needed
|
||||
tx_amp,
|
||||
subframe_tx,
|
||||
ue->pdcch_vars[eNB_id]->crnti);
|
||||
|
||||
ue->generate_ul_signal[eNB_id] = 1;
|
||||
}
|
||||
&ue->frame_parms,
|
||||
ue->ncs_cell,
|
||||
format,
|
||||
&ue->pucch_config_dedicated[eNB_id],
|
||||
pucch_resource,
|
||||
pucch_payload,
|
||||
len, // A
|
||||
0, // B2 not needed
|
||||
tx_amp,
|
||||
subframe_tx,
|
||||
ue->pdcch_vars[eNB_id]->crnti);
|
||||
}
|
||||
break;
|
||||
|
||||
case pucch_format2a:
|
||||
LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx%1024, subframe_tx);
|
||||
break;
|
||||
case pucch_format2b:
|
||||
LOG_I(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
|
||||
Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,
|
||||
frame_tx%1024, subframe_tx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT);
|
||||
@@ -2186,12 +2251,12 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
|
||||
reset_ack(&ue->frame_parms,
|
||||
ue->dlsch[eNB_id][0]->harq_ack,
|
||||
subframe_tx,
|
||||
ue->ulsch[eNB_id]->o_ACK);
|
||||
ue->ulsch[eNB_id]->o_ACK,0);
|
||||
|
||||
reset_ack(&ue->frame_parms,
|
||||
ue->dlsch_SI[eNB_id]->harq_ack,
|
||||
subframe_tx,
|
||||
ue->ulsch[eNB_id]->o_ACK);
|
||||
ue->ulsch[eNB_id]->o_ACK,0);
|
||||
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
|
||||
@@ -2770,9 +2835,9 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
|
||||
(dci_alloc_rx[i].format != format0)) {
|
||||
|
||||
|
||||
LOG_D(PHY,"[UE %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
|
||||
LOG_D(PHY,"[UE %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
|
||||
ue->Mod_id,dci_alloc_rx[i].rnti,
|
||||
frame_rx,subframe_rx,
|
||||
frame_rx%1024,subframe_rx,
|
||||
dci_alloc_rx[i].format,
|
||||
ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
|
||||
ue->pdcch_vars[eNB_id]->nCCE[subframe_rx],
|
||||
@@ -2801,8 +2866,10 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
|
||||
// update TPC for PUCCH
|
||||
if((dci_alloc_rx[i].format == format1) ||
|
||||
(dci_alloc_rx[i].format == format1A) ||
|
||||
(dci_alloc_rx[i].format == format1B) ||
|
||||
(dci_alloc_rx[i].format == format2) ||
|
||||
(dci_alloc_rx[i].format == format2A))
|
||||
(dci_alloc_rx[i].format == format2A) ||
|
||||
(dci_alloc_rx[i].format == format2B))
|
||||
{
|
||||
ue->dlsch[eNB_id][0]->g_pucch += ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->delta_PUCCH;
|
||||
}
|
||||
|
||||
@@ -88,17 +88,17 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
|
||||
}
|
||||
|
||||
if (pucch_fmt!=pucch_format1) {
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
|
||||
LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
|
||||
ue->Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
|
||||
ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
|
||||
Po_PUCCH,
|
||||
ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
|
||||
get_PL(ue->Mod_id,ue->CC_id,eNB_id),
|
||||
ue->dlsch[eNB_id][0]->g_pucch);
|
||||
} else {
|
||||
LOG_D(PHY,"[UE %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
|
||||
LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
|
||||
ue->Mod_id,
|
||||
ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
|
||||
ue->dlsch[eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
|
||||
Po_PUCCH,
|
||||
ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
|
||||
get_PL(ue->Mod_id,ue->CC_id,eNB_id),
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
/*******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file dlsim.c
|
||||
\brief Top-level DL simulator
|
||||
|
||||
@@ -1,31 +1,23 @@
|
||||
/******************************************************************************
|
||||
OpenAirInterface
|
||||
Copyright(c) 1999 - 2014 Eurecom
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file dlsim.c
|
||||
\brief Top-level DL simulator
|
||||
|
||||
@@ -17,31 +17,7 @@
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
|
||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
OpenAirInterface is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenAirInterface.The full GNU General Public License is
|
||||
included in this distribution in the file called "COPYING". If not,
|
||||
see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact Information
|
||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||
|
||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||
|
||||
*******************************************************************************/
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <cblas.h>
|
||||
@@ -143,8 +119,9 @@ void fill_channel_desc(channel_desc_t *chan_desc,
|
||||
else {
|
||||
chan_desc->R_sqrt = (struct complex**) calloc(nb_taps,sizeof(struct complex*));
|
||||
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));
|
||||
//chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0];
|
||||
/* all chan_desc share the same R_sqrt, coming from caller */
|
||||
chan_desc->R_sqrt[i] = R_sqrt[0];
|
||||
}
|
||||
}
|
||||
|
||||
+121
-121
@@ -19,124 +19,124 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifdef USER_MODE
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <asm/io.h>
|
||||
#include <asm/rtai.h>
|
||||
#endif
|
||||
#ifdef RTAI_ENABLED
|
||||
#include <rtai.h>
|
||||
#include <rtai_sched.h>
|
||||
#define time(x) (unsigned int)(rt_get_time_ns())
|
||||
#endif
|
||||
|
||||
unsigned int s0, s1, s2, b;
|
||||
|
||||
//----------------------------------------------
|
||||
//
|
||||
/*!
|
||||
*/
|
||||
//
|
||||
|
||||
unsigned int taus(void)
|
||||
{
|
||||
|
||||
b = (((s0 << 13) ^ s0) >> 19);
|
||||
s0 = (((s0 & 0xFFFFFFFE) << 12)^ b);
|
||||
b = (((s1 << 2) ^ s1) >> 25);
|
||||
s1 = (((s1 & 0xFFFFFFF8) << 4)^ b);
|
||||
b = (((s2 << 3) ^ s2) >> 11);
|
||||
s2 = (((s2 & 0xFFFFFFF0) << 17)^ b);
|
||||
return s0 ^ s1 ^ s2;
|
||||
}
|
||||
#if 1
|
||||
void set_taus_seed(unsigned int seed_init)
|
||||
{
|
||||
|
||||
#ifdef USER_MODE
|
||||
struct drand48_data buffer;
|
||||
unsigned long result = 0;
|
||||
#endif
|
||||
|
||||
if (seed_init == 0) {
|
||||
s0 = (unsigned int)time(NULL);
|
||||
s1 = (unsigned int)time(NULL);
|
||||
s2 = (unsigned int)time(NULL);
|
||||
} else {
|
||||
#ifndef USER_MODE
|
||||
s0 = (unsigned int)0x1e23d852;
|
||||
s1 = (unsigned int)0x81f38a1c;
|
||||
s2 = (unsigned int)0xfe1a133e;
|
||||
#else
|
||||
/* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
|
||||
srand48_r((long int)seed_init, &buffer);
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s0 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s1 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s2 = result;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void set_taus_seed(unsigned int seed_init)
|
||||
{
|
||||
|
||||
#ifdef USER_MODE
|
||||
struct drand48_data buffer;
|
||||
unsigned long result = 0;
|
||||
#endif
|
||||
s0 = (unsigned int)0x1e23d852;
|
||||
s1 = (unsigned int)0x81f38a1c;
|
||||
s2 = (unsigned int)0xfe1a133e;
|
||||
|
||||
return;
|
||||
|
||||
if (seed_init == 0) {
|
||||
s0 = (unsigned int)time(NULL);
|
||||
s1 = (unsigned int)time(NULL);
|
||||
s2 = (unsigned int)time(NULL);
|
||||
} else {
|
||||
#ifndef USER_MODE
|
||||
s0 = (unsigned int)0x1e23d852;
|
||||
s1 = (unsigned int)0x81f38a1c;
|
||||
s2 = (unsigned int)0xfe1a133e;
|
||||
#else
|
||||
// Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
|
||||
srand48_r((long int)seed_init, &buffer);
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s0 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s1 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s2 = result;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAIN
|
||||
|
||||
main()
|
||||
{
|
||||
|
||||
unsigned int i,rand;
|
||||
|
||||
set_taus_seed();
|
||||
|
||||
for (i=0; i<10; i++) {
|
||||
|
||||
rand = taus();
|
||||
printf("%u\n",rand);
|
||||
|
||||
}
|
||||
}
|
||||
#endif //MAIN
|
||||
|
||||
|
||||
|
||||
#ifdef USER_MODE
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <asm/io.h>
|
||||
#include <asm/rtai.h>
|
||||
#endif
|
||||
#ifdef RTAI_ENABLED
|
||||
#include <rtai.h>
|
||||
#include <rtai_sched.h>
|
||||
#define time(x) (unsigned int)(rt_get_time_ns())
|
||||
#endif
|
||||
|
||||
unsigned int s0, s1, s2, b;
|
||||
|
||||
//----------------------------------------------
|
||||
//
|
||||
/*!
|
||||
*/
|
||||
//
|
||||
|
||||
unsigned int taus(void)
|
||||
{
|
||||
|
||||
b = (((s0 << 13) ^ s0) >> 19);
|
||||
s0 = (((s0 & 0xFFFFFFFE) << 12)^ b);
|
||||
b = (((s1 << 2) ^ s1) >> 25);
|
||||
s1 = (((s1 & 0xFFFFFFF8) << 4)^ b);
|
||||
b = (((s2 << 3) ^ s2) >> 11);
|
||||
s2 = (((s2 & 0xFFFFFFF0) << 17)^ b);
|
||||
return s0 ^ s1 ^ s2;
|
||||
}
|
||||
#if 1
|
||||
void set_taus_seed(unsigned int seed_init)
|
||||
{
|
||||
|
||||
#ifdef USER_MODE
|
||||
struct drand48_data buffer;
|
||||
unsigned long result = 0;
|
||||
#endif
|
||||
|
||||
if (seed_init == 0) {
|
||||
s0 = (unsigned int)time(NULL);
|
||||
s1 = (unsigned int)time(NULL);
|
||||
s2 = (unsigned int)time(NULL);
|
||||
} else {
|
||||
#ifndef USER_MODE
|
||||
s0 = (unsigned int)0x1e23d852;
|
||||
s1 = (unsigned int)0x81f38a1c;
|
||||
s2 = (unsigned int)0xfe1a133e;
|
||||
#else
|
||||
/* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
|
||||
srand48_r((long int)seed_init, &buffer);
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s0 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s1 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s2 = result;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void set_taus_seed(unsigned int seed_init)
|
||||
{
|
||||
|
||||
#ifdef USER_MODE
|
||||
struct drand48_data buffer;
|
||||
unsigned long result = 0;
|
||||
#endif
|
||||
s0 = (unsigned int)0x1e23d852;
|
||||
s1 = (unsigned int)0x81f38a1c;
|
||||
s2 = (unsigned int)0xfe1a133e;
|
||||
|
||||
return;
|
||||
|
||||
if (seed_init == 0) {
|
||||
s0 = (unsigned int)time(NULL);
|
||||
s1 = (unsigned int)time(NULL);
|
||||
s2 = (unsigned int)time(NULL);
|
||||
} else {
|
||||
#ifndef USER_MODE
|
||||
s0 = (unsigned int)0x1e23d852;
|
||||
s1 = (unsigned int)0x81f38a1c;
|
||||
s2 = (unsigned int)0xfe1a133e;
|
||||
#else
|
||||
// Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
|
||||
srand48_r((long int)seed_init, &buffer);
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s0 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s1 = result;
|
||||
mrand48_r(&buffer, (long int *)&result);
|
||||
s2 = result;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAIN
|
||||
|
||||
main()
|
||||
{
|
||||
|
||||
unsigned int i,rand;
|
||||
|
||||
set_taus_seed();
|
||||
|
||||
for (i=0; i<10; i++) {
|
||||
|
||||
rand = taus();
|
||||
printf("%u\n",rand);
|
||||
|
||||
}
|
||||
}
|
||||
#endif //MAIN
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -316,15 +316,6 @@ typedef struct {
|
||||
*/
|
||||
#define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];}
|
||||
|
||||
/*
|
||||
* User notification callback, executed whenever a change of data with
|
||||
* respect of network information (e.g. network registration and/or
|
||||
* location change, new PLMN becomes available) is notified by the
|
||||
* EPS Mobility Management sublayer
|
||||
*/
|
||||
typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t,
|
||||
const char*, size_t);
|
||||
|
||||
typedef enum eps_protocol_discriminator_e {
|
||||
/* Protocol discriminator identifier for EPS Mobility Management */
|
||||
EPS_MOBILITY_MANAGEMENT_MESSAGE = 0x7,
|
||||
|
||||
@@ -252,13 +252,6 @@ typedef struct {
|
||||
network_pkf_t* pkf[NET_PACKET_FILTER_MAX];
|
||||
} network_tft_t;
|
||||
|
||||
/*
|
||||
* User notification callback, executed whenever a change of status with
|
||||
* respect of PDN connection or EPS bearer context is notified by the EPS
|
||||
* Session Management sublayer
|
||||
*/
|
||||
typedef int (*esm_indication_callback_t) (int, network_pdn_state_t);
|
||||
|
||||
/****************************************************************************/
|
||||
/******************** G L O B A L V A R I A B L E S ********************/
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -264,7 +264,7 @@ typedef struct protocol_ctxt_s {
|
||||
(Ctxt_Pp)->subframe = sUBfRAME; \
|
||||
PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp)
|
||||
|
||||
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %"PRIx16"]"
|
||||
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]"
|
||||
#define PROTOCOL_CTXT_ARGS(CTXT_Pp) \
|
||||
(CTXT_Pp)->frame, \
|
||||
((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \
|
||||
|
||||
@@ -443,14 +443,14 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
if (rlc_reports[j] == NULL)
|
||||
goto error;
|
||||
protocol__flex_rlc_bsr__init(rlc_reports[j]);
|
||||
rlc_reports[j]->lc_id = j+1;
|
||||
rlc_reports[j]->lc_id = j + 1;
|
||||
rlc_reports[j]->has_lc_id = 1;
|
||||
rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id,i,j+1);
|
||||
rlc_reports[j]->tx_queue_size = flexran_get_tx_queue_size(enb_id,i,j + 1);
|
||||
rlc_reports[j]->has_tx_queue_size = 1;
|
||||
|
||||
|
||||
//TODO:Set tx queue head of line delay in ms
|
||||
rlc_reports[j]->tx_queue_hol_delay = 100;
|
||||
rlc_reports[j]->has_tx_queue_hol_delay = 0;
|
||||
rlc_reports[j]->tx_queue_hol_delay = flexran_get_hol_delay(enb_id, i, j+1);
|
||||
rlc_reports[j]->has_tx_queue_hol_delay = 1;
|
||||
//TODO:Set retransmission queue size in bytes
|
||||
rlc_reports[j]->retransmission_queue_size = 10;
|
||||
rlc_reports[j]->has_retransmission_queue_size = 0;
|
||||
@@ -657,6 +657,8 @@ int flexran_agent_mac_stats_reply(mid_t mod_id,
|
||||
full_ul_report->pucch_dbm[j]->p0_pucch_dbm = flexran_get_p0_pucch_dbm(enb_id,i,j);
|
||||
full_ul_report->pucch_dbm[j]->has_p0_pucch_dbm = 1;
|
||||
}
|
||||
full_ul_report->pucch_dbm[j]->has_p0_pucch_updated = 1;
|
||||
full_ul_report->pucch_dbm[j]->p0_pucch_updated = flexran_get_p0_pucch_status(enb_id, i, j);
|
||||
}
|
||||
|
||||
//Add full UL CQI report to the UE report
|
||||
@@ -921,9 +923,13 @@ int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg) {
|
||||
|
||||
int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
|
||||
Protocol__FlexHeader *header;
|
||||
int i,j;
|
||||
int i, j, UE_id;
|
||||
|
||||
int available_harq[NUMBER_OF_UE_MAX];
|
||||
|
||||
const int xid = *((int *)params);
|
||||
|
||||
|
||||
Protocol__FlexSfTrigger *sf_trigger_msg;
|
||||
sf_trigger_msg = malloc(sizeof(Protocol__FlexSfTrigger));
|
||||
if (sf_trigger_msg == NULL) {
|
||||
@@ -937,29 +943,47 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
|
||||
frame_t frame;
|
||||
sub_frame_t subframe;
|
||||
|
||||
int ahead_of_time = 1;
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
available_harq[i] = -1;
|
||||
}
|
||||
|
||||
int ahead_of_time = 0;
|
||||
|
||||
frame = (frame_t) flexran_get_current_system_frame_num(mod_id);
|
||||
subframe = (sub_frame_t) flexran_get_current_subframe(mod_id);
|
||||
|
||||
subframe = ((subframe + ahead_of_time) % 10);
|
||||
|
||||
int full_frames_ahead = ((ahead_of_time / 10) % 10);
|
||||
|
||||
frame = frame + full_frames_ahead;
|
||||
|
||||
if (subframe < flexran_get_current_subframe(mod_id)) {
|
||||
frame++;
|
||||
frame = (frame + 1) % 1024;
|
||||
}
|
||||
|
||||
int additional_frames = ahead_of_time / 10;
|
||||
frame = (frame + additional_frames) % 1024;
|
||||
|
||||
sf_trigger_msg->header = header;
|
||||
sf_trigger_msg->has_sfn_sf = 1;
|
||||
sf_trigger_msg->sfn_sf = flexran_get_future_sfn_sf(mod_id, 1);
|
||||
sf_trigger_msg->sfn_sf = flexran_get_future_sfn_sf(mod_id, 3);
|
||||
|
||||
sf_trigger_msg->n_dl_info = 0;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (harq_pid_updated[i][j] == 1) {
|
||||
available_harq[i] = j;
|
||||
sf_trigger_msg->n_dl_info++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10);
|
||||
|
||||
/*TODO: Fill in the number of dl HARQ related info, based on the number of currently
|
||||
*transmitting UEs
|
||||
*/
|
||||
sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id);
|
||||
// sf_trigger_msg->n_dl_info = flexran_get_num_ues(mod_id);
|
||||
|
||||
Protocol__FlexDlInfo **dl_info = NULL;
|
||||
|
||||
@@ -967,29 +991,39 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle
|
||||
dl_info = malloc(sizeof(Protocol__FlexDlInfo *) * sf_trigger_msg->n_dl_info);
|
||||
if(dl_info == NULL)
|
||||
goto error;
|
||||
i = -1;
|
||||
//Fill the status of the current HARQ process for each UE
|
||||
for(i = 0; i < sf_trigger_msg->n_dl_info; i++) {
|
||||
for(UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
|
||||
if (available_harq[UE_id] < 0) {
|
||||
continue;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
dl_info[i] = malloc(sizeof(Protocol__FlexDlInfo));
|
||||
if(dl_info[i] == NULL)
|
||||
goto error;
|
||||
protocol__flex_dl_info__init(dl_info[i]);
|
||||
dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, i);
|
||||
dl_info[i]->rnti = flexran_get_ue_crnti(mod_id, UE_id);
|
||||
dl_info[i]->has_rnti = 1;
|
||||
/*Fill in the right id of this round's HARQ process for this UE*/
|
||||
unsigned char harq_id;
|
||||
unsigned char harq_status;
|
||||
flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status);
|
||||
dl_info[i]->harq_process_id = harq_id;
|
||||
// uint8_t harq_id;
|
||||
//uint8_t harq_status;
|
||||
// flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status);
|
||||
|
||||
|
||||
dl_info[i]->harq_process_id = available_harq[UE_id];
|
||||
harq_pid_updated[UE_id][available_harq[UE_id]] = 0;
|
||||
dl_info[i]->has_harq_process_id = 1;
|
||||
/* Fill in the status of the HARQ process (2 TBs)*/
|
||||
dl_info[i]->n_harq_status = 2;
|
||||
dl_info[i]->harq_status = malloc(sizeof(uint32_t) * dl_info[i]->n_harq_status);
|
||||
for (j = 0; j < dl_info[i]->n_harq_status; j++) {
|
||||
dl_info[i]->harq_status[j] = harq_pid_round[UE_id][available_harq[UE_id]];
|
||||
// TODO: This should be different per TB
|
||||
if(harq_status == 0)
|
||||
dl_info[i]->harq_status[j] = PROTOCOL__FLEX_HARQ_STATUS__FLHS_ACK;
|
||||
else if (harq_status > 0)
|
||||
dl_info[i]->harq_status[j] = PROTOCOL__FLEX_HARQ_STATUS__FLHS_NACK;
|
||||
}
|
||||
// LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d and harq %d (round %d)\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10, dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]);
|
||||
if(dl_info[i]->harq_status[0] > 0) {
|
||||
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Need to make a retransmission for harq %d (round %d)\n", flexran_get_current_frame(mod_id), flexran_get_current_subframe(mod_id), dl_info[i]->harq_process_id, dl_info[i]->harq_status[0]);
|
||||
}
|
||||
/*Fill in the serving cell index for this UE */
|
||||
dl_info[i]->serv_cell_index = UE_PCCID(mod_id,i);
|
||||
@@ -1234,12 +1268,18 @@ int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Pro
|
||||
}
|
||||
|
||||
void flexran_agent_init_mac_agent(mid_t mod_id) {
|
||||
int i, j;
|
||||
lfds700_misc_library_init_valid_on_current_logical_core();
|
||||
lfds700_misc_prng_init(&ps[mod_id]);
|
||||
int num_elements = RINGBUFFER_SIZE + 1;
|
||||
//Allow RINGBUFFER_SIZE messages to be stored in the ringbuffer at any time
|
||||
dl_mac_config_array[mod_id] = malloc( sizeof(struct lfds700_ringbuffer_element) * num_elements);
|
||||
lfds700_ringbuffer_init_valid_on_current_logical_core( &ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL );
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
harq_pid_updated[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************
|
||||
|
||||
@@ -166,6 +166,7 @@ message flex_ul_cqi_report {
|
||||
message flex_pucch_dbm {
|
||||
optional int32 p0_pucch_dbm = 1;
|
||||
optional uint32 serv_cell_index = 2;
|
||||
optional uint32 p0_pucch_updated = 3;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
#define ENB_CONFIG_STRING_RRH_GW_IQ_TXSHIFT "iq_txshift"
|
||||
#define ENB_CONFIG_STRING_RRH_GW_TX_SAMPLE_ADVANCE "tx_sample_advance"
|
||||
#define ENB_CONFIG_STRING_RRH_GW_TX_SCHEDULING_ADVANCE "tx_scheduling_advance"
|
||||
#define ENB_CONFIG_STRING_RRH_GW_IF_COMPRESSION "if_compression"
|
||||
|
||||
#define ENB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
|
||||
#define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE "none"
|
||||
@@ -338,6 +339,7 @@ void enb_config_display(void)
|
||||
} else {
|
||||
printf( "\tRF target : \tNONE:\n");
|
||||
}
|
||||
printf( "\tif_compression : \t%s Compression:\n",(enb_properties.properties[i]->rrh_gw_config[j].if_compress == 1)? "ALAW" : "None");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,6 +659,7 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
|
||||
char* ipv6 = NULL;
|
||||
char* active = NULL;
|
||||
char* preference = NULL;
|
||||
char* if_compression = NULL;
|
||||
|
||||
char* tr_preference = NULL;
|
||||
char* rf_preference = NULL;
|
||||
@@ -2327,81 +2330,91 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
|
||||
// RRH Config
|
||||
setting_rrh_gws = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_RRH_GW_CONFIG);
|
||||
if ( setting_rrh_gws != NULL) {
|
||||
num_rrh_gw = config_setting_length(setting_rrh_gws);
|
||||
enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;
|
||||
num_rrh_gw = config_setting_length(setting_rrh_gws);
|
||||
enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;
|
||||
|
||||
for (j = 0; j < num_rrh_gw; j++) {
|
||||
setting_rrh_gw = config_setting_get_elem(setting_rrh_gws, j);
|
||||
|
||||
if ( !(
|
||||
config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME, (const char **)&if_name)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS, (const char **)&ipv4)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS , (const char **)&ipv4_remote)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT, &local_port)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT, &remote_port)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_ACTIVE, (const char **)&active)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TRANSPORT_PREFERENCE, (const char **)&tr_preference)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_RF_TARGET_PREFERENCE, (const char **)&rf_preference)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_IQ_TXSHIFT, &iq_txshift)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SAMPLE_ADVANCE, &tx_sample_advance)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SCHEDULING_ADVANCE, &tx_scheduling_advance)
|
||||
)
|
||||
) {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, %u th enb %u the RRH GW address !\n",
|
||||
lib_config_file_name_pP, i, j);
|
||||
continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
|
||||
}
|
||||
|
||||
enb_properties.properties[enb_properties_index]->nb_rrh_gw += 1;
|
||||
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rrh_gw_if_name = strdup(if_name);
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address = strdup(ipv4);
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = strdup(ipv4_remote);
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port = local_port;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port = remote_port;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].iq_txshift = iq_txshift;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_sample_advance = tx_sample_advance;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_scheduling_advance= tx_scheduling_advance;
|
||||
|
||||
if (strcmp(active, "yes") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 1;
|
||||
}
|
||||
|
||||
if (strcmp(tr_preference, "udp") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
|
||||
} else if (strcmp(tr_preference, "raw") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
|
||||
} else if (strcmp(tr_preference, "udp_if4p5") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udpif4p5 = 1;
|
||||
} else if (strcmp(tr_preference, "raw_if4p5") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif4p5 = 1;
|
||||
} else if (strcmp(tr_preference, "raw_if5_mobipass") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif5_mobipass = 1;
|
||||
} else {//if (strcmp(preference, "no") == 0)
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
|
||||
}
|
||||
|
||||
if (strcmp(rf_preference, "exmimo") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1;
|
||||
} else if (strcmp(rf_preference, "usrp_b200") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1;
|
||||
} else if (strcmp(rf_preference, "usrp_x300") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1;
|
||||
} else if (strcmp(rf_preference, "bladerf") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1;
|
||||
} else if (strcmp(rf_preference, "bladerf") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1;
|
||||
} else {//if (strcmp(preference, "no") == 0)
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1;
|
||||
|
||||
}
|
||||
}
|
||||
for (j = 0; j < num_rrh_gw; j++) {
|
||||
setting_rrh_gw = config_setting_get_elem(setting_rrh_gws, j);
|
||||
|
||||
if ( !(
|
||||
config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_IF_NAME, (const char **)&if_name)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_ADDRESS, (const char **)&ipv4)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_ADDRESS , (const char **)&ipv4_remote)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_LOCAL_PORT, &local_port)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_REMOTE_PORT, &remote_port)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_ACTIVE, (const char **)&active)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TRANSPORT_PREFERENCE, (const char **)&tr_preference)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_RF_TARGET_PREFERENCE, (const char **)&rf_preference)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_IQ_TXSHIFT, &iq_txshift)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SAMPLE_ADVANCE, &tx_sample_advance)
|
||||
&& config_setting_lookup_int(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_TX_SCHEDULING_ADVANCE, &tx_scheduling_advance)
|
||||
&& config_setting_lookup_string(setting_rrh_gw, ENB_CONFIG_STRING_RRH_GW_IF_COMPRESSION, (const char **)&if_compression)
|
||||
)
|
||||
) {
|
||||
AssertFatal (0,
|
||||
"Failed to parse eNB configuration file %s, %u th enb %u the RRH GW address !\n",
|
||||
lib_config_file_name_pP, i, j);
|
||||
continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
|
||||
}
|
||||
|
||||
enb_properties.properties[enb_properties_index]->nb_rrh_gw += 1;
|
||||
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rrh_gw_if_name = strdup(if_name);
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_address = strdup(ipv4);
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_address = strdup(ipv4_remote);
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].local_port = local_port;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].remote_port = remote_port;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].iq_txshift = iq_txshift;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_sample_advance = tx_sample_advance;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].tx_scheduling_advance= tx_scheduling_advance;
|
||||
|
||||
if (strcmp(active, "yes") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].active = 1;
|
||||
}
|
||||
|
||||
if (strcmp(tr_preference, "udp") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
|
||||
} else if (strcmp(tr_preference, "raw") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
|
||||
} else if (strcmp(tr_preference, "udp_if4p5") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udpif4p5 = 1;
|
||||
} else if (strcmp(tr_preference, "raw_if4p5") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif4p5 = 1;
|
||||
} else if (strcmp(tr_preference, "raw_if5_mobipass") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif5_mobipass = 1;
|
||||
} else {//if (strcmp(preference, "no") == 0)
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
|
||||
}
|
||||
|
||||
if (strcmp(rf_preference, "exmimo") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1;
|
||||
} else if (strcmp(rf_preference, "usrp_b200") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1;
|
||||
} else if (strcmp(rf_preference, "usrp_x300") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1;
|
||||
} else if (strcmp(rf_preference, "bladerf") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1;
|
||||
} else if (strcmp(rf_preference, "lmsdr") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1;
|
||||
} else {//if (strcmp(preference, "no") == 0)
|
||||
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].exmimo = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_b200 = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 1;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 1;
|
||||
|
||||
}
|
||||
|
||||
if (strcmp(if_compression, "alaw") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 1;
|
||||
} else if (strcmp(if_compression, "none") == 0) {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 0;
|
||||
} else {
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
enb_properties.properties[enb_properties_index]->nb_rrh_gw = 0;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rrh_gw_if_name = "none";
|
||||
@@ -2420,8 +2433,9 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].usrp_x300 = 0;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].bladerf = 0;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].lmssdr = 0;
|
||||
enb_properties.properties[enb_properties_index]->rrh_gw_config[j].if_compress = 0;
|
||||
}
|
||||
|
||||
|
||||
// SCTP SETTING
|
||||
enb_properties.properties[enb_properties_index]->sctp_out_streams = SCTP_OUT_STREAMS;
|
||||
enb_properties.properties[enb_properties_index]->sctp_in_streams = SCTP_IN_STREAMS;
|
||||
|
||||
@@ -85,6 +85,7 @@ typedef struct rrh_gw_config_s {
|
||||
uint8_t udpif4p5;
|
||||
uint8_t rawif4p5;
|
||||
uint8_t rawif5_mobipass;
|
||||
uint8_t if_compress;
|
||||
int tx_scheduling_advance;
|
||||
int tx_sample_advance;
|
||||
int iq_txshift;
|
||||
|
||||
@@ -516,15 +516,14 @@ uint16_t flexran_get_future_sfn_sf (mid_t mod_id, int ahead_of_time) {
|
||||
subframe = (sub_frame_t) flexran_get_current_subframe(mod_id);
|
||||
|
||||
subframe = ((subframe + ahead_of_time) % 10);
|
||||
|
||||
int full_frames_ahead = ((ahead_of_time / 10) % 10);
|
||||
|
||||
frame = frame + full_frames_ahead;
|
||||
|
||||
if (subframe < flexran_get_current_subframe(mod_id)) {
|
||||
frame++;
|
||||
frame = (frame + 1) % 1024;
|
||||
}
|
||||
|
||||
|
||||
int additional_frames = ahead_of_time / 10;
|
||||
frame = (frame + additional_frames) % 1024;
|
||||
|
||||
frame_mask = ((1<<12) - 1);
|
||||
sf_mask = ((1<<4) - 1);
|
||||
sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
|
||||
@@ -553,69 +552,81 @@ int flexran_get_ue_phr (mid_t mod_id, mid_t ue_id) {
|
||||
}
|
||||
|
||||
int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id) {
|
||||
return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, 0, UE_RNTI(mod_id, ue_id));
|
||||
return eNB_UE_stats->DL_cqi[0];
|
||||
|
||||
// return ((UE_list_t *)enb_ue[mod_id])->eNB_UE_stats[UE_PCCID(mod_id,ue_id)][ue_id].dl_cqi;
|
||||
}
|
||||
|
||||
int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
|
||||
rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
|
||||
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO,channel_id,0);
|
||||
return rlc_status.bytes_in_buffer;
|
||||
rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
|
||||
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id,frame,ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0);
|
||||
return rlc_status.bytes_in_buffer;
|
||||
}
|
||||
|
||||
int flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) {
|
||||
int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
|
||||
rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
uint16_t frame = (uint16_t) flexran_get_current_frame(mod_id);
|
||||
mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0);
|
||||
return rlc_status.head_sdu_creation_time;
|
||||
}
|
||||
|
||||
short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id) {
|
||||
|
||||
UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id];
|
||||
int rnti;
|
||||
|
||||
rnti = flexran_get_ue_crnti(mod_id, ue_id);
|
||||
if (ue_sched_ctl->ta_timer == 0) {
|
||||
|
||||
// WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY
|
||||
switch (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RB_DL) {
|
||||
case 6:
|
||||
ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/2;
|
||||
break;
|
||||
|
||||
case 25:
|
||||
ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/4;
|
||||
break;
|
||||
|
||||
case 50:
|
||||
ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/8;
|
||||
break;
|
||||
|
||||
case 75:
|
||||
ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/12;
|
||||
break;
|
||||
|
||||
case 100:
|
||||
ue_sched_ctl->ta_update = eNB_UE_stats->timing_advance_update/16;
|
||||
break;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
//ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY
|
||||
switch (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.N_RB_DL) {
|
||||
case 6:
|
||||
return eNB_UE_stats->timing_advance_update;
|
||||
case 15:
|
||||
return eNB_UE_stats->timing_advance_update/2;
|
||||
case 25:
|
||||
return eNB_UE_stats->timing_advance_update/4;
|
||||
case 50:
|
||||
return eNB_UE_stats->timing_advance_update/8;
|
||||
case 75:
|
||||
return eNB_UE_stats->timing_advance_update/12;
|
||||
case 100:
|
||||
if (PHY_vars_eNB_g[mod_id][CC_id]->frame_parms.threequarter_fs == 0) {
|
||||
return eNB_UE_stats->timing_advance_update/16;
|
||||
} else {
|
||||
return eNB_UE_stats->timing_advance_update/12;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id) {
|
||||
|
||||
UE_list_t *UE_list=&eNB_mac_inst[mod_id].UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id];
|
||||
|
||||
if (ue_sched_ctl->ta_timer == 0) {
|
||||
|
||||
// WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...
|
||||
// LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
//ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY
|
||||
ue_sched_ctl->ta_update = flexran_get_TA(mod_id, ue_id, CC_id);
|
||||
|
||||
// clear the update in case PHY does not have a new measurement after timer expiry
|
||||
eNB_UE_stats->timing_advance_update = 0;
|
||||
}
|
||||
else {
|
||||
// eNB_UE_stats->timing_advance_update = 0;
|
||||
} else {
|
||||
ue_sched_ctl->ta_timer--;
|
||||
ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command
|
||||
ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command
|
||||
}
|
||||
|
||||
return ue_sched_ctl->ta_update = 0;
|
||||
|
||||
}
|
||||
|
||||
int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) {
|
||||
|
||||
UE_list_t *UE_list = &eNB_mac_inst[mod_id].UE_list;
|
||||
UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[ue_id];
|
||||
|
||||
rnti_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti);
|
||||
@@ -624,8 +635,8 @@ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id,int CC_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ue_sched_ctl->ta_update == 0) {
|
||||
return 1;
|
||||
if (flexran_get_TA(mod_id, ue_id, CC_id) != 0) {
|
||||
return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -680,8 +691,13 @@ int flexran_get_tpc(mid_t mod_id, mid_t ue_id) {
|
||||
return tpc;
|
||||
}
|
||||
|
||||
int flexran_get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, const int frame, const uint8_t subframe,
|
||||
unsigned char *id, unsigned char *round) { //flag_id_status = 0 then id, else status
|
||||
int flexran_get_harq(const mid_t mod_id,
|
||||
const uint8_t CC_id,
|
||||
const mid_t ue_id,
|
||||
const int frame,
|
||||
const uint8_t subframe,
|
||||
uint8_t *id,
|
||||
uint8_t *round) { //flag_id_status = 0 then id, else status
|
||||
/*TODO: Add int TB in function parameters to get the status of the second TB. This can be done to by editing in
|
||||
* get_ue_active_harq_pid function in line 272 file: phy_procedures_lte_eNB.c to add
|
||||
* DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/
|
||||
@@ -707,43 +723,43 @@ int flexran_get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id,
|
||||
}
|
||||
|
||||
int flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, int CC_id) {
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
|
||||
if (eNB_UE_stats == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(eNB_UE_stats->Po_PUCCH_update == 1) {
|
||||
return eNB_UE_stats->Po_PUCCH_dBm;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
|
||||
if (eNB_UE_stats == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if(eNB_UE_stats->Po_PUCCH_update == 1) {
|
||||
return eNB_UE_stats->Po_PUCCH_dBm;
|
||||
//}
|
||||
//else
|
||||
// return -1;
|
||||
}
|
||||
|
||||
int flexran_get_p0_nominal_pucch(mid_t mod_id, int CC_id) {
|
||||
int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id);
|
||||
return pucch_rx_received;
|
||||
int32_t pucch_rx_received = mac_xface->get_target_pucch_rx_power(mod_id, CC_id);
|
||||
return pucch_rx_received;
|
||||
}
|
||||
|
||||
int flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, int CC_id) {
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
return eNB_UE_stats->Po_PUCCH_update;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
return eNB_UE_stats->Po_PUCCH_update;
|
||||
}
|
||||
|
||||
int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, int CC_id) {
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
eNB_UE_stats->Po_PUCCH_update = 0;
|
||||
|
||||
return 0;
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint32_t rnti = flexran_get_ue_crnti(mod_id,ue_id);
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
|
||||
eNB_UE_stats->Po_PUCCH_update = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -185,8 +185,14 @@ int flexran_get_ue_wcqi (mid_t mod_id, mid_t ue_id);
|
||||
/* Get the transmission queue size for a UE with a channel_id logical channel id */
|
||||
int flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id);
|
||||
|
||||
/* Get the head of line delay for a UE with a channel_id logical channel id */
|
||||
int flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id);
|
||||
|
||||
/* Check the status of the timing advance for a UE */
|
||||
short flexran_get_TA(mid_t mod_id, mid_t ue_id, int CC_id);
|
||||
|
||||
/* Update the timing advance status (find out whether a timing advance command is required) */
|
||||
int flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id);
|
||||
void flexran_update_TA(mid_t mod_id, mid_t ue_id, int CC_id);
|
||||
|
||||
/* Return timing advance MAC control element for a designated cell and UE */
|
||||
int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, int CC_id);
|
||||
|
||||
@@ -45,4 +45,8 @@ extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
|
||||
/* Flag indicating whether the VSFs for the MAC control module have been registered */
|
||||
extern unsigned int mac_agent_registered[NUM_MAX_ENB];
|
||||
|
||||
/* Requried to know which UEs had a harq updated over some subframe */
|
||||
extern int harq_pid_updated[NUMBER_OF_UE_MAX][8];
|
||||
extern int harq_pid_round[NUMBER_OF_UE_MAX][8];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -172,7 +172,7 @@ Protocol__FlexranMessage* flexran_agent_process_timeout(long timer_id, void* tim
|
||||
struct flexran_agent_timer_element_s *found = get_timer_entry(timer_id);
|
||||
|
||||
if (found == NULL ) goto error;
|
||||
LOG_I(FLEXRAN_AGENT, "Found the entry (%p): timer_id is 0x%lx 0x%lx\n", found, timer_id, found->timer_id);
|
||||
LOG_D(FLEXRAN_AGENT, "Found the entry (%p): timer_id is 0x%lx 0x%lx\n", found, timer_id, found->timer_id);
|
||||
|
||||
if (timer_args == NULL)
|
||||
LOG_W(FLEXRAN_AGENT,"null timer args\n");
|
||||
|
||||
@@ -132,6 +132,10 @@
|
||||
#define MIN_CQI_VALUE 0
|
||||
/*!\brief maximum value for channel quality indicator */
|
||||
#define MAX_CQI_VALUE 15
|
||||
/*!\briefmaximum number of supported bandwidth (1.4, 5, 10, 20 MHz) */
|
||||
#define MAX_SUPPORTED_BW 4
|
||||
/*!\brief CQI values range from 1 to 15 (4 bits) */
|
||||
#define CQI_VALUE_RANGE 16
|
||||
|
||||
/*!\brief value for indicating BSR Timer is not running */
|
||||
#define MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF)
|
||||
|
||||
@@ -104,6 +104,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
|
||||
rnti_t rnti;
|
||||
void *DLSCH_dci=NULL;
|
||||
int size_bits=0,size_bytes=0;
|
||||
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
|
||||
#if defined(FLEXRAN_AGENT_SB_IF)
|
||||
Protocol__FlexranMessage *msg;
|
||||
@@ -150,9 +152,9 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
|
||||
eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
|
||||
|
||||
eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].cqi_req_timer++;
|
||||
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
|
||||
if (mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti)==NULL) {
|
||||
if (eNB_UE_stats==NULL) {
|
||||
//mac_remove_ue(module_idP, i, frameP, subframeP);
|
||||
//Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
|
||||
#if defined(FLEXRAN_AGENT_SB_IF)
|
||||
@@ -247,8 +249,8 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag,
|
||||
add_ue_spec_dci(DCI_pdu[CC_id],
|
||||
DLSCH_dci,
|
||||
rnti,
|
||||
size_bytes,
|
||||
process_ue_cqi (module_idP,i),//aggregation,
|
||||
size_bytes,
|
||||
get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1A),
|
||||
size_bits,
|
||||
format1A,
|
||||
0);
|
||||
|
||||
@@ -463,7 +463,7 @@ schedule_ue_spec(
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
|
||||
|
||||
//weight = get_ue_weight(module_idP,UE_id);
|
||||
aggregation = 1; // set to the maximum aggregation level
|
||||
aggregation = 2;
|
||||
|
||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
min_rb_unit[CC_id]=get_min_rb_unit(module_idP,CC_id);
|
||||
@@ -520,10 +520,28 @@ schedule_ue_spec(
|
||||
// mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
|
||||
continue_flag=1;
|
||||
}
|
||||
|
||||
if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated
|
||||
CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)
|
||||
) {
|
||||
|
||||
switch(mac_xface->get_transmission_mode(module_idP,CC_id,rnti)){
|
||||
case 1:
|
||||
case 2:
|
||||
case 7:
|
||||
aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
|
||||
eNB_UE_stats->DL_cqi[0],
|
||||
format1);
|
||||
break;
|
||||
case 3:
|
||||
aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
|
||||
eNB_UE_stats->DL_cqi[0],
|
||||
format2A);
|
||||
break;
|
||||
default:
|
||||
LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(module_idP,CC_id,rnti));
|
||||
aggregation = 2;
|
||||
}
|
||||
|
||||
if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated
|
||||
CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)
|
||||
) {
|
||||
LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
|
||||
module_idP, frameP, UE_id, CC_id);
|
||||
//if(mac_xface->get_transmission_mode(module_idP,rnti)==5)
|
||||
@@ -630,9 +648,6 @@ schedule_ue_spec(
|
||||
}
|
||||
|
||||
nb_available_rb -= nb_rb;
|
||||
aggregation = process_ue_cqi(module_idP,UE_id);
|
||||
|
||||
|
||||
PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
|
||||
PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
|
||||
|
||||
@@ -1120,8 +1135,7 @@ schedule_ue_spec(
|
||||
T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
|
||||
T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
|
||||
|
||||
aggregation = process_ue_cqi(module_idP,UE_id);
|
||||
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
|
||||
UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
|
||||
|
||||
add_ue_dlsch_info(module_idP,
|
||||
CC_id,
|
||||
@@ -1574,6 +1588,7 @@ schedule_ue_spec(
|
||||
}
|
||||
|
||||
break;
|
||||
*/
|
||||
/*
|
||||
// disabled for now as this needs to be done properly
|
||||
case 5:
|
||||
@@ -1660,7 +1675,8 @@ fill_DLSCH_dci(
|
||||
eNB_MAC_INST *eNB =&eNB_mac_inst[module_idP];
|
||||
UE_list_t *UE_list = &eNB->UE_list;
|
||||
//RA_TEMPLATE *RA_template;
|
||||
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
|
||||
start_meas(&eNB->fill_DLSCH_dci);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,VCD_FUNCTION_IN);
|
||||
|
||||
@@ -1687,6 +1703,7 @@ fill_DLSCH_dci(
|
||||
nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
|
||||
|
||||
DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid];
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
|
||||
|
||||
/// Synchronizing rballoc with rballoc_sub
|
||||
@@ -1786,7 +1803,7 @@ fill_DLSCH_dci(
|
||||
DLSCH_dci,
|
||||
rnti,
|
||||
size_bytes,
|
||||
process_ue_cqi (module_idP,UE_id),//aggregation,
|
||||
get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1),
|
||||
size_bits,
|
||||
format1,
|
||||
0);
|
||||
@@ -1882,8 +1899,8 @@ fill_DLSCH_dci(
|
||||
DLSCH_dci,
|
||||
rnti,
|
||||
size_bytes,
|
||||
process_ue_cqi (module_idP,UE_id),//aggregation,
|
||||
size_bits,
|
||||
get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format2A),
|
||||
size_bits,
|
||||
format2A,
|
||||
0);
|
||||
|
||||
|
||||
@@ -181,11 +181,41 @@ uint8_t find_active_UEs(module_id_t module_idP,int CC_id){
|
||||
*/
|
||||
|
||||
|
||||
// get aggregatiob form phy for a give UE
|
||||
unsigned char process_ue_cqi (module_id_t module_idP, int ue_idP)
|
||||
// get aggregation (L) form phy for a give UE
|
||||
unsigned char get_aggregation (uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt)
|
||||
{
|
||||
unsigned char aggregation=1;
|
||||
// check the MCS and SNR and set the aggregation accordingly
|
||||
unsigned char aggregation=3;
|
||||
|
||||
switch (dci_fmt){
|
||||
|
||||
case format0:
|
||||
aggregation = cqi2fmt0_agg[bw_index][cqi];
|
||||
break;
|
||||
case format1:
|
||||
case format1A:
|
||||
case format1B:
|
||||
case format1D:
|
||||
aggregation = cqi2fmt1x_agg[bw_index][cqi];
|
||||
break;
|
||||
case format2:
|
||||
case format2A:
|
||||
case format2B:
|
||||
case format2C:
|
||||
case format2D:
|
||||
aggregation = cqi2fmt2x_agg[bw_index][cqi];
|
||||
break;
|
||||
case format1C:
|
||||
case format1E_2A_M10PRB:
|
||||
case format3:
|
||||
case format3A:
|
||||
case format4:
|
||||
default:
|
||||
LOG_W(MAC,"unsupported DCI format %d\n",dci_fmt);
|
||||
}
|
||||
|
||||
LOG_D(MAC,"Aggregation level %d (cqi %d, bw_index %d, format %d)\n",
|
||||
1<<aggregation, cqi,bw_index,dci_fmt);
|
||||
|
||||
return aggregation;
|
||||
}
|
||||
#ifdef CBA
|
||||
@@ -714,6 +744,38 @@ uint32_t allocate_prbs(int UE_id,unsigned char nb_rb, uint32_t *rballoc)
|
||||
return(rballoc_dci);
|
||||
}
|
||||
|
||||
int get_bw_index(module_id_t module_id, uint8_t CC_id)
|
||||
{
|
||||
|
||||
int bw_index=0;
|
||||
LTE_DL_FRAME_PARMS* frame_parms = mac_xface->get_lte_frame_parms(module_id,CC_id);
|
||||
|
||||
switch (frame_parms->N_RB_DL) {
|
||||
case 6: // 1.4 MHz
|
||||
bw_index=0;
|
||||
break;
|
||||
|
||||
case 25: // 5HMz
|
||||
bw_index=1;
|
||||
break;
|
||||
|
||||
case 50: // 10HMz
|
||||
bw_index=2;
|
||||
break;
|
||||
|
||||
case 100: // 20HMz
|
||||
bw_index=3;
|
||||
break;
|
||||
|
||||
default:
|
||||
bw_index=1;
|
||||
LOG_W(MAC,"[eNB %d] N_DL_RB %d unknown for CC_id %d, setting bw_index to 1\n", module_id, frame_parms->N_RB_DL, CC_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return bw_index;
|
||||
}
|
||||
|
||||
int get_min_rb_unit(module_id_t module_id, uint8_t CC_id)
|
||||
{
|
||||
|
||||
@@ -1044,8 +1106,7 @@ try_again:
|
||||
1<<DCI_pdu->dci_alloc[j].L,
|
||||
nCCE,nCCE_max,DCI_pdu->num_pdcch_symbols);
|
||||
}
|
||||
//dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,dci_alloc->L);
|
||||
|
||||
//dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
|
||||
goto failed;
|
||||
}
|
||||
DCI_pdu->num_pdcch_symbols++;
|
||||
|
||||
@@ -729,8 +729,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
|
||||
ulsch_scheduler_pre_processor(module_idP,
|
||||
frameP,
|
||||
subframeP,
|
||||
first_rb,
|
||||
aggregation);
|
||||
first_rb);
|
||||
|
||||
// LOG_I(MAC,"exiting ulsch preprocesor\n");
|
||||
|
||||
@@ -791,14 +790,19 @@ abort();
|
||||
frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
|
||||
|
||||
aggregation=get_aggregation(get_bw_index(module_idP,CC_id),
|
||||
eNB_UE_stats->DL_cqi[0],
|
||||
format0);
|
||||
|
||||
if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
|
||||
LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
|
||||
continue; // break;
|
||||
} else{
|
||||
LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d mode %s: aggregation level %d\n",
|
||||
module_idP,frameP,subframeP,UE_id,rnti,CC_id, mode_string[eNB_UE_stats->mode], 1<<aggregation);
|
||||
}
|
||||
|
||||
|
||||
// printf("UE %d/%x is feasible, mode %s\n",UE_id,rnti,mode_string[eNB_UE_stats->mode]);
|
||||
|
||||
if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
|
||||
|
||||
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
|
||||
@@ -824,7 +828,6 @@ abort();
|
||||
UE_sched_ctrl->ul_failure_timer);
|
||||
// reset the scheduling request
|
||||
UE_template->ul_SR = 0;
|
||||
aggregation = process_ue_cqi(module_idP,UE_id);
|
||||
status = mac_eNB_get_rrc_status(module_idP,rnti);
|
||||
if (status < RRC_CONNECTED)
|
||||
cqi_req = 0;
|
||||
|
||||
@@ -50,6 +50,12 @@ extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
|
||||
//extern uint32_t Extended_BSR_TABLE[63]; ----currently not used
|
||||
|
||||
extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
|
||||
|
||||
extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
|
||||
|
||||
extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
|
||||
|
||||
extern UE_MAC_INST *UE_mac_inst;
|
||||
extern eNB_MAC_INST *eNB_mac_inst;
|
||||
extern eNB_RRC_INST *eNB_rrc_inst;
|
||||
|
||||
@@ -131,19 +131,6 @@ void _assign_rbs_required (module_id_t Mod_id,
|
||||
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES],
|
||||
int min_rb_unit[MAX_NUM_CCs]);
|
||||
|
||||
int _maxround(module_id_t Mod_id,
|
||||
uint16_t rnti,
|
||||
int frame,
|
||||
sub_frame_t subframe,
|
||||
uint8_t ul_flag );
|
||||
|
||||
int _maxcqi(module_id_t Mod_id,
|
||||
int32_t UE_id);
|
||||
|
||||
void _sort_UEs (module_id_t Mod_idP,
|
||||
int frameP,
|
||||
sub_frame_t subframeP);
|
||||
|
||||
void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
int slice_id,
|
||||
frame_t frameP,
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
|
||||
#include "header.pb-c.h"
|
||||
#include "flexran.pb-c.h"
|
||||
#include "flexran_agent_extern.h"
|
||||
|
||||
#include "flexran_agent_common.h"
|
||||
|
||||
#include "SIMULATION/TOOLS/defs.h" // for taus
|
||||
|
||||
@@ -97,10 +100,10 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
unsigned char header_len = 0, header_len_tmp = 0;
|
||||
unsigned char sdu_lcids[11],offset,num_sdus=0;
|
||||
uint16_t nb_rb;
|
||||
uint16_t TBS,j,sdu_lengths[11],rnti,padding=0,post_padding=0;
|
||||
uint16_t TBS, sdu_lengths[11],rnti,padding=0,post_padding=0;
|
||||
unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
|
||||
unsigned char round = 0;
|
||||
unsigned char harq_pid = 0;
|
||||
uint8_t round = 0;
|
||||
uint8_t harq_pid = 0;
|
||||
// LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
uint16_t sdu_length_total = 0;
|
||||
@@ -112,17 +115,16 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
|
||||
int last_sdu_header_len = 0;
|
||||
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
Protocol__FlexDlData *dl_data;
|
||||
Protocol__FlexDlDci *dl_dci;
|
||||
|
||||
uint32_t rlc_size, n_lc, lcid;
|
||||
|
||||
|
||||
// For each UE-related command
|
||||
for (i = 0; i < n_dl_ue_data; i++) {
|
||||
|
||||
|
||||
dl_data = dl_ue_data[i];
|
||||
dl_dci = dl_data->dl_dci;
|
||||
|
||||
@@ -138,6 +140,9 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
round = dl_dci->rv[0];
|
||||
harq_pid = dl_dci->harq_process;
|
||||
|
||||
//LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] Scheduling harq %d\n", frame, subframe, harq_pid);
|
||||
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d]Now scheduling harq_pid %d (round %d)\n", frame, subframe, harq_pid, round);
|
||||
|
||||
// If this is a new transmission
|
||||
if (round == 0) {
|
||||
// First we have to deal with the creation of the PDU based on the message instructions
|
||||
@@ -147,27 +152,22 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
|
||||
if (dl_data->n_ce_bitmap > 0) {
|
||||
//Check if there is TA command and set the length appropriately
|
||||
ta_len = (dl_data->ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 1 : 0;
|
||||
ta_len = (dl_data->ce_bitmap[0] & PROTOCOL__FLEX_CE_TYPE__FLPCET_TA) ? 2 : 0;
|
||||
}
|
||||
|
||||
|
||||
num_sdus = 0;
|
||||
sdu_length_total = 0;
|
||||
|
||||
if (ta_len > 0) {
|
||||
// Reset the measurement
|
||||
ue_sched_ctl->ta_timer = 20;
|
||||
eNB_UE_stats->timing_advance_update = 0;
|
||||
header_len = ta_len;
|
||||
last_sdu_header_len = ta_len;
|
||||
}
|
||||
|
||||
n_lc = dl_data->n_rlc_pdu;
|
||||
// Go through each one of the channel commands and create SDUs
|
||||
for (i = 0; i < n_lc; i++) {
|
||||
lcid = dl_data->rlc_pdu[i]->rlc_pdu_tb[0]->logical_channel_id;
|
||||
rlc_size = dl_data->rlc_pdu[i]->rlc_pdu_tb[0]->size;
|
||||
LOG_D(MAC,"[TEST] [eNB %d] Frame %d, LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
|
||||
mod_id, frame, lcid, CC_id, rlc_size);
|
||||
header_len = 0;
|
||||
last_sdu_header_len = 0;
|
||||
for (j = 0; j < n_lc; j++) {
|
||||
sdu_lengths[j] = 0;
|
||||
lcid = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->logical_channel_id;
|
||||
rlc_size = dl_data->rlc_pdu[j]->rlc_pdu_tb[0]->size;
|
||||
LOG_D(MAC,"[TEST] [eNB %d] [Frame %d] [Subframe %d], LCID %d, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
|
||||
mod_id, frame, subframe, lcid, CC_id, rlc_size);
|
||||
if (rlc_size > 0) {
|
||||
|
||||
rlc_status = mac_rlc_status_ind(mod_id,
|
||||
@@ -181,10 +181,14 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
|
||||
if (rlc_size <= 2) {
|
||||
rlc_size = 3;
|
||||
if (rlc_status.bytes_in_buffer < rlc_size) {
|
||||
rlc_size = rlc_status.bytes_in_buffer;
|
||||
}
|
||||
|
||||
if (rlc_size <= 2) {
|
||||
rlc_size = 3;
|
||||
}
|
||||
|
||||
rlc_status = mac_rlc_status_ind(mod_id,
|
||||
rnti,
|
||||
mod_id,
|
||||
@@ -194,29 +198,27 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
lcid,
|
||||
rlc_size); // transport block set size
|
||||
|
||||
sdu_lengths[i] = 0;
|
||||
|
||||
LOG_D(MAC, "[TEST] RLC can give %d bytes for LCID %d during second call\n", rlc_status.bytes_in_buffer, lcid);
|
||||
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
|
||||
sdu_lengths[i] += mac_rlc_data_req(mod_id,
|
||||
rnti,
|
||||
mod_id,
|
||||
frame,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
(char *)&dlsch_buffer[sdu_length_total]);
|
||||
sdu_lengths[j] = mac_rlc_data_req(mod_id,
|
||||
rnti,
|
||||
mod_id,
|
||||
frame,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
lcid,
|
||||
(char *)&dlsch_buffer[sdu_length_total]);
|
||||
|
||||
LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[i]);
|
||||
sdu_length_total += sdu_lengths[i];
|
||||
sdu_lcids[i] = lcid;
|
||||
LOG_D(MAC,"[eNB %d][LCID %d] CC_id %d Got %d bytes from RLC\n",mod_id, lcid, CC_id, sdu_lengths[j]);
|
||||
sdu_length_total += sdu_lengths[j];
|
||||
sdu_lcids[j] = lcid;
|
||||
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[i];
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[j];
|
||||
|
||||
if (sdu_lengths[i] <= 128) {
|
||||
if (sdu_lengths[j] < 128) {
|
||||
header_len += 2;
|
||||
last_sdu_header_len = 2;
|
||||
} else {
|
||||
@@ -230,38 +232,46 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
} // SDU creation end
|
||||
|
||||
|
||||
if (((sdu_length_total + header_len) > 0)) {
|
||||
|
||||
// header_len_tmp = header_len;
|
||||
if (((sdu_length_total + header_len + ta_len) > 0)) {
|
||||
|
||||
header_len_tmp = header_len;
|
||||
|
||||
// If we have only a single SDU, header length becomes 1
|
||||
if ((num_sdus + ta_len) == 1) {
|
||||
if ((num_sdus) == 1) {
|
||||
//if (header_len == 2 || header_len == 3) {
|
||||
header_len = 1;
|
||||
} else {
|
||||
header_len = (header_len - last_sdu_header_len) + 1;
|
||||
}
|
||||
|
||||
// there is a payload
|
||||
if (((sdu_length_total + header_len) > 0)) {
|
||||
// If we need a 1 or 2 bit padding or no padding at all
|
||||
if ((TBS - header_len - sdu_length_total - ta_len) <= 2
|
||||
|| (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow
|
||||
padding = (TBS - header_len - sdu_length_total - ta_len);
|
||||
post_padding = 0;
|
||||
} else { // The last sdu needs to have a length field, since we add padding
|
||||
padding = 0;
|
||||
header_len = header_len_tmp;
|
||||
post_padding = TBS - sdu_length_total - header_len - ta_len - 1; // 1 is for the postpadding header
|
||||
}
|
||||
// If we need a 1 or 2 bit padding or no padding at all
|
||||
if ((TBS - header_len - sdu_length_total - ta_len) <= 2
|
||||
|| (TBS - header_len - sdu_length_total - ta_len) > TBS) { //protect from overflow
|
||||
padding = (TBS - header_len - sdu_length_total - ta_len);
|
||||
post_padding = 0;
|
||||
} else { // The last sdu needs to have a length field, since we add padding
|
||||
padding = 0;
|
||||
header_len = header_len_tmp;
|
||||
post_padding = TBS - sdu_length_total - header_len - ta_len; // 1 is for the postpadding header
|
||||
}
|
||||
|
||||
if (ta_len > 0) {
|
||||
// Reset the measurement
|
||||
ta_update = flexran_get_TA(mod_id, UE_id, CC_id);
|
||||
ue_sched_ctl->ta_timer = 20;
|
||||
eNB_UE_stats->timing_advance_update = 0;
|
||||
} else {
|
||||
ta_update = 0;
|
||||
}
|
||||
|
||||
ta_update = (ta_len > 0) ? ue_sched_ctl->ta_update : 0;
|
||||
|
||||
// If there is nothing to schedule, just leave
|
||||
if ((sdu_length_total) <= 0) {
|
||||
return;
|
||||
harq_pid_updated[UE_id][harq_pid] = 1;
|
||||
harq_pid_round[UE_id][harq_pid] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// LOG_I(FLEXRAN_AGENT, "[Frame %d][Subframe %d] TBS is %d and bytes are %d\n", frame, subframe, TBS, sdu_length_total);
|
||||
|
||||
offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
|
||||
num_sdus, //num_sdus
|
||||
@@ -272,6 +282,10 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
NULL, // contention res id
|
||||
padding,
|
||||
post_padding);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_eNB_SCHEDULER
|
||||
LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n");
|
||||
@@ -289,7 +303,7 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
// fill remainder of DLSCH with random data
|
||||
for (j=0; j<(TBS-sdu_length_total-offset); j++) {
|
||||
UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff);
|
||||
}
|
||||
}
|
||||
|
||||
//eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff);
|
||||
if (opt_enabled == 1) {
|
||||
@@ -319,6 +333,8 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
nb_rb += get_min_rb_unit(mod_id, CC_id);
|
||||
stats_tbs = mac_xface->get_TBS_DL(dl_dci->mcs[0], nb_rb);
|
||||
}
|
||||
|
||||
// LOG_I(FLEXRAN_AGENT, "The MCS was %d\n", dl_dci->mcs[0]);
|
||||
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
|
||||
UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb;
|
||||
@@ -333,10 +349,14 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
|
||||
//eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]];
|
||||
//eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
|
||||
} else {
|
||||
LOG_D(FLEXRAN_AGENT, "No need to schedule a dci after all. Just drop it\n");
|
||||
harq_pid_updated[UE_id][harq_pid] = 1;
|
||||
harq_pid_round[UE_id][harq_pid] = 0;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// No need to create anything apart of DCI in case of retransmission
|
||||
|
||||
/*TODO: Must add these */
|
||||
// eNB_UE_stats->dlsch_trials[round]++;
|
||||
//UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1;
|
||||
@@ -345,8 +365,8 @@ void flexran_apply_ue_spec_scheduling_decisions(mid_t mod_id,
|
||||
//UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCECC_id];
|
||||
}
|
||||
|
||||
UE_list->UE_template[CC_id][UE_id].oldNDI[dl_dci->harq_process] = dl_dci->ndi[0];
|
||||
eNB_UE_stats->dlsch_mcs1 = dl_dci->mcs[0];
|
||||
// UE_list->UE_template[CC_id][UE_id].oldNDI[dl_dci->harq_process] = dl_dci->ndi[0];
|
||||
// eNB_UE_stats->dlsch_mcs1 = dl_dci->mcs[0];
|
||||
|
||||
//Fill the proper DCI of OAI
|
||||
flexran_fill_oai_dci(mod_id, CC_id, rnti, dl_dci);
|
||||
|
||||
@@ -104,8 +104,8 @@ float total_slice_percentage = 0;
|
||||
int slice_maxmcs[MAX_NUM_SLICES] = {28, 28, 28, 28};
|
||||
int slice_maxmcs_current[MAX_NUM_SLICES] = {28, 28, 28, 28};
|
||||
|
||||
int update_dl_scheduler[MAX_NUM_SLICES] = {1, 0, 0, 0};
|
||||
int update_dl_scheduler_current[MAX_NUM_SLICES] = {1, 0, 0, 0};
|
||||
int update_dl_scheduler[MAX_NUM_SLICES] = {1, 1, 1, 1};
|
||||
int update_dl_scheduler_current[MAX_NUM_SLICES] = {1, 1, 1, 1};
|
||||
|
||||
// name of available scheduler
|
||||
char *dl_scheduler_type[MAX_NUM_SLICES] = {"flexran_schedule_ue_spec_embb",
|
||||
@@ -137,8 +137,9 @@ void _store_dlsch_buffer (module_id_t Mod_id,
|
||||
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
|
||||
UE_TEMPLATE *UE_template;
|
||||
|
||||
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
||||
|
||||
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
|
||||
if (UE_list->active[UE_id] != TRUE) continue;
|
||||
|
||||
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||
continue;
|
||||
|
||||
@@ -221,7 +222,8 @@ void _assign_rbs_required (module_id_t Mod_id,
|
||||
// UE_TEMPLATE *UE_template;
|
||||
|
||||
// clear rb allocations across all CC_ids
|
||||
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
||||
for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
|
||||
if (UE_list->active[UE_id] != TRUE) continue;
|
||||
|
||||
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||
continue;
|
||||
@@ -229,11 +231,15 @@ void _assign_rbs_required (module_id_t Mod_id,
|
||||
pCCid = UE_PCCID(Mod_id,UE_id);
|
||||
rnti = UE_list->UE_template[pCCid][UE_id].rnti;
|
||||
|
||||
/* skip UE not present in PHY (for any of its active CCs) */
|
||||
if (!phy_stats_exist(Mod_id, rnti))
|
||||
continue;
|
||||
|
||||
//update CQI information across component carriers
|
||||
for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
|
||||
CC_id = UE_list->ordered_CCids[n][UE_id];
|
||||
eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
|
||||
eNB_UE_stats[CC_id]->dlsch_mcs1=cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)];
|
||||
eNB_UE_stats[CC_id]->dlsch_mcs1 = cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)];
|
||||
}
|
||||
|
||||
// provide the list of CCs sorted according to MCS
|
||||
@@ -260,143 +266,34 @@ void _assign_rbs_required (module_id_t Mod_id,
|
||||
CC_id = UE_list->ordered_CCids[i][UE_id];
|
||||
eNB_UE_stats[CC_id] = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,rnti);
|
||||
|
||||
if (eNB_UE_stats[CC_id]->dlsch_mcs1==0) {
|
||||
if (cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)] == 0) {//eNB_UE_stats[CC_id]->dlsch_mcs1==0) {
|
||||
nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small
|
||||
} else {
|
||||
nb_rbs_required[CC_id][UE_id] = min_rb_unit[CC_id];
|
||||
}
|
||||
|
||||
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
|
||||
TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_required[CC_id][UE_id]);
|
||||
nb_rbs_allowed_slice[CC_id][slice_id] = flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],
|
||||
flexran_get_N_RB_DL(Mod_id, CC_id));
|
||||
LOG_D(MAC,"[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
|
||||
UE_id, CC_id, UE_list->UE_template[pCCid][UE_id].dl_buffer_total,
|
||||
nb_rbs_required[CC_id][UE_id],eNB_UE_stats[CC_id]->dlsch_mcs1,TBS);
|
||||
nb_rbs_required[CC_id][UE_id], flexran_get_ue_wcqi(Mod_id, UE_id), TBS);
|
||||
|
||||
/* calculating required number of RBs for each UE */
|
||||
while (TBS < UE_list->UE_template[pCCid][UE_id].dl_buffer_total) {
|
||||
nb_rbs_required[CC_id][UE_id] += min_rb_unit[CC_id];
|
||||
|
||||
if (nb_rbs_required[CC_id][UE_id] > nb_rbs_allowed_slice[CC_id][slice_id]) {
|
||||
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1, nb_rbs_allowed_slice[CC_id][slice_id]);
|
||||
TBS = mac_xface->get_TBS_DL(flexran_get_ue_wcqi(Mod_id, UE_id), nb_rbs_allowed_slice[CC_id][slice_id]);
|
||||
nb_rbs_required[CC_id][UE_id] = nb_rbs_allowed_slice[CC_id][slice_id];
|
||||
break;
|
||||
}
|
||||
|
||||
TBS = mac_xface->get_TBS_DL(eNB_UE_stats[CC_id]->dlsch_mcs1,nb_rbs_required[CC_id][UE_id]);
|
||||
TBS = mac_xface->get_TBS_DL(cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)], nb_rbs_required[CC_id][UE_id]);
|
||||
} // end of while
|
||||
|
||||
LOG_D(MAC,"[eNB %d][SLICE %d] Frame %d: UE %d on CC %d: RB unit %d, nb_required RB %d (TBS %d, mcs %d)\n",
|
||||
Mod_id, slice_id,frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, eNB_UE_stats[CC_id]->dlsch_mcs1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function scans all CC_ids for a particular UE to find the maximum round index of its HARQ processes
|
||||
int _maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uint8_t ul_flag )
|
||||
{
|
||||
|
||||
uint8_t round,round_max=0,UE_id;
|
||||
int CC_id;
|
||||
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
|
||||
|
||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
|
||||
UE_id = find_UE_id(Mod_id,rnti);
|
||||
round = UE_list->UE_sched_ctrl[UE_id].round[CC_id];
|
||||
if (round > round_max) {
|
||||
round_max = round;
|
||||
}
|
||||
}
|
||||
|
||||
return round_max;
|
||||
}
|
||||
|
||||
// This function scans all CC_ids for a particular UE to find the maximum DL CQI
|
||||
int _maxcqi(module_id_t Mod_id,int32_t UE_id)
|
||||
{
|
||||
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
UE_list_t *UE_list = &eNB_mac_inst[Mod_id].UE_list;
|
||||
int CC_id,n;
|
||||
int CQI = 0;
|
||||
|
||||
for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
|
||||
CC_id = UE_list->ordered_CCids[n][UE_id];
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(Mod_id,CC_id,UE_RNTI(Mod_id,UE_id));
|
||||
|
||||
if (eNB_UE_stats==NULL) {
|
||||
mac_xface->macphy_exit("maxcqi: could not get eNB_UE_stats\n");
|
||||
return 0; // not reached
|
||||
}
|
||||
|
||||
if (eNB_UE_stats->DL_cqi[0] > CQI) {
|
||||
CQI = eNB_UE_stats->DL_cqi[0];
|
||||
}
|
||||
}
|
||||
|
||||
return(CQI);
|
||||
}
|
||||
|
||||
|
||||
// This fuction sorts the UE in order their dlsch buffer and CQI
|
||||
void _sort_UEs (module_id_t Mod_idP,
|
||||
int frameP,
|
||||
sub_frame_t subframeP)
|
||||
{
|
||||
|
||||
|
||||
int UE_id1,UE_id2;
|
||||
int pCC_id1,pCC_id2;
|
||||
int cqi1,cqi2,round1,round2;
|
||||
int i=0,ii=0;//,j=0;
|
||||
rnti_t rnti1,rnti2;
|
||||
|
||||
UE_list_t *UE_list = &eNB_mac_inst[Mod_idP].UE_list;
|
||||
|
||||
for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||
|
||||
for(ii=UE_list->next[i]; ii>=0; ii=UE_list->next[ii]) {
|
||||
|
||||
UE_id1 = i;
|
||||
rnti1 = UE_RNTI(Mod_idP,UE_id1);
|
||||
if(rnti1 == NOT_A_RNTI)
|
||||
continue;
|
||||
if (UE_list->UE_sched_ctrl[UE_id1].ul_out_of_sync == 1)
|
||||
continue;
|
||||
pCC_id1 = UE_PCCID(Mod_idP,UE_id1);
|
||||
cqi1 = _maxcqi(Mod_idP,UE_id1); //
|
||||
round1 = _maxround(Mod_idP,rnti1,frameP,subframeP,0);
|
||||
|
||||
UE_id2 = ii;
|
||||
rnti2 = UE_RNTI(Mod_idP,UE_id2);
|
||||
if(rnti2 == NOT_A_RNTI)
|
||||
continue;
|
||||
if (UE_list->UE_sched_ctrl[UE_id2].ul_out_of_sync == 1)
|
||||
continue;
|
||||
cqi2 = _maxcqi(Mod_idP,UE_id2);
|
||||
round2 = _maxround(Mod_idP,rnti2,frameP,subframeP,0); //mac_xface->get_ue_active_harq_pid(Mod_id,rnti2,subframe,&harq_pid2,&round2,0);
|
||||
pCC_id2 = UE_PCCID(Mod_idP,UE_id2);
|
||||
|
||||
if(round2 > round1) { // Check first if one of the UEs has an active HARQ process which needs service and swap order
|
||||
swap_UEs(UE_list,UE_id1,UE_id2,0);
|
||||
} else if (round2 == round1) {
|
||||
// RK->NN : I guess this is for fairness in the scheduling. This doesn't make sense unless all UEs have the same configuration of logical channels. This should be done on the sum of all information that has to be sent. And still it wouldn't ensure fairness. It should be based on throughput seen by each UE or maybe using the head_sdu_creation_time, i.e. swap UEs if one is waiting longer for service.
|
||||
|
||||
// first check the buffer status for SRB1 and SRB2
|
||||
if ( (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[1] + UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_info[2]) <
|
||||
(UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[1] + UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_info[2]) ) {
|
||||
swap_UEs(UE_list,UE_id1,UE_id2,0);
|
||||
} else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_head_sdu_creation_time_max <
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_head_sdu_creation_time_max ) {
|
||||
swap_UEs(UE_list,UE_id1,UE_id2,0);
|
||||
} else if (UE_list->UE_template[pCC_id1][UE_id1].dl_buffer_total <
|
||||
UE_list->UE_template[pCC_id2][UE_id2].dl_buffer_total ) {
|
||||
swap_UEs(UE_list,UE_id1,UE_id2,0);
|
||||
} else if (cqi1 < cqi2) {
|
||||
swap_UEs(UE_list,UE_id1,UE_id2,0);
|
||||
}
|
||||
Mod_id, slice_id,frameP,UE_id, CC_id, min_rb_unit[CC_id], nb_rbs_required[CC_id][UE_id], TBS, cqi_to_mcs[flexran_get_ue_wcqi(Mod_id, UE_id)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -543,10 +440,11 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
int *mbsfn_flag)
|
||||
{
|
||||
|
||||
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid=0, total_ue_count;
|
||||
unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], total_ue_count;
|
||||
unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
|
||||
int UE_id, i;
|
||||
unsigned char round = 0;
|
||||
uint8_t round = 0;
|
||||
uint8_t harq_pid = 0;
|
||||
uint16_t ii,j;
|
||||
uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
|
||||
uint16_t nb_rbs_allowed_slice[MAX_NUM_CCs][MAX_NUM_SLICES];
|
||||
@@ -574,7 +472,9 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
|
||||
min_rb_unit[CC_id]=get_min_rb_unit(Mod_id,CC_id);
|
||||
|
||||
for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||
if (UE_list->active[i] != TRUE) continue;
|
||||
|
||||
UE_id = i;
|
||||
// Initialize scheduling information for all active UEs
|
||||
|
||||
@@ -602,24 +502,24 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
_assign_rbs_required (Mod_id,slice_id, frameP,subframeP,nb_rbs_required,nb_rbs_allowed_slice,min_rb_unit);
|
||||
|
||||
// Sorts the user on the basis of dlsch logical channel buffer and CQI
|
||||
_sort_UEs (Mod_id,frameP,subframeP);
|
||||
sort_UEs (Mod_id,frameP,subframeP);
|
||||
|
||||
total_ue_count = 0;
|
||||
|
||||
// loop over all active UEs
|
||||
for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||
for (i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||
rnti = flexran_get_ue_crnti(Mod_id, i);
|
||||
if(rnti == NOT_A_RNTI)
|
||||
continue;
|
||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
||||
continue;
|
||||
|
||||
UE_id = i;
|
||||
|
||||
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||
continue;
|
||||
|
||||
// if there is no available harq_process, skip the UE
|
||||
if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
|
||||
if (!phy_stats_exist(Mod_id, rnti))
|
||||
continue;
|
||||
|
||||
for (ii=0; ii < UE_num_active_CC(UE_list,UE_id); ii++) {
|
||||
@@ -628,6 +528,10 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
ue_sched_ctl->max_allowed_rbs[CC_id]=nb_rbs_allowed_slice[CC_id][slice_id];
|
||||
flexran_get_harq(Mod_id, CC_id, UE_id, frameP, subframeP, &harq_pid, &round);
|
||||
|
||||
// if there is no available harq_process, skip the UE
|
||||
if (UE_list->UE_sched_ctrl[UE_id].harq_pid[CC_id]<0)
|
||||
continue;
|
||||
|
||||
average_rbs_per_user[CC_id]=0;
|
||||
|
||||
frame_parms[CC_id] = mac_xface->get_lte_frame_parms(Mod_id,CC_id);
|
||||
@@ -669,6 +573,15 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
for(i=UE_list->head; i>=0; i=UE_list->next[i]) {
|
||||
rnti = UE_RNTI(Mod_id,i);
|
||||
|
||||
if(rnti == NOT_A_RNTI)
|
||||
continue;
|
||||
|
||||
if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
|
||||
continue;
|
||||
|
||||
if (!phy_stats_exist(Mod_id, rnti))
|
||||
continue;
|
||||
|
||||
if (flexran_slice_member(i, slice_id) == 0)
|
||||
continue;
|
||||
|
||||
@@ -733,9 +646,13 @@ void _dlsch_scheduler_pre_processor (module_id_t Mod_id,
|
||||
// LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
|
||||
if(rnti == NOT_A_RNTI)
|
||||
continue;
|
||||
|
||||
if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
|
||||
continue;
|
||||
|
||||
if (!phy_stats_exist(Mod_id, rnti))
|
||||
continue;
|
||||
|
||||
transmission_mode = mac_xface->get_transmission_mode(Mod_id,CC_id,rnti);
|
||||
//rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti);
|
||||
/* 1st allocate for the retx */
|
||||
@@ -1027,11 +944,11 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
int N_RBG[MAX_NUM_CCs];
|
||||
unsigned char aggregation;
|
||||
mac_rlc_status_resp_t rlc_status;
|
||||
unsigned char header_len = 0, ta_len = 0;
|
||||
unsigned char header_len = 0, header_len_last = 0, ta_len = 0;
|
||||
uint16_t nb_rb, nb_rb_temp, total_nb_available_rb[MAX_NUM_CCs], nb_available_rb;
|
||||
uint16_t TBS, j, rnti;
|
||||
unsigned char round = 0;
|
||||
unsigned char harq_pid = 0;
|
||||
uint8_t round = 0;
|
||||
uint8_t harq_pid = 0;
|
||||
uint16_t sdu_length_total = 0;
|
||||
int mcs, mcs_tmp;
|
||||
uint16_t min_rb_unit[MAX_NUM_CCs];
|
||||
@@ -1042,7 +959,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
int32_t tpc = 1;
|
||||
static int32_t tpc_accumulated=0;
|
||||
UE_sched_ctrl *ue_sched_ctl;
|
||||
|
||||
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
|
||||
Protocol__FlexDlData *dl_data[NUM_MAX_UE];
|
||||
int num_ues_added = 0;
|
||||
int channels_added = 0;
|
||||
@@ -1058,17 +975,19 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
uint8_t ue_has_transmission = 0;
|
||||
uint32_t ndi;
|
||||
|
||||
flexran_agent_mac_create_empty_dl_config(mod_id, dl_info);
|
||||
#if 0
|
||||
|
||||
if (UE_list->head==-1) {
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
start_meas(&eNB->schedule_dlsch);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
|
||||
|
||||
//weight = get_ue_weight(module_idP,UE_id);
|
||||
aggregation = 2; // set to the maximum aggregation level
|
||||
aggregation = 1; // set to the maximum aggregation level
|
||||
|
||||
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
|
||||
min_rb_unit[CC_id] = get_min_rb_unit(mod_id, CC_id);
|
||||
@@ -1105,11 +1024,19 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
|
||||
if (mbsfn_flag[CC_id]>0)
|
||||
continue;
|
||||
|
||||
|
||||
for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
|
||||
|
||||
rnti = flexran_get_ue_crnti(mod_id, UE_id);
|
||||
eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti);
|
||||
ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
|
||||
|
||||
|
||||
if (eNB_UE_stats==NULL) {
|
||||
LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n");
|
||||
// mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flexran_slice_member(UE_id, slice_id) == 0)
|
||||
continue;
|
||||
|
||||
@@ -1119,12 +1046,24 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flexran_get_ue_crnti(mod_id, UE_id) == NOT_A_RNTI) {
|
||||
LOG_D(MAC,"[eNB] Cannot find UE\n");
|
||||
// mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
|
||||
continue;
|
||||
switch(mac_xface->get_transmission_mode(mod_id,CC_id,rnti)){
|
||||
case 1:
|
||||
case 2:
|
||||
case 7:
|
||||
aggregation = get_aggregation(get_bw_index(mod_id,CC_id),
|
||||
eNB_UE_stats->DL_cqi[0],
|
||||
format1);
|
||||
break;
|
||||
case 3:
|
||||
aggregation = get_aggregation(get_bw_index(mod_id,CC_id),
|
||||
eNB_UE_stats->DL_cqi[0],
|
||||
format2A);
|
||||
break;
|
||||
default:
|
||||
LOG_W(MAC,"Unsupported transmission mode %d\n", mac_xface->get_transmission_mode(mod_id,CC_id,rnti));
|
||||
aggregation = 2;
|
||||
}
|
||||
|
||||
|
||||
if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated
|
||||
CCE_allocation_infeasible(mod_id, CC_id, 0, subframe, aggregation, rnti)) {
|
||||
LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
|
||||
@@ -1160,6 +1099,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
flexran_get_harq(mod_id, CC_id, UE_id, frame, subframe, &harq_pid, &round);
|
||||
sdu_length_total=0;
|
||||
mcs = cqi_to_mcs[flexran_get_ue_wcqi(mod_id, UE_id)];
|
||||
// LOG_I(FLEXRAN_AGENT, "The MCS is %d\n", mcs);
|
||||
mcs = cmin(mcs,flexran_slice_maxmcs(slice_id));
|
||||
#ifdef EXMIMO
|
||||
|
||||
@@ -1192,9 +1132,10 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
dl_dci->harq_process = harq_pid;
|
||||
|
||||
/* process retransmission */
|
||||
|
||||
if (round > 0) {
|
||||
|
||||
LOG_D(FLEXRAN_AGENT, "There was a retransmission just now and the round was %d\n", round);
|
||||
|
||||
if (flexran_get_duplex_mode(mod_id, CC_id) == PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD) {
|
||||
UE_list->UE_template[CC_id][UE_id].DAI++;
|
||||
update_ul_dci(mod_id, CC_id, rnti, UE_list->UE_template[CC_id][UE_id].DAI);
|
||||
@@ -1237,8 +1178,6 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
}
|
||||
|
||||
nb_available_rb -= nb_rb;
|
||||
aggregation = process_ue_cqi(mod_id, UE_id);
|
||||
|
||||
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
|
||||
PHY_vars_eNB_g[mod_id][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
|
||||
|
||||
@@ -1267,15 +1206,16 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
//TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb);
|
||||
TBS = mac_xface->get_TBS_DL(mcs, nb_available_rb);
|
||||
dci_tbs = TBS;
|
||||
|
||||
LOG_D(FLEXRAN_AGENT, "TBS is %d\n", TBS);
|
||||
|
||||
// check first for RLC data on DCCH
|
||||
// add the length for all the control elements (timing adv, drx, etc) : header + payload
|
||||
|
||||
ta_len = (ue_sched_ctl->ta_update!=0) ? 2 : 0;
|
||||
ta_len = (ue_sched_ctl->ta_update != 0) ? 2 : 0;
|
||||
|
||||
dl_data[num_ues_added]->n_ce_bitmap = 2;
|
||||
dl_data[num_ues_added]->ce_bitmap = (uint32_t *) malloc(sizeof(uint32_t) * 2);
|
||||
|
||||
dl_data[num_ues_added]->ce_bitmap = (uint32_t *) calloc(2, sizeof(uint32_t));
|
||||
|
||||
if (ta_len > 0) {
|
||||
ce_flags |= PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
|
||||
}
|
||||
@@ -1288,9 +1228,11 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
|
||||
// TODO : Need to prioritize DRBs
|
||||
// Loop through the UE logical channels (DCCH, DCCH1, DTCH for now)
|
||||
header_len = 0;
|
||||
header_len_last = 0;
|
||||
sdu_length_total = 0;
|
||||
for (j = 1; j < NB_RB_MAX; j++) {
|
||||
header_len+=3;
|
||||
|
||||
header_len += 3;
|
||||
// Need to see if we have space for data from this channel
|
||||
if (dci_tbs - ta_len - header_len - sdu_length_total > 0) {
|
||||
LOG_D(MAC, "[TEST]Requested %d bytes from RLC buffer on channel %d during first call\n", dci_tbs-ta_len-header_len);
|
||||
@@ -1302,15 +1244,19 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
ENB_FLAG_YES,
|
||||
MBMS_FLAG_NO,
|
||||
j,
|
||||
(dci_tbs-ta_len-header_len)); // transport block set size
|
||||
(dci_tbs - ta_len - header_len - sdu_length_total)); // transport block set size
|
||||
|
||||
//If data are available in channel j
|
||||
if (rlc_status.bytes_in_buffer > 0) {
|
||||
LOG_D(MAC, "[TEST]Have %d bytes in DCCH buffer during first call\n", rlc_status.bytes_in_buffer);
|
||||
//Fill in as much as possible
|
||||
data_to_request = cmin(dci_tbs-ta_len-header_len, rlc_status.bytes_in_buffer);
|
||||
data_to_request = cmin(dci_tbs - ta_len - header_len - sdu_length_total, rlc_status.bytes_in_buffer);
|
||||
LOG_D(FLEXRAN_AGENT, "Will request %d bytes from channel %d\n", data_to_request, j);
|
||||
if (data_to_request < 128) { //The header will be one byte less
|
||||
header_len--;
|
||||
header_len_last = 2;
|
||||
} else {
|
||||
header_len_last = 3;
|
||||
}
|
||||
/* if (j == 1 || j == 2) {
|
||||
data_to_request+=0;
|
||||
@@ -1350,17 +1296,29 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
dl_data[num_ues_added]->rlc_pdu[i] = rlc_pdus[i];
|
||||
}
|
||||
|
||||
if (header_len == 0) {
|
||||
LOG_D(FLEXRAN_AGENT, "Header was empty\n");
|
||||
header_len_last = 0;
|
||||
}
|
||||
|
||||
// there is a payload
|
||||
if (( dl_data[num_ues_added]->n_rlc_pdu > 0)) {
|
||||
if ((dl_data[num_ues_added]->n_rlc_pdu > 0)) {
|
||||
// Now compute number of required RBs for total sdu length
|
||||
// Assume RAH format 2
|
||||
// adjust header lengths
|
||||
|
||||
if (header_len == 2 || header_len == 3) { //Only one SDU, remove length field
|
||||
header_len = 1;
|
||||
} else { //Remove length field from the last SDU
|
||||
header_len--;
|
||||
LOG_D(FLEXRAN_AGENT, "We have %d bytes to transfer\n", sdu_length_total);
|
||||
if (header_len != 0) {
|
||||
LOG_D(FLEXRAN_AGENT, "Header length was %d ", header_len);
|
||||
header_len_last--;
|
||||
header_len -= header_len_last;
|
||||
LOG_D(FLEXRAN_AGENT, "so we resized it to %d\n", header_len);
|
||||
}
|
||||
|
||||
/* if (header_len == 2 || header_len == 3) { //Only one SDU, remove length field */
|
||||
/* header_len = 1; */
|
||||
/* } else { //Remove length field from the last SDU */
|
||||
/* header_len--; */
|
||||
/* } */
|
||||
|
||||
mcs_tmp = mcs;
|
||||
if (mcs_tmp == 0) {
|
||||
@@ -1434,8 +1392,8 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
|
||||
dci_tbs = TBS;
|
||||
mcs = mcs_tmp;
|
||||
|
||||
aggregation = process_ue_cqi(mod_id,UE_id);
|
||||
LOG_D(FLEXRAN_AGENT, "Final mcs was %d\n", mcs);
|
||||
|
||||
dl_dci->has_aggr_level = 1;
|
||||
dl_dci->aggr_level = aggregation;
|
||||
|
||||
@@ -1451,8 +1409,7 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
// do PUCCH power control
|
||||
// this is the normalized RX power
|
||||
normalized_rx_power = flexran_get_p0_pucch_dbm(mod_id,UE_id, CC_id); //eNB_UE_stats->Po_PUCCH_dBm;
|
||||
target_rx_power = flexran_get_p0_nominal_pucch(mod_id, CC_id) + 10; //mac_xface->get_target_pucch_rx_power(mod_id, CC_id) + 10;
|
||||
|
||||
target_rx_power = flexran_get_p0_nominal_pucch(mod_id, CC_id) + 20; //mac_xface->get_target_pucch_rx_power(mod_id, CC_id) + 20;
|
||||
// this assumes accumulated tpc
|
||||
// make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
|
||||
int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
|
||||
@@ -1460,8 +1417,8 @@ flexran_schedule_ue_spec_common(mid_t mod_id,
|
||||
if (((framex10psubframe+10)<=(frame*10+subframe)) || //normal case
|
||||
((framex10psubframe>(frame*10+subframe)) && (((10240-framex10psubframe+frame*10+subframe)>=10)))) //frame wrap-around
|
||||
if (flexran_get_p0_pucch_status(mod_id, UE_id, CC_id) == 1) {
|
||||
flexran_update_p0_pucch(mod_id, UE_id, CC_id);
|
||||
|
||||
flexran_update_p0_pucch(mod_id, UE_id, CC_id);
|
||||
|
||||
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frame;
|
||||
UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframe;
|
||||
if (normalized_rx_power>(target_rx_power+1)) {
|
||||
|
||||
@@ -62,24 +62,27 @@
|
||||
#endif //PHY_EMUL
|
||||
|
||||
#include "SCHED/defs.h"
|
||||
|
||||
/* TODO: this abstraction_flag here is very hackish - find a proper solution */
|
||||
extern uint8_t abstraction_flag;
|
||||
void dl_phy_sync_success(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
unsigned char eNB_index,
|
||||
uint8_t first_sync) //init as MR
|
||||
{
|
||||
LOG_D(MAC,"[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", module_idP, frameP, eNB_index);
|
||||
#if ! defined(ENABLE_USE_MME)
|
||||
#if defined(ENABLE_USE_MME)
|
||||
int mme_enabled=1;
|
||||
#else
|
||||
int mme_enabled=0;
|
||||
#endif
|
||||
|
||||
if (first_sync==1) {
|
||||
if (first_sync==1 && !(mme_enabled==1 && abstraction_flag==0)) {
|
||||
layer2_init_UE(module_idP);
|
||||
openair_rrc_ue_init(module_idP,eNB_index);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
rrc_in_sync_ind(module_idP,frameP,eNB_index);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mrbch_phy_sync_failure(module_id_t module_idP, frame_t frameP, uint8_t free_eNB_index) //init as CH
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/* this function checks that get_eNB_UE_stats returns
|
||||
* a non-NULL pointer for all CCs for a given UE
|
||||
*/
|
||||
static int phy_stats_exist(module_id_t Mod_id, int rnti)
|
||||
int phy_stats_exist(module_id_t Mod_id, int rnti)
|
||||
{
|
||||
int CC_id;
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++)
|
||||
@@ -1081,8 +1081,7 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t Mod_id,
|
||||
void ulsch_scheduler_pre_processor(module_id_t module_idP,
|
||||
int frameP,
|
||||
sub_frame_t subframeP,
|
||||
uint16_t *first_rb,
|
||||
uint8_t aggregation)
|
||||
uint16_t *first_rb)
|
||||
{
|
||||
|
||||
int16_t i;
|
||||
|
||||
@@ -320,7 +320,7 @@ rnti_t UE_RNTI (module_id_t module_idP, int UE_id);
|
||||
int UE_PCCID (module_id_t module_idP, int UE_id);
|
||||
uint8_t find_active_UEs (module_id_t module_idP);
|
||||
boolean_t is_UE_active (module_id_t module_idP, int UE_id);
|
||||
uint8_t process_ue_cqi (module_id_t module_idP, int UE_id);
|
||||
uint8_t get_aggregation (uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt);
|
||||
|
||||
int8_t find_active_UEs_with_traffic(module_id_t module_idP);
|
||||
|
||||
@@ -531,11 +531,12 @@ int UE_PCCID(module_id_t mod_idP,int ue_idP);
|
||||
rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
|
||||
|
||||
|
||||
void ulsch_scheduler_pre_processor(module_id_t module_idP, int frameP, sub_frame_t subframeP, uint16_t *first_rb, uint8_t aggregattion);
|
||||
void ulsch_scheduler_pre_processor(module_id_t module_idP, int frameP, sub_frame_t subframeP, uint16_t *first_rb);
|
||||
void store_ulsch_buffer(module_id_t module_idP, int frameP, sub_frame_t subframeP);
|
||||
void sort_ue_ul (module_id_t module_idP,int frameP, sub_frame_t subframeP);
|
||||
void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subframeP,uint16_t *first_rb);
|
||||
void adjust_bsr_info(int buffer_occupancy, uint16_t TBS, UE_TEMPLATE *UE_template);
|
||||
int phy_stats_exist(module_id_t Mod_id, int rnti);
|
||||
|
||||
/*! \fn UE_L2_state_t ue_scheduler(const module_id_t module_idP,const frame_t frameP, const sub_frame_t subframe, const lte_subframe_t direction,const uint8_t eNB_index)
|
||||
\brief UE scheduler where all the ue background tasks are done. This function performs the following: 1) Trigger PDCP every 5ms 2) Call RRC for link status return to PHY3) Perform SR/BSR procedures for scheduling feedback 4) Perform PHR procedures.
|
||||
@@ -696,6 +697,8 @@ uint32_t allocate_prbs_sub(int nb_rb, uint8_t *rballoc);
|
||||
|
||||
void update_ul_dci(module_id_t module_idP,uint8_t CC_id,rnti_t rnti,uint8_t dai);
|
||||
|
||||
int get_bw_index(module_id_t module_id, uint8_t CC_id);
|
||||
|
||||
int get_min_rb_unit(module_id_t module_idP, uint8_t CC_id);
|
||||
|
||||
/* \brief Generate header for DL-SCH. This function parses the desired control elements and sdus and generates the header as described
|
||||
|
||||
@@ -97,7 +97,7 @@ unsigned short fill_rar(
|
||||
eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
|
||||
rar[0] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset>>(2+4)); // 7 MSBs of timing advance + divide by 4
|
||||
rar[1] = (uint8_t)(eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[ra_idx].timing_offset<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4
|
||||
rballoc = mac_xface->computeRIV(N_RB_UL,1,1); // first PRB only for UL Grant
|
||||
rballoc = mac_xface->computeRIV(N_RB_UL,26,1); // first PRB only for UL Grant
|
||||
rar[1] |= (rballoc>>7)&7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
|
||||
rar[2] = ((uint8_t)(rballoc&0xff))<<1; // 7 LSBs of rballoc
|
||||
mcs = 10;
|
||||
|
||||
@@ -55,6 +55,36 @@ const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,5
|
||||
1067031,1312097,1613447,1984009,2439678,3000000,
|
||||
6000000};
|
||||
|
||||
//#define MAX_SIZE_OF_AGG3 576
|
||||
//#define MAX_SIZE_OF_AGG2 288
|
||||
//#define MAX_SIZE_OF_AGG1 144
|
||||
//#define MAX_SIZE_OF_AGG0 72
|
||||
|
||||
/*
|
||||
* If the CQI is low, then scheduler will use a higher aggregation level and lower aggregation level otherwise
|
||||
* this is also dependent to transmission mode, where an offset could be defined
|
||||
*/
|
||||
// the follwoing three tables are calibrated for TXMODE 1 and 2
|
||||
const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
|
||||
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 37 bits
|
||||
//{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
|
||||
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
|
||||
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 43
|
||||
{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE = 44
|
||||
};
|
||||
const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
|
||||
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size < 38 bits
|
||||
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE < 43
|
||||
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE < 47
|
||||
{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE < 55
|
||||
};
|
||||
const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
|
||||
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 47 bits
|
||||
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 55
|
||||
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 59
|
||||
{3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0} // 20_DCI0_CRC_SIZE = 64
|
||||
};
|
||||
|
||||
//uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
|
||||
|
||||
MAC_xface *mac_xface;
|
||||
|
||||
@@ -816,6 +816,14 @@ pdcp_data_ind(
|
||||
((pdcp_data_ind_header_t *) new_sdu_p->data)->rb_id = rb_id;
|
||||
#if defined(OAI_EMU)
|
||||
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + oai_emulation.info.nb_enb_local - oai_emulation.info.first_ue_local;
|
||||
#else
|
||||
# if defined(ENABLE_USE_MME)
|
||||
/* for the UE compiled in S1 mode, we need 1 here
|
||||
* for the UE compiled in noS1 mode, we need 0
|
||||
* TODO: be sure of this
|
||||
*/
|
||||
((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1;
|
||||
# endif
|
||||
#endif
|
||||
} else {
|
||||
((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB);
|
||||
|
||||
@@ -167,7 +167,8 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP)
|
||||
((pdcp_data_ind_header_t *) sdu_p->data)->data_size);
|
||||
#else
|
||||
#if ! defined(OAI_EMU)
|
||||
((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
|
||||
/* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
|
||||
// ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -571,7 +572,8 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP)
|
||||
pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local :
|
||||
pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/
|
||||
#else // OAI_EMU
|
||||
pdcp_read_header_g.inst = 0;
|
||||
/* TODO: do we have to reset to 0 or not? not for a scenario with 1 UE at least */
|
||||
// pdcp_read_header_g.inst = 0;
|
||||
//#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id"
|
||||
ctxt.frame = ctxt_cpy.frame;
|
||||
ctxt.enb_flag = ctxt_cpy.enb_flag;
|
||||
|
||||
@@ -345,7 +345,7 @@ void ue_ip_common_wireless2ip(struct nlmsghdr *nlh_pP)
|
||||
|
||||
ue_ip_common_class_wireless2ip(pdcph_p->data_size,
|
||||
(unsigned char *)NLMSG_DATA(nlh_pP) + UE_IP_PDCPH_SIZE,
|
||||
1, //pdcph_p->inst,
|
||||
pdcph_p->inst,
|
||||
pdcph_p->rb_id);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "openairinterface5g_limits.h"
|
||||
#ifndef _UE_IP_CST
|
||||
#define _UE_IP_CST
|
||||
|
||||
@@ -51,7 +52,7 @@
|
||||
|
||||
|
||||
|
||||
#define UE_IP_NB_INSTANCES_MAX 8
|
||||
#define UE_IP_NB_INSTANCES_MAX NUMBER_OF_UE_MAX
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -99,7 +99,7 @@ int errno;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define XER_PRINT
|
||||
//#define XER_PRINT
|
||||
|
||||
extern Enb_properties_array_t enb_properties;
|
||||
typedef struct xer_sprint_string_s {
|
||||
|
||||
@@ -1095,6 +1095,17 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio
|
||||
memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo,
|
||||
(char*)radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo,
|
||||
sizeof(physicalConfigDedicated2->antennaInfo));
|
||||
|
||||
UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode =
|
||||
radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode;
|
||||
UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.codebookSubsetRestriction =
|
||||
radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.codebookSubsetRestriction;
|
||||
UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection =
|
||||
radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection;
|
||||
|
||||
LOG_I(PHY,"New Transmission Mode %ld \n",radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode);
|
||||
LOG_I(PHY,"Configured Transmission Mode %ld \n",UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo->choice.explicitValue.transmissionMode);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3131,9 +3142,13 @@ static void dump_sib2( SystemInformationBlockType2_t *sib2 )
|
||||
sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig );
|
||||
LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission : %d\n",
|
||||
sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission );
|
||||
//LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts : %ld\n",
|
||||
|
||||
if(sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts)
|
||||
{
|
||||
LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts : %ld\n",
|
||||
/* TODO: check that it's okay to access [0] */
|
||||
// sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts[0] );
|
||||
sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts[0] );
|
||||
}
|
||||
}
|
||||
|
||||
// uplinkPowerControlCommon
|
||||
@@ -4391,7 +4406,6 @@ void *rrc_ue_task( void *args_p )
|
||||
|
||||
/* NAS messages */
|
||||
case NAS_CELL_SELECTION_REQ:
|
||||
ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */
|
||||
|
||||
LOG_D(RRC, "[UE %d] Received %s: state %d, plmnID (%d%d%d.%d%d%d), rat %x\n", ue_mod_id, msg_name, rrc_get_state(ue_mod_id),
|
||||
NAS_CELL_SELECTION_REQ (msg_p).plmnID.MCCdigit1,
|
||||
@@ -4692,7 +4706,6 @@ void *rrc_ue_task( void *args_p )
|
||||
break;
|
||||
|
||||
case RRC_RAL_CONNECTION_RELEASE_REQ:
|
||||
ue_mod_id = 0; /* TODO force ue_mod_id to first UE, NAS UE not virtualized yet */
|
||||
LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, msg_name);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -3432,7 +3432,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int i;
|
||||
int i, drb_id;
|
||||
#ifdef PDCP_USE_NETLINK
|
||||
int oip_ifup = 0;
|
||||
int dest_ip_offset = 0;
|
||||
@@ -3564,6 +3564,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
if (DRB_configList != NULL) {
|
||||
for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8)
|
||||
if (DRB_configList->list.array[i]) {
|
||||
drb_id = (int)DRB_configList->list.array[i]->drb_Identity;
|
||||
LOG_I(RRC,
|
||||
"[eNB %d] Frame %d : Logical Channel UL-DCCH, Received RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n",
|
||||
ctxt_pP->module_id,
|
||||
@@ -3580,7 +3581,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
(int)DRB_configList->list.array[i]->drb_Identity,
|
||||
(int)*DRB_configList->list.array[i]->logicalChannelIdentity);
|
||||
|
||||
if (ue_context_pP->ue_context.DRB_active[i] == 0) {
|
||||
if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) {
|
||||
/*
|
||||
rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_ADD,
|
||||
(ue_mod_idP * NB_RB_MAX) + *DRB_configList->list.array[i]->logicalChannelIdentity,UNDEF_SECURITY_MODE);
|
||||
@@ -3588,7 +3589,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
(ue_mod_idP * NB_RB_MAX) + (int)*eNB_rrc_inst[ctxt_pP->module_id].DRB_config[ue_mod_idP][i]->logicalChannelIdentity,
|
||||
RADIO_ACCESS_BEARER,Rlc_info_um);
|
||||
*/
|
||||
ue_context_pP->ue_context.DRB_active[i] = 1;
|
||||
ue_context_pP->ue_context.DRB_active[drb_id] = 1;
|
||||
|
||||
LOG_D(RRC,
|
||||
"[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n",
|
||||
@@ -3673,7 +3674,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
|
||||
} else { // remove LCHAN from MAC/PHY
|
||||
|
||||
if (ue_context_pP->ue_context.DRB_active[i] == 1) {
|
||||
if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
|
||||
// DRB has just been removed so remove RLC + PDCP for DRB
|
||||
/* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE,
|
||||
(ue_mod_idP * NB_RB_MAX) + DRB2LCHAN[i],UNDEF_SECURITY_MODE);
|
||||
@@ -3687,7 +3688,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
|
||||
Rlc_info_um);
|
||||
}
|
||||
|
||||
ue_context_pP->ue_context.DRB_active[i] = 0;
|
||||
ue_context_pP->ue_context.DRB_active[drb_id] = 0;
|
||||
LOG_D(RRC,
|
||||
PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n",
|
||||
PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
|
||||
|
||||
-2
@@ -36,7 +36,6 @@ void lfds700_hash_a_cleanup( struct lfds700_hash_a_state *has,
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
#pragma warning( disable : 4100 )
|
||||
|
||||
static void btree_au_element_cleanup_function( struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element *baue )
|
||||
{
|
||||
@@ -57,5 +56,4 @@ static void btree_au_element_cleanup_function( struct lfds700_btree_au_state *ba
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma warning( default : 4100 )
|
||||
|
||||
|
||||
-2
@@ -154,7 +154,6 @@ void lfds700_list_asu_insert_at_end( struct lfds700_list_asu_state *lasus,
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
#pragma warning( disable : 4100 )
|
||||
|
||||
void lfds700_list_asu_insert_after_element( struct lfds700_list_asu_state *lasus,
|
||||
struct lfds700_list_asu_element *lasue,
|
||||
@@ -189,5 +188,4 @@ void lfds700_list_asu_insert_after_element( struct lfds700_list_asu_state *lasus
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma warning( default : 4100 )
|
||||
|
||||
|
||||
+272
-171
@@ -43,6 +43,13 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include "rtai_fifos.h"
|
||||
#endif
|
||||
@@ -76,41 +83,197 @@ extern "C" {
|
||||
* @ingroup _macro
|
||||
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
|
||||
* @{*/
|
||||
#ifndef LOG_EMERG
|
||||
# define LOG_EMERG 0 /*!< \brief system is unusable */
|
||||
#endif
|
||||
#ifndef LOG_ALERT
|
||||
# define LOG_ALERT 1 /*!< \brief action must be taken immediately */
|
||||
#endif
|
||||
#ifndef LOG_CRIT
|
||||
# define LOG_CRIT 2 /*!< \brief critical conditions */
|
||||
#endif
|
||||
#ifndef LOG_ERR
|
||||
# define LOG_ERR 3 /*!< \brief error conditions */
|
||||
#endif
|
||||
#ifndef LOG_WARNING
|
||||
# define LOG_WARNING 4 /*!< \brief warning conditions */
|
||||
#endif
|
||||
#ifndef LOG_NOTICE
|
||||
# define LOG_NOTICE 5 /*!< \brief normal but significant condition */
|
||||
#endif
|
||||
#ifndef LOG_INFO
|
||||
# define LOG_INFO 6 /*!< \brief informational */
|
||||
#endif
|
||||
#ifndef LOG_DEBUG
|
||||
# define LOG_DEBUG 7 /*!< \brief debug-level messages */
|
||||
#endif
|
||||
#ifndef LOG_FILE
|
||||
# define LOG_FILE 8 /*!< \brief message sequence chart -level */
|
||||
#endif
|
||||
#ifndef LOG_TRACE
|
||||
# define LOG_TRACE 9 /*!< \brief trace-level messages */
|
||||
#endif
|
||||
|
||||
#define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */
|
||||
/* @}*/
|
||||
|
||||
|
||||
/** @defgroup _log_format Defined log format
|
||||
* @ingroup _macro
|
||||
* @brief Macro of log formats defined by LOG
|
||||
* @{*/
|
||||
|
||||
/* .log_format = 0x13 uncolored standard messages
|
||||
* .log_format = 0x93 colored standard messages */
|
||||
|
||||
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
|
||||
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
|
||||
#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */
|
||||
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
|
||||
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
|
||||
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
|
||||
/* @}*/
|
||||
|
||||
|
||||
/** @defgroup _syslog_conf Macros for write in syslog.conf
|
||||
* @ingroup _macro
|
||||
* @brief Macros used to write lines (local/remote) in syslog.conf
|
||||
* @{*/
|
||||
#define LOG_LOCAL 0x01
|
||||
#define LOG_REMOTE 0x02
|
||||
|
||||
#define FLAG_COLOR 0x001 /*!< \brief defaults */
|
||||
#define FLAG_PID 0x002 /*!< \brief defaults */
|
||||
#define FLAG_COMP 0x004
|
||||
#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */
|
||||
#define FLAG_LEVEL 0x010
|
||||
#define FLAG_FUNCT 0x020
|
||||
#define FLAG_FILE_LINE 0x040
|
||||
#define FLAG_TIME 0x100
|
||||
|
||||
#define LOG_NONE 0x00
|
||||
#define LOG_LOW 0x5
|
||||
#define LOG_MED 0x15
|
||||
#define LOG_HIGH 0x35
|
||||
#define LOG_FULL 0x75
|
||||
|
||||
#define OAI_OK 0 /*!< \brief all ok */
|
||||
#define OAI_ERR 1 /*!< \brief generic error */
|
||||
#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */
|
||||
#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */
|
||||
/* @}*/
|
||||
|
||||
|
||||
//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */
|
||||
|
||||
//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
|
||||
|
||||
typedef enum {
|
||||
MIN_LOG_COMPONENTS = 0,
|
||||
PHY = MIN_LOG_COMPONENTS,
|
||||
MAC,
|
||||
EMU,
|
||||
OCG,
|
||||
OMG,
|
||||
OPT,
|
||||
OTG,
|
||||
OTG_LATENCY,
|
||||
OTG_LATENCY_BG,
|
||||
OTG_GP,
|
||||
OTG_GP_BG,
|
||||
OTG_JITTER,
|
||||
RLC,
|
||||
PDCP,
|
||||
RRC,
|
||||
NAS,
|
||||
PERF,
|
||||
OIP,
|
||||
CLI,
|
||||
MSC,
|
||||
OCM,
|
||||
UDP_,
|
||||
GTPU,
|
||||
SPGW,
|
||||
S1AP,
|
||||
SCTP,
|
||||
HW,
|
||||
OSA,
|
||||
RAL_ENB,
|
||||
RAL_UE,
|
||||
ENB_APP,
|
||||
FLEXRAN_AGENT,
|
||||
TMR,
|
||||
USIM,
|
||||
LOCALIZE,
|
||||
RRH,
|
||||
X2AP,
|
||||
MAX_LOG_COMPONENTS,
|
||||
}
|
||||
comp_name_t;
|
||||
|
||||
//#define msg printf
|
||||
|
||||
typedef struct {
|
||||
char *name; /*!< \brief string name of item */
|
||||
int value; /*!< \brief integer value of mapping */
|
||||
} mapping;
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int level;
|
||||
int flag;
|
||||
int interval;
|
||||
int fd;
|
||||
int filelog;
|
||||
char *filelog_name;
|
||||
|
||||
/* SR: make the log buffer component relative */
|
||||
char log_buffer[MAX_LOG_TOTAL];
|
||||
} log_component_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int remote_ip;
|
||||
unsigned int audit_ip;
|
||||
int remote_level;
|
||||
int facility;
|
||||
int audit_facility;
|
||||
int format;
|
||||
} log_config_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
log_component_t log_component[MAX_LOG_COMPONENTS];
|
||||
log_config_t config;
|
||||
char* level2string[NUM_LOG_LEVEL];
|
||||
int level;
|
||||
int onlinelog;
|
||||
int flag;
|
||||
int syslog;
|
||||
int filelog;
|
||||
char* filelog_name;
|
||||
} log_t;
|
||||
|
||||
typedef struct LOG_params {
|
||||
const char *file;
|
||||
const char *func;
|
||||
int line;
|
||||
int comp;
|
||||
int level;
|
||||
const char *format;
|
||||
char l_buff_info [MAX_LOG_INFO];
|
||||
int len;
|
||||
} LOG_params;
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
typedef enum log_instance_type_e {
|
||||
LOG_INSTANCE_UNKNOWN,
|
||||
LOG_INSTANCE_ENB,
|
||||
LOG_INSTANCE_UE,
|
||||
} log_instance_type_t;
|
||||
|
||||
void log_set_instance_type (log_instance_type_t instance);
|
||||
#endif
|
||||
|
||||
|
||||
/*--- INCLUDES ---------------------------------------------------------------*/
|
||||
# include "log_if.h"
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int logInit (void);
|
||||
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...);
|
||||
void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...);
|
||||
int set_comp_log(int component, int level, int verbosity, int interval);
|
||||
int set_log(int component, int level, int interval);
|
||||
void set_glog(int level, int verbosity);
|
||||
void set_log_syslog(int enable);
|
||||
void set_log_onlinelog(int enable);
|
||||
void set_log_filelog(int enable);
|
||||
void set_component_filelog(int comp);
|
||||
int map_str_to_int(mapping *map, const char *str);
|
||||
char *map_int_to_str(mapping *map, int val);
|
||||
void logClean (void);
|
||||
int is_newline( char *str, int size);
|
||||
void *log_thread_function(void * list);
|
||||
|
||||
/** @defgroup _logIt logIt function
|
||||
* @ingroup _macro
|
||||
* @brief Macro used to call tr_log_full_ex with file, function and line information
|
||||
@@ -186,169 +349,107 @@ extern "C" {
|
||||
#define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
|
||||
/* @}*/
|
||||
|
||||
|
||||
/** @defgroup _log_format Defined log format
|
||||
* @ingroup _macro
|
||||
* @brief Macro of log formats defined by LOG
|
||||
* @{*/
|
||||
|
||||
/* .log_format = 0x13 uncolored standard messages
|
||||
* .log_format = 0x93 colored standard messages */
|
||||
|
||||
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
|
||||
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
|
||||
#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */
|
||||
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
|
||||
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
|
||||
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
|
||||
/* @}*/
|
||||
|
||||
|
||||
/** @defgroup _syslog_conf Macros for write in syslog.conf
|
||||
* @ingroup _macro
|
||||
* @brief Macros used to write lines (local/remote) in syslog.conf
|
||||
* @{*/
|
||||
#define LOG_LOCAL 0x01
|
||||
#define LOG_REMOTE 0x02
|
||||
|
||||
#define FLAG_COLOR 0x001 /*!< \brief defaults */
|
||||
#define FLAG_PID 0x002 /*!< \brief defaults */
|
||||
#define FLAG_COMP 0x004
|
||||
#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */
|
||||
#define FLAG_LEVEL 0x010
|
||||
#define FLAG_FUNCT 0x020
|
||||
#define FLAG_FILE_LINE 0x040
|
||||
#define FLAG_TIME 0x100
|
||||
|
||||
#define LOG_NONE 0x00
|
||||
#define LOG_LOW 0x5
|
||||
#define LOG_MED 0x15
|
||||
#define LOG_HIGH 0x35
|
||||
#define LOG_FULL 0x75
|
||||
|
||||
#define OAI_OK 0 /*!< \brief all ok */
|
||||
#define OAI_ERR 1 /*!< \brief generic error */
|
||||
#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */
|
||||
#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */
|
||||
/* @}*/
|
||||
|
||||
|
||||
//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */
|
||||
|
||||
//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
|
||||
|
||||
typedef enum {
|
||||
MIN_LOG_COMPONENTS = 0,
|
||||
PHY = MIN_LOG_COMPONENTS,
|
||||
MAC,
|
||||
EMU,
|
||||
OCG,
|
||||
OMG,
|
||||
OPT,
|
||||
OTG,
|
||||
OTG_LATENCY,
|
||||
OTG_LATENCY_BG,
|
||||
OTG_GP,
|
||||
OTG_GP_BG,
|
||||
OTG_JITTER,
|
||||
RLC,
|
||||
PDCP,
|
||||
RRC,
|
||||
NAS,
|
||||
PERF,
|
||||
OIP,
|
||||
CLI,
|
||||
MSC,
|
||||
OCM,
|
||||
UDP_,
|
||||
GTPU,
|
||||
SPGW,
|
||||
S1AP,
|
||||
SCTP,
|
||||
HW,
|
||||
OSA,
|
||||
RAL_ENB,
|
||||
RAL_UE,
|
||||
ENB_APP,
|
||||
FLEXRAN_AGENT,
|
||||
TMR,
|
||||
USIM,
|
||||
LOCALIZE,
|
||||
RRH,
|
||||
X2AP,
|
||||
MAX_LOG_COMPONENTS,
|
||||
static __inline__ uint64_t rdtsc(void) {
|
||||
uint64_t a, d;
|
||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
||||
return (d<<32) | a;
|
||||
}
|
||||
comp_name_t;
|
||||
|
||||
//#define msg printf
|
||||
#define DEBUG_REALTIME 1
|
||||
#if DEBUG_REALTIME
|
||||
|
||||
typedef struct {
|
||||
char *name; /*!< \brief string name of item */
|
||||
int value; /*!< \brief integer value of mapping */
|
||||
} mapping;
|
||||
extern double cpuf;
|
||||
|
||||
static inline uint64_t checkTCPU(int timeout, char * file, int line) {
|
||||
static uint64_t __thread lastCPUTime=0;
|
||||
static uint64_t __thread last=0;
|
||||
uint64_t cur=rdtsc();
|
||||
struct timespec CPUt;
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt);
|
||||
uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000;
|
||||
double microCycles=(double)(cpuf*1000);
|
||||
int duration=(int)((cur-last)/microCycles);
|
||||
if ( last!=0 && duration > timeout ) {
|
||||
//struct timespec ts;
|
||||
//clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line,
|
||||
duration, timeout, (long long)CPUTime-lastCPUTime );
|
||||
}
|
||||
last=cur;
|
||||
lastCPUTime=CPUTime;
|
||||
return cur;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int level;
|
||||
int flag;
|
||||
int interval;
|
||||
int fd;
|
||||
int filelog;
|
||||
char *filelog_name;
|
||||
static inline unsigned long long checkT(int timeout, char * file, int line) {
|
||||
static unsigned long long __thread last=0;
|
||||
unsigned long long cur=rdtsc();
|
||||
int microCycles=(int)(cpuf*1000);
|
||||
int duration=(int)((cur-last)/microCycles);
|
||||
if ( last!=0 && duration > timeout )
|
||||
printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line,
|
||||
duration, timeout);
|
||||
last=cur;
|
||||
return cur;
|
||||
}
|
||||
|
||||
/* SR: make the log buffer component relative */
|
||||
char log_buffer[MAX_LOG_TOTAL];
|
||||
} log_component_t;
|
||||
typedef struct m {
|
||||
uint64_t iterations;
|
||||
uint64_t sum;
|
||||
uint64_t maxArray[11];
|
||||
} Meas;
|
||||
|
||||
typedef struct {
|
||||
unsigned int remote_ip;
|
||||
unsigned int audit_ip;
|
||||
int remote_level;
|
||||
int facility;
|
||||
int audit_facility;
|
||||
int format;
|
||||
} log_config_t;
|
||||
static inline void printMeas(char * txt, Meas *M, int period) {
|
||||
if (M->iterations%period == 0 ) {
|
||||
char txt2[512];
|
||||
sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%"
|
||||
PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n",
|
||||
txt,
|
||||
M->sum/M->iterations,
|
||||
M->iterations,
|
||||
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5],
|
||||
M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
|
||||
LOG_W(PHY,txt2);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int cmpint(const void* a, const void* b) {
|
||||
uint64_t* aa=(uint64_t*)a;
|
||||
uint64_t* bb=(uint64_t*)b;
|
||||
return (int)(*aa-*bb);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
log_component_t log_component[MAX_LOG_COMPONENTS];
|
||||
log_config_t config;
|
||||
char* level2string[NUM_LOG_LEVEL];
|
||||
int level;
|
||||
int onlinelog;
|
||||
int flag;
|
||||
int syslog;
|
||||
int filelog;
|
||||
char* filelog_name;
|
||||
} log_t;
|
||||
static inline void updateTimes(uint64_t start, Meas *M, int period, char * txt) {
|
||||
if (start!=0) {
|
||||
uint64_t end=rdtsc();
|
||||
long long diff=(end-start)/(cpuf*1000);
|
||||
M->maxArray[0]=diff;
|
||||
M->sum+=diff;
|
||||
M->iterations++;
|
||||
qsort(M->maxArray, 11, sizeof(uint64_t), cmpint);
|
||||
printMeas(txt,M,period);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct LOG_params {
|
||||
const char *file;
|
||||
const char *func;
|
||||
int line;
|
||||
int comp;
|
||||
int level;
|
||||
const char *format;
|
||||
char l_buff_info [MAX_LOG_INFO];
|
||||
int len;
|
||||
} LOG_params;
|
||||
#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0)
|
||||
#define checkcpu(a) do { checkTCPU(a,__FILE__,__LINE__); } while (0)
|
||||
#define initRefTimes(a) static __thread Meas a= {0}
|
||||
#define pickTime(a) uint64_t a=rdtsc()
|
||||
#define readTime(a) a
|
||||
#define initStaticTime(a) static __thread uint64_t a={0}
|
||||
#define pickStaticTime(a) do { a=rdtsc(); } while (0)
|
||||
|
||||
|
||||
#if defined(ENABLE_ITTI)
|
||||
typedef enum log_instance_type_e {
|
||||
LOG_INSTANCE_UNKNOWN,
|
||||
LOG_INSTANCE_ENB,
|
||||
LOG_INSTANCE_UE,
|
||||
} log_instance_type_t;
|
||||
|
||||
void log_set_instance_type (log_instance_type_t instance);
|
||||
#else
|
||||
#define check(a) do {} while (0)
|
||||
#define checkcpu(a) do {} while (0)
|
||||
#define initRefTimes(a) do {} while (0)
|
||||
#define initStaticTime(a) do {} while (0)
|
||||
#define pickTime(a) do {} while (0)
|
||||
#define readTime(a) 0
|
||||
#define pickStaticTime(a) do {} while (0)
|
||||
#define updateTimes(a,b,c,d) do {} while (0)
|
||||
#define printMeas(a,b,c) do {} while (0)
|
||||
#endif
|
||||
int logInit (void);
|
||||
|
||||
/*--- INCLUDES ---------------------------------------------------------------*/
|
||||
# include "log_if.h"
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,59 +27,8 @@
|
||||
* \warning This component can be runned only in user-space
|
||||
* @ingroup routing
|
||||
*/
|
||||
#ifndef __LOG_IF_H__
|
||||
# define __LOG_IF_H__
|
||||
|
||||
|
||||
/*--- INCLUDES ---------------------------------------------------------------*/
|
||||
# include "log.h"
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
# ifdef COMPONENT_LOG
|
||||
# ifdef COMPONENT_LOG_IF
|
||||
# define private_log_if(x) x
|
||||
# define friend_log_if(x) x
|
||||
# define public_log_if(x) x
|
||||
# else
|
||||
# define private_log_if(x)
|
||||
# define friend_log_if(x) extern x
|
||||
# define public_log_if(x) extern x
|
||||
# endif
|
||||
# else
|
||||
# define private_log_if(x)
|
||||
# define friend_log_if(x)
|
||||
# define public_log_if(x) extern x
|
||||
# endif
|
||||
|
||||
/** @defgroup _log_if Interfaces of LOG
|
||||
* @{*/
|
||||
|
||||
//public_log_if( log_t *g_log;)
|
||||
|
||||
public_log_if( int logInit (void);)
|
||||
public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));)
|
||||
public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));)
|
||||
public_log_if( int set_comp_log(int component, int level, int verbosity, int interval);)
|
||||
public_log_if( int set_log(int component, int level, int interval);)
|
||||
public_log_if( void set_glog(int level, int verbosity);)
|
||||
public_log_if( void set_log_syslog(int enable);)
|
||||
public_log_if( void set_log_onlinelog(int enable);)
|
||||
public_log_if( void set_log_filelog(int enable);)
|
||||
public_log_if( void set_component_filelog(int comp);)
|
||||
public_log_if( int map_str_to_int(mapping *map, const char *str);)
|
||||
public_log_if( char *map_int_to_str(mapping *map, int val);)
|
||||
public_log_if( void logClean (void); )
|
||||
public_log_if( int is_newline( char *str, int size);)
|
||||
public_log_if( void *log_thread_function(void * list);)
|
||||
|
||||
/* @}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// LTS: kept this file for compatibility
|
||||
// this file was probably a trial to separate internal functions and external ones
|
||||
// but it has never been finished, most source code include directly log.h (not log_if.h)
|
||||
#include "log.h"
|
||||
|
||||
@@ -181,6 +181,10 @@ const char* eurecomVariablesNames[] = {
|
||||
"ue0_trx_write_ns",
|
||||
"ue0_trx_read_ns_missing",
|
||||
"ue0_trx_write_ns_missing"
|
||||
"send_if4_symbol",
|
||||
"recv_if4_symbol",
|
||||
"send_if5_pkt_id",
|
||||
"recv_if5_pkt_id"
|
||||
};
|
||||
|
||||
const char* eurecomFunctionsNames[] = {
|
||||
@@ -375,7 +379,10 @@ const char* eurecomFunctionsNames[] = {
|
||||
"send_if4",
|
||||
"recv_if4",
|
||||
"send_if5",
|
||||
"recv_if5"
|
||||
"recv_if5",
|
||||
|
||||
"compress_if",
|
||||
"decompress_if"
|
||||
};
|
||||
|
||||
struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = {
|
||||
|
||||
@@ -147,6 +147,10 @@ typedef enum {
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN5,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN6,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_SFN7,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF4_SYMBOL,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF4_SYMBOL,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_SEND_IF5_PKT_ID,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_RECV_IF5_PKT_ID,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_SIZE,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE_PDCP_FLUSH_ERR,
|
||||
VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS,
|
||||
@@ -354,6 +358,9 @@ typedef enum {
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF5,
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5,
|
||||
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF,
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF,
|
||||
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
|
||||
VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
|
||||
} vcd_signal_dump_functions;
|
||||
|
||||
@@ -31,13 +31,12 @@
|
||||
#ifndef STRUCTURES_H
|
||||
#define STRUCTURES_H
|
||||
|
||||
#include "openairinterface5g_limits.h"
|
||||
#ifndef __PHY_IMPLEMENTATION_DEFS_H__
|
||||
#define Maxneighbor 64
|
||||
#define NUMBER_OF_UE_MAX 64
|
||||
#define NUMBER_OF_eNB_MAX 3
|
||||
#ifndef NB_ANTENNAS_RX
|
||||
# define NB_ANTENNAS_RX 4
|
||||
#endif
|
||||
#define Maxneighbor NUMBER_OF_UE_MAX
|
||||
#ifndef NB_ANTENNAS_RX
|
||||
#define NB_ANTENNAS_RX 4
|
||||
#endif
|
||||
#endif
|
||||
//
|
||||
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
#ifndef __OTG_DEFS_H__
|
||||
# define __OTG_DEFS_H__
|
||||
|
||||
|
||||
/* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */
|
||||
#if STANDALONE==1
|
||||
# define NUMBER_OF_eNB_MAX 3
|
||||
# define NUMBER_OF_UE_MAX 3
|
||||
#include "openairinterface5g_limits.h"
|
||||
#else
|
||||
#include "PHY/impl_defs_top.h" /* \brief To define the NUMBER_OF_eNB_MAX and NUMBER_OF_UE_MAX */
|
||||
// impl_defs_top.h includes openairinterface5g_limits.h
|
||||
#include "PHY/impl_defs_top.h"
|
||||
#endif
|
||||
|
||||
#include "otg_config.h"
|
||||
|
||||
@@ -464,6 +464,9 @@ int emm_msg_encode(EMM_msg *msg, uint8_t *buffer, uint32_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (encode_result < 0)
|
||||
LOG_FUNC_RETURN (encode_result);
|
||||
|
||||
LOG_FUNC_RETURN (header_result + encode_result);
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,30 @@ char* memory_get_path(const char* dirname, const char* filename)
|
||||
return data_filename;
|
||||
}
|
||||
|
||||
char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid)
|
||||
{
|
||||
/* Get non-volatile data directory */
|
||||
const char* path = getenv(dirname);
|
||||
char buffer[2048];
|
||||
|
||||
if (path == NULL) {
|
||||
path = getenv(DEFAULT_NAS_PATH);
|
||||
}
|
||||
|
||||
if (path == NULL) {
|
||||
LOG_TRACE(WARNING, "MEMORY - %s and %s environment variables are not defined trying local directory", dirname, DEFAULT_NAS_PATH);
|
||||
path = ".";
|
||||
}
|
||||
|
||||
/* Append non-volatile data file name */
|
||||
if ( snprintf(buffer, sizeof(buffer), "%s/%s%d", path, filename, ueid) < 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(buffer);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: memory_read() **
|
||||
|
||||
@@ -58,6 +58,8 @@ Description Memory access utilities
|
||||
|
||||
char* memory_get_path(const char* dirname, const char* filename);
|
||||
|
||||
char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid);
|
||||
|
||||
int memory_read(const char* datafile, void* data, size_t size);
|
||||
|
||||
int memory_write(const char* datafile, const void* data, size_t size);
|
||||
|
||||
@@ -314,6 +314,7 @@ typedef struct {
|
||||
*/
|
||||
#define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* User notification callback, executed whenever a change of data with
|
||||
* respect of network information (e.g. network registration and/or
|
||||
@@ -322,6 +323,7 @@ typedef struct {
|
||||
*/
|
||||
typedef int (*emm_indication_callback_t) (Stat_t, tac_t, ci_t, AcT_t,
|
||||
const char*, size_t);
|
||||
#endif
|
||||
|
||||
typedef enum eps_protocol_discriminator_e {
|
||||
/* Protocol discriminator identifier for EPS Mobility Management */
|
||||
|
||||
@@ -260,12 +260,14 @@ typedef struct {
|
||||
network_pkf_t* pkf[NET_PACKET_FILTER_MAX];
|
||||
} network_tft_t;
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* User notification callback, executed whenever a change of status with
|
||||
* respect of PDN connection or EPS bearer context is notified by the EPS
|
||||
* Session Management sublayer
|
||||
*/
|
||||
typedef int (*esm_indication_callback_t) (int, network_pdn_state_t);
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/******************** G L O B A L V A R I A B L E S ********************/
|
||||
|
||||
@@ -18,9 +18,9 @@ EURECOM-NAS directory should contain following files:
|
||||
|
||||
EURECOM-NAS
|
||||
|-- bin
|
||||
| |-- .ue.nvram
|
||||
| |-- .ue_emm.nvram
|
||||
| |-- .usim.nvram
|
||||
| |-- .ue.nvram0
|
||||
| |-- .ue_emm.nvram0
|
||||
| |-- .usim.nvram0
|
||||
| |-- NetworkProcess
|
||||
| |-- UEprocess
|
||||
| `-- UserProcess
|
||||
@@ -57,10 +57,10 @@ UE for testing purpose.
|
||||
When starting up, UEprocess reads configuration data from .nvram binary
|
||||
files used as UE's non-volatile memory.
|
||||
|
||||
.usim.nvram contains data stored into the USIM
|
||||
.ue.nvram contains data related to the UE identification (IMEI,
|
||||
.usim.nvram0 contains data stored into the USIM
|
||||
.ue.nvram0 contains data related to the UE identification (IMEI,
|
||||
manufacturer, model, PIN code)
|
||||
.ue_emm.nvram contains data related to EPS Mobility Management (IMSI, last
|
||||
.ue_emm.nvram0 contains data related to EPS Mobility Management (IMSI, last
|
||||
registered PLMN)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#/*
|
||||
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
# * contributor license agreements. See the NOTICE file distributed with
|
||||
# * this work for additional information regarding copyright ownership.
|
||||
# * The OpenAirInterface Software Alliance licenses this file to You under
|
||||
# * the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
# * except in compliance with the License.
|
||||
# * You may obtain a copy of the License at
|
||||
# *
|
||||
# * http://www.openairinterface.org/?page_id=698
|
||||
# *
|
||||
# * Unless required by applicable law or agreed to in writing, software
|
||||
# * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# * See the License for the specific language governing permissions and
|
||||
# * limitations under the License.
|
||||
# *-------------------------------------------------------------------------------
|
||||
# * For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
export PROCESS = UE
|
||||
|
||||
ifndef PROJDIR
|
||||
PROJDIR = $(PWD)/..
|
||||
endif
|
||||
|
||||
include $(PROJDIR)/Makerules
|
||||
include $(PROJDIR)/Makefile.inc
|
||||
include $(PROJDIR)/../Makefile.tools
|
||||
|
||||
export LD_RUN_PATH = $(LIBDIR):$(LIBPROCESS)
|
||||
|
||||
LIBS = -luenas.a -lrt
|
||||
INCLUDES = -I. -I$(INCDIR) -I$(UTILDIR) -I$(USIMAPIDIR) -I$(EMMDIR) -I$(ESMDIR) -I$(IESDIR)
|
||||
|
||||
#LIBSUTIL = $(LIBDIR)/$(LIBUTIL).a $(LIBDIR)/$(LIBUTIL).so
|
||||
|
||||
USIM_OBJ = usim_data.o
|
||||
UE_OBJ = ue_data.o
|
||||
|
||||
USIM_TARGET = usim_data
|
||||
UE_TARGET = ue_data
|
||||
|
||||
TARGETS = $(USIM_TARGET) $(UE_TARGET)
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
#-DIMSI_USA_MNC_3DIGITS
|
||||
%.o: %.c Makefile
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(USIM_TARGET): $(USIM_OBJ) $(LIBSUTIL)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -lnettle -lcrypto -lm
|
||||
@echo Replacing $@ to $(BINDIR)
|
||||
@$(RM) $(BINDIR)/$@
|
||||
@$(CP) $@ $(BINDIR)
|
||||
|
||||
$(UE_TARGET): $(UE_OBJ) $(LIBSUTIL)
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -lnettle -lcrypto -lm
|
||||
@echo Replacing $@ to $(BINDIR)
|
||||
@$(RM) $(BINDIR)/$@
|
||||
@$(CP) $@ $(BINDIR)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS) *.bak *~
|
||||
|
||||
veryclean: clean
|
||||
$(RM) $(TARGETS)
|
||||
|
||||
veryveryclean: veryclean
|
||||
$(RM) -Rf *.o $(PROJDIR)
|
||||
$(RM) -Rf *.a $(PROJDIR)
|
||||
|
||||
depend:
|
||||
makedepend -- ${CFLAGS} -- ${SRCS}
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#include <stdio.h> // perror, printf, fprintf, snprintf
|
||||
#include <stdlib.h> // exit, free
|
||||
#include <string.h> // memset, strncpy
|
||||
#include <getopt.h>
|
||||
|
||||
#include "conf2uedata.h"
|
||||
#include "display.h"
|
||||
#include "conf_parser.h"
|
||||
|
||||
int main(int argc, char**argv) {
|
||||
int option;
|
||||
const char* conf_file = NULL;
|
||||
const char* output_dir = NULL;
|
||||
const char options[]="c:o:h";
|
||||
|
||||
while ((option = getopt(argc, argv, options)) != -1) {
|
||||
switch (option) {
|
||||
case 'c':
|
||||
conf_file = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
output_dir = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
_display_usage();
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (output_dir == NULL ) {
|
||||
printf("No output option found\n");
|
||||
_display_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( conf_file == NULL ) {
|
||||
printf("No Configuration file is given\n");
|
||||
_display_usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( parse_config_file(output_dir, conf_file, OUTPUT_ALL) == false ) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
display_data_from_directory(output_dir, DISPLAY_ALL);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Displays command line usage
|
||||
*/
|
||||
void _display_usage(void) {
|
||||
fprintf(stderr, "usage: conf2uedata [OPTION]...\n");
|
||||
fprintf(stderr, "\t[-c]\tConfig file to use\n");
|
||||
fprintf(stderr, "\t[-o]\toutput file directory\n");
|
||||
fprintf(stderr, "\t[-h]\tDisplay this usage\n");
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _CONF2UEDATA_H
|
||||
#define _CONF2UEDATA_H
|
||||
|
||||
void _display_usage(void);
|
||||
|
||||
#endif // _CONF2UEDATA_H
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "conf_emm.h"
|
||||
#include "fs.h"
|
||||
|
||||
void gen_emm_data(
|
||||
emm_nvdata_t *emm_data,
|
||||
const char *hplmn,
|
||||
const char *msin,
|
||||
const plmns_list *eplmn,
|
||||
const networks_t networks)
|
||||
{
|
||||
memset(emm_data, 0, sizeof(emm_nvdata_t));
|
||||
int hplmn_index = get_plmn_index(hplmn, networks);
|
||||
plmn_conf_param_t *conf = &networks.items[hplmn_index].conf;
|
||||
int i;
|
||||
|
||||
emm_data->imsi.length = 8;
|
||||
emm_data->imsi.u.num.parity = get_msin_parity(msin, conf->mcc, conf->mnc);
|
||||
emm_data->imsi.u.num.digit1 = conf->mcc[0];
|
||||
emm_data->imsi.u.num.digit2 = conf->mcc[1];
|
||||
emm_data->imsi.u.num.digit3 = conf->mcc[2];
|
||||
|
||||
emm_data->imsi.u.num.digit4 = conf->mnc[0];
|
||||
emm_data->imsi.u.num.digit5 = conf->mnc[1];
|
||||
|
||||
if (strlen(conf->mnc) == 3) {
|
||||
emm_data->rplmn.MNCdigit3 = conf->mnc[2];
|
||||
|
||||
emm_data->imsi.u.num.digit6 = conf->mnc[2];
|
||||
emm_data->imsi.u.num.digit7 = msin[0];
|
||||
emm_data->imsi.u.num.digit8 = msin[1];
|
||||
emm_data->imsi.u.num.digit9 = msin[2];
|
||||
emm_data->imsi.u.num.digit10 = msin[3];
|
||||
emm_data->imsi.u.num.digit11 = msin[4];
|
||||
emm_data->imsi.u.num.digit12 = msin[5];
|
||||
emm_data->imsi.u.num.digit13 = msin[6];
|
||||
emm_data->imsi.u.num.digit14 = msin[7];
|
||||
emm_data->imsi.u.num.digit15 = msin[8];
|
||||
} else {
|
||||
emm_data->rplmn.MNCdigit3 = 0xf;
|
||||
|
||||
emm_data->imsi.u.num.digit6 = msin[0];
|
||||
emm_data->imsi.u.num.digit7 = msin[1];
|
||||
emm_data->imsi.u.num.digit8 = msin[2];
|
||||
emm_data->imsi.u.num.digit9 = msin[3];
|
||||
emm_data->imsi.u.num.digit10 = msin[4];
|
||||
emm_data->imsi.u.num.digit11 = msin[5];
|
||||
emm_data->imsi.u.num.digit12 = msin[6];
|
||||
emm_data->imsi.u.num.digit13 = msin[7];
|
||||
emm_data->imsi.u.num.digit14 = msin[8];
|
||||
emm_data->imsi.u.num.digit15 = msin[9];
|
||||
}
|
||||
|
||||
emm_data->rplmn.MCCdigit1 = conf->mcc[0];
|
||||
emm_data->rplmn.MCCdigit2 = conf->mcc[1];
|
||||
emm_data->rplmn.MCCdigit3 = conf->mcc[2];
|
||||
emm_data->rplmn.MNCdigit1 = conf->mnc[0];
|
||||
emm_data->rplmn.MNCdigit2 = conf->mnc[1];
|
||||
|
||||
emm_data->eplmn.n_plmns = eplmn->size;
|
||||
for (i = 0; i < eplmn->size; i++) {
|
||||
emm_data->eplmn.plmn[i] = networks.items[eplmn->items[i]].plmn;
|
||||
}
|
||||
}
|
||||
|
||||
bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data) {
|
||||
int rc;
|
||||
char* filename = make_filename(directory, EMM_NVRAM_FILENAME, user_id);
|
||||
rc = memory_write(filename, emm_data, sizeof(emm_nvdata_t));
|
||||
free(filename);
|
||||
if (rc != RETURNok) {
|
||||
perror("ERROR\t: memory_write() failed");
|
||||
exit(false);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
int get_msin_parity(const char * msin, const char *mcc, const char *mnc) {
|
||||
int imsi_size = strlen(msin) + strlen(mcc)
|
||||
+ strlen(mnc);
|
||||
int result = (imsi_size % 2 == 0) ? 0 : 1;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _CONF_EMM_H
|
||||
#define _CONF_EMM_H
|
||||
|
||||
#include "emmData.h"
|
||||
#include "conf_network.h"
|
||||
#include "conf_user_plmn.h"
|
||||
|
||||
void gen_emm_data(
|
||||
emm_nvdata_t *emm_data,
|
||||
const char *hplmn,
|
||||
const char *msin,
|
||||
const plmns_list *eplmn,
|
||||
const networks_t networks);
|
||||
|
||||
bool write_emm_data(const char *directory, int user_id, emm_nvdata_t *emm_data);
|
||||
int get_msin_parity(const char * msin, const char *mcc, const char *mnc);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "conf_network.h"
|
||||
|
||||
int get_plmn_index(const char * mccmnc, const networks_t networks) {
|
||||
char mcc[4];
|
||||
char mnc[strlen(mccmnc) - 2];
|
||||
strncpy(mcc, mccmnc, 3);
|
||||
mcc[3] = '\0';
|
||||
strncpy(mnc, mccmnc + 3, 3);
|
||||
mnc[strlen(mccmnc) - 3] = '\0';
|
||||
for (int i = 0; i < networks.size; i++) {
|
||||
if (strcmp(networks.items[i].conf.mcc, mcc) == 0) {
|
||||
if (strcmp(networks.items[i].conf.mnc, mnc) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
plmn_t make_plmn_from_conf(const plmn_conf_param_t *plmn_conf) {
|
||||
plmn_t plmn;
|
||||
char num[6];
|
||||
|
||||
memset(&plmn, 0xff, sizeof(plmn));
|
||||
|
||||
snprintf(num, 6, "%s%s", plmn_conf->mcc, plmn_conf->mnc);
|
||||
|
||||
plmn.MCCdigit2 = plmn_conf->mcc[1];
|
||||
plmn.MCCdigit1 = plmn_conf->mcc[0];
|
||||
plmn.MCCdigit3 = plmn_conf->mcc[2];
|
||||
plmn.MNCdigit2 = plmn_conf->mnc[1];
|
||||
plmn.MNCdigit1 = plmn_conf->mnc[0];
|
||||
if (strlen(plmn_conf->mnc) > 2) {
|
||||
plmn.MNCdigit3 = plmn_conf->mnc[2];
|
||||
}
|
||||
return plmn;
|
||||
}
|
||||
|
||||
void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record) {
|
||||
strcpy(record->fullname, conf->fullname);
|
||||
strcpy(record->shortname, conf->shortname);
|
||||
|
||||
char num[6];
|
||||
sprintf(num, "%s%s", conf->mcc, conf->mnc);
|
||||
record->num = atoi(num);
|
||||
|
||||
record->plmn = make_plmn_from_conf(conf);
|
||||
record->tac_end = 0xfffd;
|
||||
record->tac_start = 0x0001;
|
||||
}
|
||||
|
||||
bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf) {
|
||||
int rc = 0;
|
||||
rc = config_setting_lookup_string(plmn_setting, FULLNAME, &conf->fullname);
|
||||
if (rc != 1) {
|
||||
printf("Error on FULLNAME\n");
|
||||
return false;
|
||||
}
|
||||
rc = config_setting_lookup_string(plmn_setting, SHORTNAME, &conf->shortname);
|
||||
if (rc != 1) {
|
||||
printf("Error on SHORTNAME\n");
|
||||
return false;
|
||||
}
|
||||
rc = config_setting_lookup_string(plmn_setting, MNC, &conf->mnc);
|
||||
if (rc != 1 || strlen(conf->mnc) > 3
|
||||
|| strlen(conf->mnc) < 2) {
|
||||
printf("Error ond MNC. Exiting\n");
|
||||
return false;
|
||||
}
|
||||
rc = config_setting_lookup_string(plmn_setting, MCC, &conf->mcc);
|
||||
if (rc != 1 || strlen(conf->mcc) != 3) {
|
||||
printf("Error on MCC\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *networks) {
|
||||
config_setting_t *plmn_setting = NULL;
|
||||
char plmn[10];
|
||||
int size = 0;
|
||||
|
||||
size = config_setting_length(all_plmn_setting);
|
||||
|
||||
networks->size = size;
|
||||
networks->items = malloc(sizeof(network_t) * size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
memset(&networks->items[i].record, 0xff, sizeof(network_record_t));
|
||||
}
|
||||
|
||||
for (int i = 0; i < networks->size; i++) {
|
||||
network_t *network = &networks->items[i];
|
||||
sprintf(plmn, "%s%d", PLMN, i);
|
||||
plmn_setting = config_setting_get_member(all_plmn_setting, plmn);
|
||||
if (plmn_setting == NULL) {
|
||||
printf("PLMN%d not fouund\n", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( parse_plmn_param(plmn_setting, &network->conf) == false ) {
|
||||
return false;
|
||||
}
|
||||
gen_network_record_from_conf(&network->conf, &network->record);
|
||||
network->plmn = network->record.plmn;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef _CONF_NETWORK_H
|
||||
#define _CONF_NETWORK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <libconfig.h>
|
||||
#include "usim_api.h"
|
||||
|
||||
#define PLMN "PLMN"
|
||||
|
||||
#define FULLNAME "FULLNAME"
|
||||
#define SHORTNAME "SHORTNAME"
|
||||
#define MNC "MNC"
|
||||
#define MCC "MCC"
|
||||
|
||||
#define MIN_TAC 0x0000
|
||||
#define MAX_TAC 0xFFFE
|
||||
|
||||
/*
|
||||
* PLMN network operator record
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int num;
|
||||
plmn_t plmn;
|
||||
char fullname[NET_FORMAT_LONG_SIZE + 1];
|
||||
char shortname[NET_FORMAT_SHORT_SIZE + 1];
|
||||
tac_t tac_start;
|
||||
tac_t tac_end;
|
||||
} network_record_t;
|
||||
|
||||
typedef struct {
|
||||
const char *fullname;
|
||||
const char *shortname;
|
||||
const char *mnc;
|
||||
const char *mcc;
|
||||
} plmn_conf_param_t;
|
||||
|
||||
typedef struct {
|
||||
plmn_conf_param_t conf;
|
||||
network_record_t record;
|
||||
plmn_t plmn;
|
||||
} network_t;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
network_t *items;
|
||||
} networks_t;
|
||||
|
||||
bool parse_plmn_param(config_setting_t *plmn_setting, plmn_conf_param_t *conf);
|
||||
bool parse_plmns(config_setting_t *all_plmn_setting, networks_t *plmns);
|
||||
|
||||
void gen_network_record_from_conf(const plmn_conf_param_t *conf, network_record_t *record);
|
||||
int get_plmn_index(const char * mccmnc, const networks_t networks);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user